You are on page 1of 13

CSSLAYOUTWITHFLEXBOX

LayingoutadesignwithCSSisfraughtwithperilofcrossbrowserbugsandmysteriouslycollapsingmargins.But
newtoolslikeflexboxhavetransformedthisonceodioustaskintosomethingyoushouldn'tdread.Bytheendof
thischapteryou'llbecodingupnewlayoutsforyourdesignfasterthanyoucanthinkofthem.
Rememberthoseoldcartoonswiththeroadrunnerandthecoyote?Rocketpropelledrollerskates,bottled
lightning,bundlesofdynamite,magneticbirdseed,razorboomerangs,"super"bombsandgianttrampolinesno
technologycouldcatchthebird.EverytoolbackfiredandsentWileE.Coyoteplummetingtohillariousdeath.
UsingCSStolayoutyourdesignisliketryingtocatchtheroadrunnerwithajetpoweredpogostick.Itwon'tend
well.

Nothingismorefrustratingthanwritingapileofcode,refreshingyourbrowserandseeingajumbledmessof
overlappingtextandimages.Youcan'tusetablesbecausetheyaren'tsemantic.Floatsandclearsneverdowhat
youexpect.Justtocentersomethingonthepagerequiresstrangeincantationsofautomarginsortextalignthe
centertagisrightout.
Butyouknowwhat?ThisisoldnewsbecauseCSSdoesn'tsuckatlayoutanymore.

Onceyouspendsometimewithflexboxyou'llfeellikeanunstoppablesuperheroofCSS.Yourfooterwillstayat
thebottomofthepagewhereitbelongs.YourLIswillfloweffortlesslyintoneatlittlecolumns.Divswillshrinkand
growandflyindelicateformationsliketheBlueAngels.Imagetagswilldanceandjumpandsingsongsofyour
designprowess.
"Wait,let'snotgetcarriedaway"yousay,"Flexboxistoonew.Youcan'tevenuseitinIE9."
Itdoesn'tmatter.Thinkaboutit:howmanybrowsersdoesaPSDworkin?None?Exactly.Asadesigneryou'renot
buildingthefinalversionofthedesign.Youdon'tcareifflexboxdoesn'tworkinOperaMinibecausethecompyou
arecreatingforyourclientonlyneedstoruninChrome.WorryaboutSeaMonkeylater.

DIVINGINTOFLEXBOX
YouonlyneedtoknowahandfulofCSSpropertiestouseflexbox.We'llstartwithanoverviewandgetsome
terminologyoutoftheway.

Everythingstartswiththeflexcontainer.Onceanelementissetasaflexcontaineritschildrenfollowtheflexbox
rulesforlayoutinsteadofthestandardblock,inlineandinlineblockrules.Withinaflexcontaineritemslineupon
the"mainaxis"andthemainaxiscaneitherbehorizontalorverticalsoyoucanarrangeitemsintocolumnsor
rows.

Thereisanotheraxisperpendiculartothemainaxiscalledthecrossaxis.Youcanshiftitemsalongbothaxes.In
theexamplesyou'veseensofartheyhavebeencenteredbutyoucanalsomovethemtothebeginningorendof
eitheraxis.

SPACINGAROUNDFLEXITEMS

SHRINKINGANDGROWING
Youcandefinethesizeofflexitems.Thisletsyoucreatelayoutswith,forexample,acolumnwithafixedwidth
andacolumnthatgrowsorshrinkswiththespaceavailable.

TIMETOLOOKATSOMECODE
I'veavoidedshowingyoucodeuptothispointbecausetheCSSpropertynamesdon'tmapwelltotheverysimple
conceptsbehindflexbox.TohelpyououtI'mintroducingthecodeinascreencastsoyoucanwatchwhathappens
tothelayoutliveasItype.I'vealsocreatedacheatsheetyoucanusewhileyougetusedtotheterminology.

EXAMPLESFROMREALWEBSITES
Flexboxdoesn'tsolveeverylayoutproblembutitcertainlyfixestheworstofthem.Aswelookatafewrealworld
examplesyouwilllearnafewothertechniquesforarrangingelementsonthepagebutflexboxalonewillgetyou
90%ofthewaymostofthetime.

37SIGNALS

You'relookingatthreedivscenteredhorizontallycertainlynotthemostcomplicatedlayoutofalltime.Evenso,
beforeflexboxcreatingthiskindoflayoutrequiredsomethought;centeringelementsonthepagewasnot
intuitive.
<divclass="products">
<div>
<imgsrc="basecamp.png"></img>
<h2><ahref="">Basecamp</a></h2>
<h3>ManageProjects</h3>
<p>Usedbymillionsforproductmanagement.</p>
</div>
<div>
<imgsrc="highrise.png"></img>
<h2><ahref="">Highrise</a></h2>
<h3><ahref="">ManageContacts</a></h3>
<p>Knowthepeopleyoudobusinesswith.</p>
</div>
<div>
<imgsrc="campfire.png"></img>
<h2><ahref="">Campfire</a></h2>
<h3>WorkinRealTime</h3>
<p>Groupchatroomsforyourbusiness.</p>
</div>
</div>

THEHTML
NOLAYOUTYET

ThisishowthemarkuprenderswithjustenoughCSStomakethestylinglookaboutthesame.Youarelookingat
thedefaultbrowserlayoutbeforewe'veappliedanyflexboxrules.Thethreeboxesaredivelements.Divelements
areblockelementsandblockelementsstack,theydon'tflownexttoeachother.
Firstlet'scenteritonthepageandgeteverythingflowingintoarow.

THECSS
.products{
display:flex;
flexflow:row;
justifycontent:center;
}

FIVELINESOFCSSLATER...

Thedivwrappingtheproductdivswassetto"display:flex"tomakeitaflexcontainer.Thentogetitsitemsintoa
rowIsettheflexflowpropertyto"row".
Gettingeverythingcenteredwaseasy.Justifycontentlet'syoumoveflexitemsonthemainaxis.Inthiscasethe
mainaxisishorizontalbecausetheflexflowpropertyissetto"row".Whenthemainaxisishorizontal,justify
contentwillmovetheitemstotheleftandright.Ifthemainaxisisvertical,(setflexflowtocolumn),justify
contentmovestheitemsupanddowninsteadofleftandright.Tocentertheproductdivsintheexample
horizontallyIsetjustifycontentto"center".
Thefirstrealworldexampleisalmostdone.Themiddlecontainerneedssomespacearounditandalloftheitems
ineachcontainershouldbecenteredhorizontally.
Tocentertheitemsinthedivit'seasiesttothinkaboutthemasflowinginacolumnandthencenteringthemon
thecrossaxis.Sointhiscasethemainaxisisverticalandthecrossaxisishorizontal.Here'sthecode:
/*
1.Makealloftheproductdivsflexcontainers.
2.Settheiritemstoflowintoacolumn.
3.Centerthemlefttorightbycenteringthem
onthecrossaxisusingalignitems.
*/

.products>div{
display:flex;
flexflow:column;
alignitems:center;
}

/*Usingselectorslikethis
iscoveredinanotherchapter.*/
.products>div:nthchild(2){
margin:02em;
}

ANATOMYOFATWEET

THEHTM
<divclass="tweet">
<divclass="content">
<imgsrc="aaron.png"></img>
<h2>AaronGustafson<span>@AaronGustafson</span></h2>
<time>12h</time>
<p>
SmartphoneBrowserlocalStorageisupto5xFasterthanNativeCache<a
href="http://www.mobify.com/blog/smartphonelocalstorageoutperformsbrowsercache/">mobify.com/blog/smartphon
...</a>
</p>
<ulclass="actions">
<li><ahref="">Collapse</a></li>
<li><ahref="">Reply</a></li>
<li><ahref="">Retweet</a></li>
<li><ahref="">Favorite</a></li>

<li><ahref="">More</a></li>
</ul>
<ulclass="meta">
<liclass="retweets">
<span>7</span>
<span>RETWEETS</span>
</li>
<liclass="favorites">
<span>5</span>
<span>FAVORITES</span>
</li>
<liclass="people">
<ulclass="people">
<li>
<imgsrc="people1.jpg"/>
</li>
<li>
<imgsrc="people2.jpg"/>
</li>
<li>
<imgsrc="people3.jpg"/>
</li>
<li>
<imgsrc="people4.jpg"/>
</li>
<li>
<imgsrc="people5.jpg"/>
</li>
<li>
<imgsrc="people6.jpg"/>
</li>
<li>
<imgsrc="people7.jpg"/>
</li>
</ul>

</li>
</ul>
<time>4:35AM24May13</time>
</div>
<divclass="reply">
<divcontenteditable="true">
Replyto<span>@AaronGustafson</span>
</div>
</div>
</div>

NOLAYOUT

PERFECTISTHEENEMYOFDONE
Whenconfrontedwithaconfoundinglayoutproblemacommonpitfallistowastetimefindingthe"best"solution.
Assoonasyoufindyourselfponderingthemeritsofchangingthemarkupandworryingaboutmessingupthe
semantics,stopwhatyou'redoingandseeifabsolutepositioningwouldwork.
Wheneveryou'rethinkingabouttechnicaldecisionsyou'renotthinkingaboutdesign.Remember,yourjobisto
createacomp,notthefinalsite.Thecodeyouarewritingwillbereworkedandrewrittensodon'tspendanytime
makingitperfectperfectistheenemyofdone.
Thefirstchallengewiththetweetistheuserprofileimageandthedatetag.Althoughnotobviousinthisexample
thetweettextflowsunderthedateandtheprofileimageseemstohaveitsowncolumn.Thewaythemarkupwas
writtendoesnotmakeaflexboxlayoutimmediatelyobvious.WhenIputthisexampletogetherIwastedafew
minutesthinkingaboutwaysIcouldchangethemarkupandgetthelayoutIwanted,butthenIcaughtmyselfand
justabsolutelypositionedbothelementswhereIwantedthem.

THECSS
/*createthespaceontheleftfortheprofileimage*/
.tweet.content,

10

.tweet.reply{
paddingleft:70px;
}

/*movetheimagetotheleftintothecolumn*/
.content>img{
position:absolute;
marginleft:60px;
}

/*
Movethetimestampupandtotheright
Iuse"em"insteadofpixelshere,butpixels
arejustfine.
*/
.content>time:firstoftype{
position:absolute;
margintop:1.5em;
marginleft:30em;
}

/*Iaddedsomeverticalpaddingtoall
oftheelementsinthecontentdiv.
*/
.content>*{
padding:.25em0;
}

ABSOLUTELYPOSITIONEDTWOELEMENTS

11

Thenextstepistotaketheactions,(e.g.collapse,reply,retweet,etc.),theretweetsandfavoritesandthelistof
smallprofilepicturesandputthemintorowsinsteadofcolumns.

ADASHOFFLEXBOX
.actions,li.people,.meta,.people>ul{
display:flex;
}

ALMOSTDONE

Elementsincontainersarearrangedintorowsbydefaultsoyoujustneedtosetthecontainertodisplay:flex.
You'llnoticeintherealtweetthenumbersareontopof"favorites"and"retweets".Therearetwowaystodothis.
Thefirstistotreatthemlikeflexcontainersandputthemintoacolumn.Thesecondwayistomakeeachofthe
spanswrappingthenumbersintoablockelementinsteadofinline.
Thesecondwayisonlyobviousifyouknowthatblockelementsstack.Thebeautyofflexboxisyoudon'tneedto
knowtheinsandoutsofblock,inlineorinlineblockelements.Learnthebasicsbutdon'twastetimeuseflexbox
whenit'snotobvious.

STACKTHEELEMENTS
.meta.retweets,
.meta.favorites{
display:flex;
flexflow:column;
}

12

FINISHED

TIPSANDTRICKS
o

Whenabsolutelypositioninganelementusemarginsinsteadoftop,left,right,bottom.Elementsabsolutelypositionedwith
marginsaremoreconsistentacrossdifferentscreenresolutions.

Useemsinsteadofpixels.Emsadjustwhenyouchangefontsize.Ifyouincreasedthebasefontsizeinthisexamplethedate
wouldmaintainitsposition.

Usepaddinginsteadofmarginforspacing.Spacescreatedwithmarginsometimescollapseintoeachotherinsteadofstacking.
Sometimesyouwantthisbutmostofthetimeit'snothelpful.Paddingdoesn'tcollapsesoit'smorepredictablethanusing
margins.

Usetheuniversalselector,*,withoutfear.Experiencedwebdevelopersavoidtheuniversalselectorforperformancereasons.
Youshouldn'tspendanytimethinkingaboutthis.Thereareperformanceissuesbutnothingtoworryaboutwhencreatingthe
initialdesign.

Thekeytocreatingmorecomplicatedlayoutswithflexboxistobreakitintopieces.Don'tbeafraidtomakeeverythingaflex
containerifthat'swhatworksforyou.

13