Flexbox header
Na tretjem CSS Meetupu #2016:first-child()
sem predstavil poenostavljeno kodo za flexbox header naše zadnje ProteusThemes WordPress teme, ki je še v izdelavi. Objavim link, ko bo sprejeta na ThemeForest.
HTML struktura
Za delovanje flexboxa najprej potrebujemo HTML strukturo, kjer imamo neke elemente znotraj containerja. V našem primeru bo container class .header
, elementi znotraj njega so pa .header__logo
, .header__widgets
, .header__navigation
in .header__social-icons
.
<header class="header">
<div class="header__logo">
Logo
</div>
<div class="header__widgets">
Widgets
</div>
<div class="header__navigation">
Navigation
</div>
<div class="header__social-icons">
Social Icons
</div>
</header>
Osnoven CSS
Sedaj, ko imamo strukturo narejeno, bomo vsakemu elementu določili različen background color. Le zato, da jih lažje ločimo med seboj. Pod resolucijo 992px bo širina vseh elementov 100%, nad 992px pa določimo neko fiksno širino in višino. Primer kode za class .header__logo
:
.header__logo {
background-color: red;
width: 100%;
}
@media (min-width: 992px) {
.header__logo {
width: 250px;
height: 150px;
}
}
Poglejmo, kaj se je zgodilo, če to kodo pogledamo v brskalniku.
Na resolucijah manjših od 992px lahko vidimo, da so vsi elementi en pod drugim in vsak zaseda 100% širine.
Nad 992px so spet vsi elementi eden pod drugim, le da imajo tukaj določeno še širino in višino.
Sedaj, ko imamo vse to pripravljeno, lahko začnemo s flexboxom.
Flexbox
.header {
display: flex;
}
Na container, v našem primeru je to class .header
, dodamo display: flex;
, na ta način smo flexbox aktivirali in to sedaj vpliva tudi na vse elemente (prvega nivoja) znotraj containerja.
Mobilna verzija:
Vidimo, da nam je tako za mobile kot za desktop verzijo strani vse elemente prestavilo v eno vrstico, čeprav imajo skupno širino večjo od 100%. Zakaj se to zgodi?
Flex Wrap
Kriva je privzeta flexbox nastavitev za flex-wrap
, ki je nowrap
. To pomeni, da flexbox ne pusti, da bi elementi skočili v novo vrstico. Če nowrap
spremenimo v wrap
, pa gredo v novo vrstico, če je njihova širina večja od 100%.
.header {
display: flex;
flex-wrap: wrap;
}
Flex Direction
Druga pomembna stvar tukaj je še flex-direction
, za katerega je privzeta nastavitev row
. Tukaj imamo na izbiro še row-reverse
, ki elemente razporedi v obratnem vrstnem redu. Zelo uporabno, če delamo RTL verzijo strani. Obstaja še column
in column-reverse
. Vse se obnaša isto kot pri row
, le da so tukaj elementi eden pod drugim. V našem primeru bomo uporabili nastavitev row
, saj hočemo, da so vsi naši elementi v vrsti in v normalnem vrstnem redu.
.header {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
Flex Flow
To kodo lahko še skrajšamo, tako da jo združimo v flex-flow
, kjer najprej napišemo flex-direction
potem pa še flex-wrap
.
.header {
display: flex;
flex-flow: row wrap;
}
Vidimo, da so se elementi lepo razporedili in da je širina upoštevana. Problem imamo le še z Navigation in Social Icons. V našem primeru lahko to rešimo tako, da .header__navigation
premaknemo v levo, kolikor je velik logo z margin-left
in dvignemo za 90px, točno toliko, kolikor imamo še praznega prostora pod Widgetsi. Podobno naredimo še s Social Icons. Ker imamo flex-wrap
nastavljen na wrap
bosta oba elementa lepo zapolnila prazen prostor pod widgetsi.
@media (min-width: 992px) {
.header__navigation {
width: calc(80% - 250px);
height: 90px;
margin-left: 250px;
margin-top: -90px;
}
}
@media (min-width: 992px) {
.header__social-icons {
width: 20%;
height: 90px;
margin-top: -90px;
}
}
Order
Še en majhen problem imamo pri resolucijah manjših od 992px. V dizajnu so Widgeti pred Logotom in ne za Logotom, kot je to na desktop verziji. Včasih bi to rešili tako, da bi kodo od widgetov imeli v HTMLju napisano 2x. Enkrat pred logotom, drugič za logotom, vse skupaj bi pa po potrebi skrivali z display: none;
. Stvar funkcionira, koda je pa grda in se po nepotrebnem 2x naloži.
Flexbox ima tudi tukaj super rešitev, in sicer order
. Prav order je eden izmed glavnih razlogov, da v naših temah v headerju uporabljamo flexbox. Uporaba je precej enostavna. Napišemo, kje po vrsti naj se določen element pojavi in to je to.
.header__logo {
order: 2;
}
@media (min-width: 992px) {
.header__logo {
order: 1;
}
}
.header__widgets {
order: 1;
}
@media (min-width: 992px) {
.header__widgets {
order: 2;
}
}
.header__navigation {
order: 3;
}
.header__social-icons {
order: 4;
}
V našem primeru order pustimo takšen, kot je za resolucije večje od 992px. Za manjše pa lahko vidimo, da smo za .header__logo
dodali order: 2;
za .header__widgets
pa order: 1
;
Flexbox header
Sedaj, ko imamo vso strukturo pripravljeno, popravimo background-color
barve, dodamo v vsak element primerno vsebino in naš header je končan.
Mobilna verzija:
Flexbox podpora
Za pregled podpore uporabimo spletno stran Can I Use: http://caniuse.com/#feat=flexbox. Vidimo, da je flexbox podprt povsod razen v starejših Internet Explorerjih.
IE10 in IE11 sta podprta samo delno zaradi kupa bugov, ki jih imata s flexboxom, ampak tudi za večino teh obstajajo že rešitve. Če ste prisiljeni podpirati tudi IE8 in IE9 pa obstaja Polyfill, ki vam bo rešil ta problem: https://github.com/10up/flexibility.
* Zaradi lepše predstavitve sem izpustil prefixe.