Alinierea Flexbox. Alinierea blocurilor cu css folosind un container flexibil. Dimensiune de bază: flex-base

Bună, habr!

Într-o seară bună, fără a prefigura ceva interesant, camera noastră de chat a primit o propunere de la autorul publicației „Translating 5 Really Useful Responsive Markup Templates into Code”, pe care a scris-o în primăvara lui 2012, pentru a scrie un articol remake, dar folosind FlexBox și o explicație însoțitoare despre ce și cum funcționează. După câteva îndoieli, interesul de a înțelege mai profund specificația a câștigat și eu și m-am așezat cu bucurie să scriu aceleași exemple. Pe măsură ce ne cufundam în această zonă, multe nuanțe au început să devină clare, care au devenit ceva mai mult decât reproiectarea layout-urilor. În general, în acest articol vreau să vorbesc despre o specificație atât de minunată numită „CSS Flexible Box Layout Module” și să arăt câteva dintre ele. caracteristici interesanteși exemple de aplicații. Îi invit cu drag pe toți cei interesați să se alăture hack-ului.

Ceea ce aș dori să vă atrag atenția este că pentru a crea un aspect pe FlexBox, dezvoltatorul va avea nevoie de un anumit grad de adaptare. Din propriul meu exemplu, am simțit că mulți ani de experiență fac o glumă crudă. FlexBox necesită un mod ușor diferit de a gândi despre alinierea elementelor într-un flux.

Partea tehnica

Înainte de a trece la orice exemple, merită să înțelegeți ce proprietăți sunt incluse în această specificație și cum funcționează. Din moment ce unele dintre ele nu sunt foarte clare inițial, iar altele sunt înconjurate de mituri care nu au nimic de-a face cu realitatea.

Aşa. Există două tipuri principale de elemente în FlexBox: Flex Container și copiii săi - Flex Items. Pentru a inițializa containerul, trebuie doar să atribuiți, prin css, elementului display: flex; sau display: inline-flex;. Diferența dintre flex și inline-flex este doar în principiul interacțiunii cu elementele care înconjoară containerul, similar cu afișajul: bloc; și afișare: inline-block;, respectiv.

În interiorul unui container flexibil sunt create două axe, axa principală și axa perpendiculară sau transversală. Cele mai multe elemente flexibile sunt aliniate de-a lungul axei principale și apoi de-a lungul axei transversale. În mod implicit, axa principală este orizontală și direcționată de la stânga la dreapta, iar axa transversală este verticală și direcționată de sus în jos.

Direcția axelor poate fi controlată folosind o proprietate css flex-direcție. Această proprietate ia un număr de valori:
rând(implicit): axa principală a containerului flexibil are aceeași orientare ca axa în linie a modului de direcție a rândului curent. Începutul (principal-start) și sfârșitul (principal-sfârșit) direcției axei principale corespund începutului (inline-start) și sfârșitului (inline-end) ale axei inline.
rând-invers: Totul este la fel ca în rând, doar main-start și main-end sunt schimbate.
coloană: la fel ca și rândul, doar că acum axa principală este direcționată de sus în jos.
coloană-invers: la fel ca și invers, numai axa principală este direcționată de jos în sus.
Puteți vedea cum funcționează acest lucru în exemplul de pe jsfiddle.

În mod implicit, toate elementele flexibile dintr-un container sunt plasate pe o singură linie, chiar dacă nu se potrivesc în container, se extind dincolo de limitele acestuia. Acest comportament este comutat folosind proprietatea flex-wrap. Această proprietate are trei stări:
nowrap(implicit): articolele Flex sunt aliniate într-o singură linie de la stânga la dreapta.
înfășura: elementele flexibile sunt construite în modul multi-linie, transferul se efectuează în direcția axei transversale, de sus în jos.
înfășurare-invers: la fel ca și wrap, dar se înfășoară de jos în sus.
Să ne uităm la un exemplu.

Pentru confort, există o proprietate suplimentară flex-flow, în care puteți specifica simultan flex-direcțieŞi flex-wrap. Arata cam asa: flux flexibil:

Elementele dintr-un container pot fi aliniate folosind proprietatea justifica-conținut de-a lungul axei principale. Această proprietate acceptă până la cinci valori diferite.
flex-start(implicit): Elementele flexibile sunt aliniate la originea axei principale.
flex-end: elementele sunt aliniate la capătul axei principale
centru: Elementele sunt aliniate la centrul axei principale
spațiu-între: Elementele ocupă toată lățimea disponibilă în container, elementele cele mai exterioare sunt presate strâns pe marginile containerului, iar spațiul liber este distribuit uniform între elemente.
spatiu-in jur: Elementele flexibile sunt aliniate astfel încât spațiul liber să fie distribuit uniform între elemente. Dar este de remarcat faptul că spațiul dintre marginea recipientului și elementele exterioare va fi la jumătate față de spațiul dintre elementele din mijlocul rândului.
Desigur, puteți face clic pe un exemplu despre cum funcționează această proprietate.

Asta nu este tot, avem și capacitatea de a alinia elemente de-a lungul axei transversale. Prin aplicarea proprietății alinierea elementelor, care ia și cinci valori diferite, puteți obține un comportament interesant. Această proprietate vă permite să aliniați elementele într-un rând unul față de celălalt.
flex-start: toate elementele sunt împinse la începutul liniei
flex-end: elementele sunt împinse până la capătul liniei
centru: elementele sunt aliniate la centrul rândului
linia de bază: Elementele sunt aliniate la linia de bază a textului
întinde(implicit): elementele sunt întinse pentru a umple întreaga linie.

O altă proprietate similară celei anterioare este alinierea-conținut. Este singurul responsabil pentru alinierea liniilor întregi în raport cu containerul flexibil. Nu va avea niciun efect dacă articolele flexibile ocupă o singură linie. Proprietatea ia șase valori diferite.
flex-start: toate liniile sunt apăsate la începutul axei transversale
flex-end: toate liniile sunt apăsate până la capătul axei transversale
centru: Toate liniile de pachet sunt aliniate la centrul axei transversale
spațiu-între: liniile sunt distribuite de la marginea superioară spre jos, lăsând spațiu liber între linii, în timp ce liniile cele mai exterioare sunt presate pe marginile recipientului.
spatiu-in jur: liniile sunt distribuite uniform în întregul container.
întinde(implicit): liniile sunt întinse pentru a ocupa tot spațiul disponibil.
Puteți încerca cum funcționează elementele de aliniere și conținutul de aliniere în acest exemplu. Am prezentat în mod specific aceste două proprietăți într-un singur exemplu, deoarece interacționează destul de strâns, fiecare realizând propria sa sarcină. Observați ce se întâmplă atunci când elementele sunt plasate pe o linie sau pe mai multe linii.

Am aranjat parametrii unui container flexibil, tot ce rămâne este să ne dăm seama de proprietățile elementelor flexibile.
Prima proprietate cu care ne vom familiariza este comanda. Această proprietate vă permite să schimbați poziția unui anumit element în flux. În mod implicit, toate elementele flexibile au ordine: 0;și sunt construite în ordinea curgerii naturale. În exemplu, puteți vedea cum sunt schimbate elementele dacă li se aplică diferite valori de ordine.

Una dintre proprietățile principale este flex-bază. Cu această proprietate putem specifica lățimea de bază a unui element flexibil. Valoarea implicită este auto. Această proprietate este strâns legată de flex-creștereŞi flex-contractie, despre care voi vorbi puțin mai târziu. Acceptă o valoare a lățimii în px, %, em și alte unități. În esență, aceasta nu este strict lățimea elementului flexibil, este un fel de punct de plecare. Față de care elementul se întinde sau se micșorează. În modul automat, elementul primește o lățime de bază în raport cu conținutul din interiorul său.

flex-creștere pe mai multe resurse are o descriere complet incorectă. Se spune că se presupune că stabilește raportul dintre dimensiunile elementelor din container. De fapt, acest lucru nu este adevărat. Această proprietate specifică factorul de mărire al elementului atunci când există spațiu liber în container. În mod implicit, această proprietate are valoarea 0. Să ne imaginăm că avem un container flex care are o lățime de 500px, în interiorul lui sunt două elemente flex, fiecare cu o lățime de bază de 100px. Acest lucru lasă încă 300 de pixeli de spațiu liber în container. Dacă specificăm flex-grow: 2 pentru primul element, iar flex-grow: 1; Ca urmare, aceste blocuri vor ocupa toată lățimea disponibilă a containerului, doar lățimea primului bloc va fi de 300 px, iar al doilea doar 200 px. Ce s-a întâmplat? Ceea ce s-a întâmplat este că cei 300 px de spațiu liber disponibil în container au fost distribuite între elemente într-un raport de 2:1, +200px pentru primul și +100px pentru al doilea. Acesta este de fapt modul în care funcționează.

Aici trecem fără probleme la o altă proprietate similară, și anume flex-contractie. Valoarea implicită este 1. De asemenea, stabilește un factor pentru modificarea lățimii elementelor, doar în direcția opusă. Dacă recipientul are o lățime Mai puțin decât suma lățimii de bază a elementelor, atunci această proprietate intră în vigoare. De exemplu, containerul are o lățime de 600px, iar baza flexibilă a elementelor este de 300px. Dați primului element flex-shrink: 2; și al doilea element flex-shrink: 1;. Acum să micșorăm containerul cu 300 px. Prin urmare, suma lățimii elementelor este cu 300px mai mare decât containerul. Această diferență este distribuită într-un raport de 2:1, așa că scădem 200px din primul bloc și 100px din al doilea. Noua dimensiune a elementelor este 100px și 200px, pentru primul și, respectiv, al doilea element. Dacă setăm flex-shrink la 0, atunci împiedicăm elementul să se micșoreze la o dimensiune mai mică decât lățimea de bază.

De fapt, aceasta este o descriere foarte simplificată a modului în care funcționează totul, astfel încât să fie clar principiu general. Mai detaliat, dacă cineva este interesat, algoritmul este descris în specificație.

Toate cele trei proprietăți pot fi scrise în formă prescurtată folosind expresia flex. Acesta arată astfel:
flex: ;
Și mai putem scrie două versiuni prescurtate, flex:auto;Şi flex: niciunul;, ceea ce înseamnă flex: 1 1 auto;Şi flex: 0 0 auto; respectiv.

Ultima proprietate a elementelor flexibile rămâne alinierea-sine. Totul este simplu aici, este la fel ca elementele de aliniere pentru un container, ceea ce vă permite să suprascrieți alinierea pentru un anumit element.

Gata, m-am saturat! Dați exemple!

Am rezolvat partea tehnică, s-a dovedit a fi destul de lungă, dar trebuie să intri în ea. Acum putem trece la aplicarea practică.
În timpul dezvoltării acelor „cinci șabloane de aspect responsive cu adevărat utile”, a trebuit să rezolvăm situații tipice pe care dezvoltatorii le întâlnesc destul de des. Cu flexbox, implementarea acestor soluții devine mai ușoară și mai flexibilă.
Să luăm același aspect al 4-lea, pentru că... are cele mai interesante elemente.

Mai întâi, să desemnăm lățimea principală a paginii, să o aliniem la centru și să apăsăm subsolul în partea de jos a paginii. Ca întotdeauna în general.

Html ( fundal: #ccc; min-height: 100%; font-family: sans-serif; display: -webkit-flex; display: flex; flex-direction: coloană; ) body ( marja: 0; padding: 0 15px ; display: -webkit-flex: flex: 10px; : 960px; margine: 430px;

Datorita faptului ca am specificat flex-grow: 1 pentru .main; se întinde la toată înălțimea disponibilă, apăsând astfel subsolul în partea de jos. Bonusul acestei soluții este că subsolul poate avea o înălțime nefixă.

Acum să plasăm logo-ul și meniul în antet.
.logo (dimensiune font: 0; margine: -10px 10px 10px 0; afișare: flex; flex: niciunul; aliniere-element: centru; ) .logo:before, .logo:after (conținut: ""; afișare: bloc ; ) .logo: înainte ( fundal: # 222; lățime: 50 px; înălțime: 50 px; margine: 0 10 px 0 20 px; chenar- rază: 50 %; ) . logo: după ( fundal: # 222; lățime: 90 px; înălțime : 30px; ) .nav ( margine: -5px 0 0 -5px; afișare: -webkit-flex; afișare: flex; flex-wrap: wrap; ) .nav-itm ( fundal: #222; lățime: 130px; înălțime: 50px; dimensiunea fontului: 1.5rem;

Deoarece antetul are flex-wrap: wrap; și justificare-conținut: spațiu-între; Logo-ul și meniul sunt împrăștiate pe diferite părți ale antetului, iar dacă nu există suficient spațiu pentru meniu, acesta se va deplasa elegant sub logo.

Apoi vedem o postare mare sau un banner, este dificil să spunem despre ce este vorba în mod specific, dar nu acesta este ideea. Avem o imagine în dreapta și text cu un titlu în stânga. Eu personal aderă la ideea că orice element ar trebui să fie cât mai flexibil posibil, indiferent dacă aspectul este adaptiv sau static. Deci in aceasta postare avem o bara laterala in care este plasata o poza strict vorbind, nu putem spune exact ce latime avem nevoie, pentru ca azi avem o poza mare, maine avem una mica, si nu vrem sa refacem; elementul de la zero de fiecare dată. Aceasta înseamnă că avem nevoie de bara laterală să ocupe locul de care are nevoie, iar restul spațiului va merge la conținut. Să facem asta:

Caseta (dimensiunea fontului: 1.25rem; înălțimea liniei: 1.5; stilul fontului: cursiv; marginea: 0 0 40px -50px; afișarea: -webkit-flex; afișarea: flex; flex-wrap: wrap; justificarea conținutului: center; .box-base ( margin-left: 50px; flex: 1 0 430px; ) .box-side ( margin-left: 50px; flex: none; ) .box-img (max-lățime: 100%; înălțime: auto)

După cum puteți vedea pentru .box-base, unde avem titlul și textul, am specificat lățimea bazei cu flex-base: 430px;, și, de asemenea, a interzis utilizarea contracției blocului flex-contractie: 0;. Cu această manipulare am spus că conținutul nu poate deveni mai mic de 430px lățime. Și având în vedere faptul că pentru .box indic flex-wrap: wrap;în momentul în care bara laterală și conținutul nu se potrivesc în container.box, bara laterală va cădea automat sub conținut. Și toate acestea fără aplicare @media! Cred că asta este într-adevăr foarte tare.

Rămânem cu conținut în trei coloane. Există mai multe soluții la această problemă, vă voi arăta una dintre ele, există o altă opțiune în celelalte aspecte.
Să creăm un container, să-l numim .content și să-l configurem.
.conținut ( margin-bottom: 30px; display: -webkit-flex; display: flex; flex-wrap: wrap; )

Containerul are trei coloane, .bannere, .postări, .comentarii
.bannere ( flex: 1 1 200 px; ) . postări ( marjă: 0 0 30 px 30 px; flex: 1 1 200 px; ) . comentarii ( marjă: 0 0 30 px 30 px; flex: 1 1 200 px; )

Am dat coloanelor o lățime de bază de 200px, astfel încât coloanele să nu se îngusteze prea mult, dar ar fi mai bine dacă ar fi mutate una sub cealaltă la nevoie.

Conform aspectului, nu ne vom putea lipsi de @media cu conținutul, așa că haideți să mai reglam puțin comportamentul coloanelor pentru lățime<800px и <600px.
@media ecran și (max-width: 800px) ( .bannere ( margin-left: -30px; display: -webkit-flex; display: flex; flex-basis: 100%; ) .posts ( margin-left: 0; ) ) Ecran @media și (lățime maximă: 600px) ( .conținut ( afișare: bloc; ) .bannere ( marjă: 0; afișare: bloc; ) .comments ( marjă: 0; ) )

Aceasta este toată magia atunci când vine vorba de crearea unui aspect pe FlexBox. O altă sarcină care mi-a plăcut este cea de-a 5-a aspect, în special se referă la adaptarea conținutului.

Vedem cum la rezoluția desktop postările sunt construite într-o grilă de trei la rând. Când lățimea ferestrei de vizualizare devine mai mică de 800 px, grila se transformă într-o coloană cu postări, în care fotografia postării este aliniată în partea stângă și dreaptă a conținutului postării, alternativ. Și dacă lățimea este mai mică de 600px, fotografia postată este complet ascunsă.
.grid ( display: -webkit-flex; display: flex; flex-wrap: wrap; justify-content: space-between; ) .grid-itm ( margin-bottom: 30px; flex-basis: calc(33,33% - 30px) * 2/3); display: -webkit-flex: flex-wrap: wrap ) .grid-img ( margine: 0 auto 20px; flex: 0 1 80%; ) 100%; grid-img ( flex: 0 0 auto; ) .grid-itm:nth-child(even) .grid-img ( margin: 0 0 0 30px; order: 2; ) .grid-itm:nth-child (impar) .grid-img ( margine: 0 30px 0 0; ) .grid-cont (flex: 1 1 auto; ) .grid-title ( text-align: left; ) ) @media ecran și (max-width: 600px) ( .grid-img (afișare: niciunul; ) )

De fapt, aceasta este doar o mică parte din ceea ce poate fi implementat cu FlexBox. Specificația vă permite să construiți machete de pagină foarte complexe folosind cod simplu.

Modul de aspect Flexbox ( din engleza Flexible Box - bloc flexibil), în prezent la „ Recomandare posibilă» Standardizare W3C ( Recomandarea candidatului W3C) urmărește să ofere o modalitate mai eficientă de aranjare, aliniere și alocare a spațiului între elementele dintr-un container, chiar dacă dimensiunea acestora este necunoscută și/sau determinată dinamic ( de aceea se numea „flexibil”).

Ideea principală din spatele aspectului flexibil este de a oferi unui container capacitatea de a schimba înălțimea/lățimea (și ordinea) elementelor sale pentru a umple în mod optim spațiul disponibil ( în principal pentru a suporta toate tipurile și dimensiunile de ecrane).

Un container flexibil întinde elementele pentru a umple spațiul gol sau le comprimă pentru a preveni revărsarea lor.

Cel mai important, marcajul Flexbox este independent de direcție, spre deosebire de marcajul obișnuit ( blocuri care sunt orientate vertical și elemente inline care sunt orientate orizontal).

Și, în timp ce elementele obișnuite de marcare funcționează bine pentru pagini, le lipsește flexibilitatea ( și acesta nu este un joc de cuvinte) pentru a susține aplicații mari și complexe ( mai ales când vine vorba de schimbarea orientării, mărimii, întinderii, micșorării și așa mai departe).

Notă: aspectul Flexbox este cel mai bun pentru componentele aplicației și machetele mici, în timp ce aspectul grilă este destinat pentru aspecte mai mari.

Concepte și termeni de bază

Deoarece Flexbox este un modul întreg și nu o proprietate separată, include multe elemente, inclusiv un întreg set de proprietăți. Unele sunt concepute pentru a fi aplicate pe un container ( element părinte cunoscut sub numele de container flexibil), în timp ce altele ar trebui aplicate elementelor copil ( să le numim elemente flexibile).

Dacă aspectul obișnuit se bazează pe direcțiile blocurilor și ale elementelor inline, atunci aspectul flexibil se bazează pe direcțiile fluxului flexibil. Vă rugăm să aruncați o privire la diagrama de mai jos din specificație, care explică ideea de bază din spatele markupului flexibil:


Practic, elementele vor fi plasate fie de-a lungul axei principale ( de la începutul principal până la punctul final principal), sau de-a lungul axei transversale ( de la început încrucișat la capăt încrucișat):
  • axa principală este axa principală a containerului flexibil de-a lungul căreia sunt plasate articolele flexibile. Atenție, nu este neapărat orizontal, poziția sa depinde de proprietatea flex-direction (vezi mai jos);
  • main-start | main-end - elementele flexibile sunt amplasate în interiorul containerului, pornind de la punctul de pornire principal și ajungând la punctul final principal;
  • dimensiunea principală este lățimea sau înălțimea elementului flexibil, în funcție de dimensiunea principală. Proprietatea dimensiune principală poate fi setată la lățime sau înălțime;
  • axa transversală – axa transversală perpendiculară pe axa principală. Direcția sa depinde de direcția axei principale.
  • pornire încrucișată | cross-end – liniile flexibile sunt umplute cu elemente și plasate în container, pornind de la partea de început încrucișată spre partea de capăt;
  • dimensiune cruce – lățimea sau înălțimea elementului flexibil, în funcție de dimensiunea selectată. Proprietatea poate fi fie lățimea, fie înălțimea dimensiunii crucii.

Proprietăți ale clasei părinte (container flexibil)

afişa

Această proprietate determină dacă containerul flexibil este în linie sau bloc, în funcție de valoarea setată. De asemenea, permite contextul flexibil pentru toți copiii săi direcți:

Container ( afișare: flex; /* sau inline-flex */ )

Rețineți că coloanele CSS nu au niciun efect într-un container flexibil.

flex-direcție

Această proprietate specifică o axă majoră care determină direcția în care articolele flexibile sunt plasate într-un container flexibil. Flexbox ( excluzând învelișul opțional) este un concept de marcare unidirecțională.

Imaginați-vă că articolele flexibile sunt plasate în principal în coloane orizontale sau verticale:

Container (direcție flexibilă: rând | rând invers | coloană | coloană inversă; )

  • rând (implicit): de la stânga la dreapta pentru ltr;
  • de la dreapta la stânga pentru rtl;
  • rând-invers: de la dreapta la stânga pentru în ltr;
  • de la stânga la dreapta pentru rtl;

coloană: la fel ca și rândul, dar de sus în jos;

coloană-invers: la fel ca rândul-invers, dar de jos în sus.

flex-wrap

  • În mod implicit, elementele flexibile vor încerca să se încadreze într-o singură linie. Puteți modifica acest lucru și înfășura elementele după cum este necesar folosind această proprietate. Direcția în care sunt amplasate noile linii joacă, de asemenea, un rol aici:
  • Container( flex-wrap: nowrap | wrap | wrap-reverse; )
  • nowrap (implicit): o linie/de la stânga la dreapta pentru ltr;

de la dreapta la stânga pentru rtl;

wrap : multilinie / de la stânga la dreapta pentru ltr ; de la dreapta la stânga pentru rtl;

flux flexibil:<‘flex-direction’> || <‘flex-wrap’>

wrap-reverse: multilinie / de la dreapta la stânga pentru ltr; de la stânga la dreapta pentru rtl.

flex-flow (se aplică elementului părinte al containerului flexibil)

Aceasta este o formă scurtă a proprietăților de direcție flexibilă și înfășurare flexibilă, care împreună definesc axele principale și transversale ale unui container flexibil. Valoarea implicită este row nowrap:

  • justifica-conținut
  • Această proprietate specifică alinierea de-a lungul axei principale. Acest lucru ajută la distribuirea spațiului liber în exces în cazul în care toate elementele flexibile dintr-un rând sunt inflexibile sau flexibile, dar au atins dimensiunea maximă. Această proprietate vă permite, de asemenea, să obțineți control asupra alinierii elementelor atunci când acestea depășesc limitele liniei:
  • centru : elementele sunt aliniate la centrul liniei;
  • space-between : elementele sunt distribuite uniform pe linie: primul element este situat la începutul liniei, ultimul la sfârșit;
  • space-around : elementele sunt distribuite uniform pe linie cu aceeași distanță între ele.

alinierea elementelor

Această proprietate determină modul în care elementele flexibile sunt poziționate implicit în raport cu axa transversală pe linia curentă. Poate fi considerată versiunea pe axa transversală a justify-content ( perpendicular pe principal):

Container ( alinierea elementelor: flex-start | flex-end | centru | linie de bază | stretch; )

  • flex-start: marginea elementelor cross-start este situată pe linia cross-start;
  • flex-end: marginea elementelor de pornire încrucișată este situată pe linia de capăt transversal;
  • centru : elementele sunt situate în centrul axei transversale;
  • linia de bază: elementele sunt aliniate conform liniei de bază;
  • stretch (implicit): elementele sunt întinse pentru a umple recipientul ( luând în considerare valorile min-width/max-width).

alinierea-conținut

Această proprietate permite ca liniile dintr-un container flexibil să fie aliniate atunci când există spațiu liber pe axa transversală, similar modului în care proprietatea justify-content aliniază elementele individuale de-a lungul axei majore.

Notă: această proprietate nu va funcționa dacă există un singur rând de elemente flexibile:

Container ( align-content: flex-start | flex-end | centru | spațiu între | spațiu-în jur | întindere; )

  • flex-start: liniile sunt plasate la începutul containerului;
  • flex-end: liniile sunt plasate la capătul containerului;
  • centru: liniile sunt situate în mijlocul containerului;
  • spatiu intre : liniile sunt distribuite uniform; prima linie este la începutul containerului, iar ultima linie este la sfârșit;
  • space-around : liniile sunt distanțate uniform la aceeași distanță unele de altele;
  • întindere (implicit): liniile sunt întinse pentru a umple spațiul rămas.

Proprietățile elementelor copil

(elemente flexibile)

Comanda

În mod implicit, elementele flexibile sunt aranjate în ordinea specificată de sursă. Cu toate acestea, proprietatea de comandă controlează ordinea în care articolele apar într-un container flexibil:

Articol (comanda: ; }

flex-creștere

Această proprietate permite unui element flexibil să „crească” după cum este necesar. El capătă o valoare adimensională care servește drept proporție. Această valoare determină cât spațiu disponibil în containerul flexibil poate ocupa articolul.

Dacă toate elementele au proprietatea flex-grow setată la 1, atunci fiecare element copil va fi setat la aceeași dimensiune în interiorul containerului. Dacă setați unul dintre elementele copil la 2, atunci va ocupa de două ori mai mult spațiu decât celelalte:

Articol (flex-grow: ; /* implicit 0 */ )

flex-contractie

Această proprietate permite articolelor flexibile să se micșoreze atunci când este necesar:

Articol ( flex-shrink: ; /* implicit 1 */ )

Numerele negative nu sunt permise.

flex-bază

Această proprietate determină dimensiunea implicită a elementelor înainte de a aloca spațiul rămas:

Articol (bază flexibilă: | auto; /* implicit este automat */ )

flex

Această proprietate este o formă prescurtată pentru o combinație a proprietăților flex-grow, flex-shrink și flex-base. Al doilea și al treilea parametri (flex-shrink și flex-basis) sunt opționali. Valori implicite: 0 1 auto:

Articol ( flex: niciunul | [<"flex-grow"> <"flex-shrink">? || <"flex-basis"> ] }

aliniere-sine

Această proprietate vă permite să suprascrieți alinierea implicită ( sau definit de proprietatea align-items) pentru elemente flexibile individuale.

Puteți găsi valorile disponibile în descrierea proprietății align-items:

Element ( aliniere: automat | flex-start | flex-end | centru | linie de bază | stretch; )

Vă rugăm să rețineți că float, clear și vertical-align nu funcționează cu elementele flexibile.

Exemple

Să începem cu un exemplu foarte simplu, rezolvând o problemă aproape de zi cu zi: alinierea perfectă la centru. Nimic nu ar putea fi mai ușor dacă folosești flexbox:

Părinte ( afișare: flex; înălțime: 300 px; /* Sau orice */ ) .copil ( lățime: 100 px; /* Sau orice */ înălțime: 100 px; /* Sau orice */ margine: auto; /* Magic ! */ )

Acest exemplu se bazează pe faptul că proprietatea marjă setată la auto consumă spațiu suplimentar. Prin urmare, setarea offset-ului în acest fel aliniază elementul exact în centrul ambelor axe.

Acum să folosim câteva proprietăți suplimentare. Să presupunem că avem o listă de 6 elemente, toate de dimensiune fixă ​​( pentru estetică), dar cu capacitatea de a se completa automat.

Vrem să fie drăguțe, distribuite uniform de-a lungul axei orizontale, astfel încât atunci când redimensionăm fereastra browserului, totul să arate bine ( fără a utiliza interogări media):

Flex-container ( /* Mai întâi creăm un context flex layout */ display: flex; /* Apoi definim direcția fluxului și dacă dorim ca elementele să fie înfășurate. * Amintiți-vă că acesta este același cu: * flex-direction : row; * flex-wrap: wrap */ flex-flow: row wrap;

Gata! Orice altceva este doar o chestiune de design. Iată o demonstrație a acestui exemplu. Urmați linkul și încercați să redimensionați fereastra pentru a vedea ce se întâmplă:

HTML:

CSS:

Flex-container ( umplutură: 0; margine: 0; list-style: niciunul; afișare: -webkit-box; afișare: -moz-box; afișare: -ms-flexbox; afișare: -webkit-flex; afișare: flex; -webkit-flex-flow: row wrap; justify-content: space-around; .flex-item ( fundal: roșie; umplutură: 5px; lățime: 200px; înălțime: 150px; margin-top: 10px; line-height: 150px ; dimensiunea fontului: bold;

Să încercăm altceva. Să presupunem că avem un meniu de navigare aliniat la dreapta în partea de sus a site-ului nostru web, dar dorim ca acesta să fie centrat pe ecrane de dimensiuni medii și într-o singură coloană pentru dispozitivele cu ecran mic. Este destul de simplu:

CSS:

/* Ecrane mari */ .navigation ( display: flex; flex-flow: row wrap; /* Aliniați elementele la sfârșitul rândului de-a lungul axei principale */ justify-content: flex-end; ) /* Ecrane medii * / @media all și (max-width: 800px) ( .navigation ( /* Pentru ecranele de dimensiuni medii, centrem elementele, distribuind uniform spațiul alb între ele */ justify-content: space-around; ) ) /* Ecrane mici */ @media all and (max-width: 500px) ( .navigation ( /* Pentru ecrane mici folosim direcția coloanei în loc de rândul */ flex-direction: coloana; ) )

HTML:

CSS:

Navigare (stil listă: niciuna; marjă: 0; fundal: deepskyblue; afișare: -webkit-box; afișare: -moz-box; afișare: -ms-flexbox; afișare: -webkit-flex; afișare: flex; -webkit -flex-flow: row wrap; justify-content: flex-end ) .navigation a ( text-decor: none; display: block; padding: 1em; color: white; ) .navigation a: hover ( background: darken( deepskyblue, 2%) ) @media all și (max-width: 800px) ( .navigation ( justify-content: space-around; ) ) @media all și (max-width: 600px) ( .navigation ( -webkit-) flex-flow: coloană; flex-flow: coloană: 0 .navigation a ( text-align: center; padding: 10px; border-top: 1px solid rgba(255,255,255,0.3); border-bottom: 1px solid rgba (0,0,0,0.1 .navigation li:last-of-type a (border-bottom: niciunul; ) )

Să încercăm să o facem și mai bine jucându-ne cu „flexibilitatea” elementelor flexibile. Ce zici de un aspect mobil cu trei coloane cu un antet și un subsol la lățime completă? Și cu ieșirea elementelor independente de ordinea specificată de codul sursă:

CSS:

Wrapper ( display: flex; flex-flow: row wrap; ) /* Setați lățimea pentru toate elementele la 100% */ .header, .main, .nav, .aside, .footer (flex: 1 100%; ) / * În acest caz, pentru a viza dispozitivele mobile, ne bazăm pe ordinea inițială: * 1. antet * 2. navigare * 3. corp * 4. bară laterală * 5. subsol */ /* Ecrane din mijloc */ @media all și ( min -width: 600px) ( /* Ambele bare laterale sunt pe aceeași linie */ .aside ( flex: 1 auto; ) ) ) /* Ecrane mari */ @media all și (min-width: 800px) ( /* inversează afișați comanda prima bară laterală și partea principală și spuneți elementului principal să ocupe cel mult de două ori spațiul celor două bare laterale */ .main ( flex: 2 0px; ) .aside-1 ( order: 1; ) .main ( ordine: 2; ) .aside-2 ( ordine: 3; ) .footer ( ordine: 4; ) )

Proprietatea order controlează ordinea în care apar elementele copil într-un container flexibil. În mod implicit, acestea sunt aranjate în ordinea în care au fost adăugate inițial în containerul flexibil.

Valori

.flex-element ( comanda:<целое число>; }

Articolele Flex pot fi reordonate folosind această proprietate simplă fără a schimba codul HTML.

Valoare implicită: 0.

flex-creștere

Această proprietate specifică un factor de creștere, care determină cât de mult va crește un element flexibil în raport cu alte elemente flexibile din containerul flexibil atunci când se alocă spațiu liber pozitiv.

Valori

.flex-element (flex-grow:<число>; }

Dacă toate articolele flexibile au aceeași valoare de creștere flexibilă, atunci toate articolele vor avea aceeași dimensiune în container.

Al doilea element flexibil ocupă mai mult spațiu în raport cu dimensiunea celorlalte articole flexibile.

Valoare implicită: 0.

flex-contractie

flex-shrink specifică un factor de contracție care determină cât de mult se va micșora un articol flexibil în raport cu alte elemente flexibile din containerul flexibil atunci când se distribuie spațiu liber negativ.

Valori

.flex-element ( flex-shrink:<число>; }

În mod implicit, toate elementele flexibile pot fi micșorate, dar dacă setăm valoarea de micșorare flexibilă la zero (fără micșorare), atunci articolele își păstrează dimensiunea inițială.

Valoare implicită: 1.

Numerele negative nu sunt permise.

flex-bază

Această proprietate ia aceleași valori ca și proprietățile de lățime și înălțime și specifică dimensiunea de bază inițială a elementului flexibil, înainte ca spațiul liber să fie alocat în funcție de rapoarte.

Valori

.flex-item ( flex-basis: auto |<ширина>; }

flex-basis este specificat pentru al patrulea articol flexibil și dictează dimensiunea inițială a acestuia.

Valoare implicită:auto.

flex

Această proprietate este prescurtarea pentru proprietățile flex-grow, flex-shrink și flex-base. Printre alte valori, puteți seta și auto (1 1 auto ) și niciunul (0 0 auto ).

Valori

.flex-element (flex: niciunul | auto | [ ? || ]; }

Valoare implicită: 0 1 auto .

W3C recomandă utilizarea proprietății flex shorthand în loc de proprietăți individuale, deoarece flex resetează corect orice componente nespecificate pentru utilizare obișnuită.

aliniere-sine

Proprietatea align-self vă permite să înlocuiți alinierea implicită (sau valoarea specificată prin align-items ) pentru elementele flexibile individuale. Pentru a înțelege valorile disponibile, consultați descrierea elementelor de aliniere pentru containerul flexibil.

Valori

.flex-element ( align-self: auto | flex-start | flex-end | centru | linie de bază | stretch; )

Pentru al treilea și al patrulea element flexibil, alinierea a fost redefinită prin proprietatea align-self.

  • Traducere

Despre autor: Rachel Andrew nu este doar redactorul-șef al revistei Smashing Magazine, ci și dezvoltator web, scriitor și vorbitor. Este autoarea mai multor cărți, inclusiv Noul aspect CSS, unul dintre dezvoltatorii sistemului de management al conținutului Perch. Scrie despre afaceri și tehnologie pe site-ul său web rachelandrew.co.uk.

Rezumat:În acest articol, ne vom uita la proprietățile de aliniere din Flexbox și câteva reguli de bază privind modul în care funcționează alinierea de-a lungul axei principale și transversale.

Valorile funcționează la fel pe verticală, adică dacă direcția flexibilă este aplicată coloanei. Adevărat, este posibil să nu aveți spațiu liber în coloană pentru distribuție dacă nu adăugați o înălțime sau o dimensiune de bloc la container, ca în această demonstrație.

Alinierea axelor folosind align-content

Dacă containerul are mai multe axe și flex-wrap: wrap este specificat, atunci align-content poate fi folosit pentru a alinia rândurile pe axa transversală. Dar este nevoie de spațiu suplimentar. În această demonstrație, axa transversală rulează în direcția coloanei și am specificat o înălțime a containerului de 60vh. Deoarece acest lucru este mai mult decât este necesar pentru afișarea tuturor elementelor, există spațiu vertical liber.

Apoi pot aplica align-content cu oricare dintre .

Dacă direcția flexibilă este coloana , atunci align-content funcționează ca în exemplul următor.

Ca și în cazul justify-content , lucrăm cu un grup de rânduri și alocăm spațiu liber.

Proprietate după loc-conținut

În specificația de aliniere a casetei, puteți găsi proprietatea locație-conținut. Folosirea acestei proprietăți înseamnă că setați în același timp justify-content și align-content. Prima valoare este pentru align-content , a doua este pentru justify-content . Dacă este specificată o singură valoare, aceasta se aplică ambelor proprietăți:

Container ( loc-conținut: spațiu-între întindere; )
Corespunde cu aceasta:

Container ( aliniere-conținut: spațiu-între; justificare-conținut: întindere; )
Și acest cod:

Container ( loc-conținut: spațiu-între; )
Echivalent cu următoarele:

Container ( aliniere-conținut: spațiu-între; justificare-conținut: spațiu-între; )

Alinierea axelor folosind elemente de aliniere

Acum știm că putem alinia un set de elemente sau rânduri ca grup. Cu toate acestea, există o altă modalitate de a alinia elementele unul față de celălalt pe o axă transversală. Un container are o înălțime, care este determinată de înălțimea celui mai înalt element.


Alternativ, poate fi definit prin proprietatea înălțime din container:


De ce elementele sunt întinse la dimensiunea celui mai înalt element se datorează faptului că valoarea inițială a parametrului align-items este stretch . Elementele sunt întinse de-a lungul axei transversale la dimensiunea containerului în acea direcție.

Rețineți că într-un container cu mai multe linii, fiecare linie acționează ca un nou container. Cel mai înalt element din acel rând va determina dimensiunea tuturor elementelor din acel rând.

Pe lângă valoarea de pornire stretch , puteți seta align-items la flex-start , caz în care acestea sunt aliniate la începutul containerului și nu se mai întinde în înălțime.


Valoarea flex-end le mută la capătul containerului de-a lungul axei transversale.


Dacă utilizați centrul valorii , atunci elementele sunt centrate unul față de celălalt:


De asemenea, le putem alinia la linia de bază. Acest lucru asigură că textul este aliniat la aceeași bază, spre deosebire de alinierea marginilor în jurul textului.


Toate aceste opțiuni pot fi încercate în demo.

Aliniere personalizată folosind align-self

Proprietatea align-items specifică alinierea tuturor elementelor simultan. De fapt, stabilește valorile align-self pentru toate elementele grupului. De asemenea, puteți utiliza proprietatea align-self pe orice element pentru a-l alinia într-o linie și în raport cu alte elemente.

Următorul exemplu folosește align-items din container pentru a centra întregul grup, dar și align-self pentru primul și ultimul element.

De ce nu există sinele justificat?

Adesea apare întrebarea de ce nu este posibilă alinierea unui element sau grup de elemente de-a lungul unei axe majore. De ce Flexbox nu are o proprietate -self pentru alinierea axelor majore? Dacă te gândești la justify-content și align-content ca o modalitate de a aloca spațiu, răspunsul devine mai evident. Ne ocupăm de elemente ca grup și plasăm spațiul liber într-un anumit fel: fie la începutul sau la sfârșitul grupului, fie între elemente.

De asemenea, ar putea fi util să ne gândim la modul în care funcționează justificarea conținutului și alinierea conținutului în aspectul grilă CSS. În Grid, aceste proprietăți sunt folosite pentru a aloca spațiu liber în containerul grilă. între pistele grilei. Și aici luăm un grup de piste - și folosind aceste proprietăți distribuim spațiu liber între ele. Deoarece operăm într-un grup atât în ​​Grid, cât și în Flexbox, nu putem lua un singur element și facem ceva diferit cu el. Cu toate acestea, există o modalitate de a obține designul de aspect pe care designerii de aspect îl doresc atunci când vorbesc despre proprietatea proprie pe axa principală. Aceasta este utilizarea câmpurilor automate.

Utilizarea marjelor automate pe axa primară

Dacă ați centrat vreodată un bloc în CSS (de exemplu, un wrapper pentru conținutul paginii de pornire setând marginile din stânga și din dreapta la automat), atunci aveți deja ceva experiență cu marginile automate. O valoare auto pentru margini umple cât mai mult spațiu posibil în direcția specificată. Pentru a centra blocul, am setat atât marginile din stânga, cât și din dreapta la automat: fiecare încearcă să ocupe cât mai mult spațiu posibil și, prin urmare, plasează blocul nostru în centru.

Marginile automate funcționează foarte bine în Flexbox pentru alinierea elementelor individuale sau a grupurilor de elemente pe axa principală. Următorul exemplu arată un caz tipic. Există o bară de navigare, articolele sunt afișate ca șir și folosesc valoarea inițială justify-content: start . Vreau ca ultimul element să apară separat de celelalte la sfârșitul rândului - cu condiția să existe suficient spațiu în linie pentru ca acest lucru să se întâmple.

Luăm acest element și setăm proprietatea margin-left la auto . Aceasta înseamnă că caseta încearcă să obțină cât mai mult spațiu în stânga elementului, ceea ce înseamnă că elementul este împins la marginea dreaptă.

Dacă utilizați marje automate pe axa principală, atunci justify-content nu va mai avea efect, deoarece marginile automate vor ocupa tot spațiul care altfel ar fi alocat folosind justify-content .

Aliniere de rezervă

Pentru fiecare metodă de aliniere, este descrisă o alternativă - ce se va întâmpla dacă alinierea specificată nu este posibilă. De exemplu, dacă aveți doar un element într-un container și specificați justify-content: space-between , ce ar trebui să se întâmple? În acest caz, se aplică alinierea de rezervă flex-start - un element va fi aliniat la începutul containerului. În cazul justify-content: space-around, alinierea de rezervă este center .

În specificația actuală nu puteți modifica alinierea de rezervă. Există o notă de specificație care permite posibilitatea de a specifica o rezervă arbitrară în versiunile viitoare.

Aliniere sigură și nesigură

O adăugare recentă la specificația Box Alignment este conceptul de aliniere sigură și nesigură folosind cuvinte cheie seifŞi nesigure.

În codul următor, ultimul element este prea lat pentru container, iar cu o aliniere nesigură și un container flexibil în partea stângă a paginii, elementul este tăiat deoarece debordarea se extinde dincolo de limitele paginii.

Container ( afișare: flex; direcție flexibilă: coloană; lățime: 100 px; elemente de aliniere: centru nesigur; ) .item:last-child ( lățime: 200 px; )


Alinierea securizată previne pierderea datelor prin mutarea supraîncărcării pe cealaltă parte.

Container ( afișare: flex; direcție flexibilă: coloană; lățime: 100 px; aliniere: centru sigur; ) .item:last-child ( lățime: 200 px; )


Aceste cuvinte cheie nu sunt încă acceptate de toate browserele, dar demonstrează modul în care specificațiile de aliniere a casetei adaugă control la Flexbox.

Concluzie

Proprietățile de aliniere au început ca o listă în Flexbox, dar acum au propria lor specificație și se aplică altor contexte de aspect. Iată câteva fapte cheie pentru a vă ajuta să vă amintiți utilizarea lor în Flexbox:
  • justificați - pentru axele principale și aliniați - pentru cele transversale;
  • alinierea-conținut și justificarea-conținut necesită spațiu liber;
  • proprietățile align-content și justify-content sunt aplicate elementelor din grup, distribuind spațiul între ele. Nu puteți specifica alinierea unui element individual deoarece lipsește proprietatea -self;
  • dacă doriți să aliniați un element sau să împărțiți un grup de-a lungul axei principale, utilizați câmpuri automate;
  • align-items stabilește aceleași proprietăți align-self pentru întregul grup. Utilizați align-self pe un element copil al unui grup pentru a-i seta valoarea individual.

Etichete: Adăugați etichete

Bună, habr!

Într-o seară bună, fără a prefigura ceva interesant, chat-ul nostru a primit o propunere de la autorul unei publicații pe care a scris-o în primăvara lui 2012, de a scrie un articol remake, dar folosind FlexBox și o explicație însoțitoare despre ce și cum funcționează. După câteva îndoieli, interesul de a înțelege mai profund specificația a câștigat și eu și m-am așezat cu bucurie să scriu aceleași exemple. Pe măsură ce ne cufundam în această zonă, multe nuanțe au început să devină clare, care au devenit ceva mai mult decât doar reproiectarea layout-urilor. În general, în acest articol vreau să vorbesc despre o specificație atât de minunată numită „CSS Flexible Box Layout Module” și să arăt câteva dintre caracteristicile sale interesante și exemple de aplicație. Îi invit cu drag pe toți cei interesați să se alăture hack-ului.

Ceea ce aș dori să vă atrag atenția este că pentru a crea un aspect pe FlexBox, dezvoltatorul va avea nevoie de un anumit grad de adaptare. Din propriul meu exemplu, am simțit că mulți ani de experiență fac o glumă crudă. FlexBox necesită un mod ușor diferit de a gândi despre alinierea elementelor într-un flux.

Partea tehnica

Înainte de a trece la orice exemple, merită să înțelegeți ce proprietăți sunt incluse în această specificație și cum funcționează. Din moment ce unele dintre ele nu sunt foarte clare inițial, iar altele sunt înconjurate de mituri care nu au nimic de-a face cu realitatea.

Aşa. Există două tipuri principale de elemente în FlexBox: Flex Container și copiii săi - Flex Items. Pentru a inițializa containerul, trebuie doar să atribuiți, prin css, elementului display: flex; sau display: inline-flex;. Diferența dintre flex și inline-flex este doar în principiul interacțiunii cu elementele care înconjoară containerul, similar cu afișajul: bloc; și afișare: inline-block;, respectiv.

În interiorul unui container flexibil sunt create două axe, axa principală și axa perpendiculară sau transversală. Cele mai multe elemente flexibile sunt aliniate de-a lungul axei principale și apoi de-a lungul axei transversale. În mod implicit, axa principală este orizontală și direcționată de la stânga la dreapta, iar axa transversală este verticală și direcționată de sus în jos.

Direcția axelor poate fi controlată folosind o proprietate css flex-direcție. Această proprietate ia un număr de valori:
rând(implicit): axa principală a containerului flexibil are aceeași orientare ca axa în linie a modului de direcție a rândului curent. Începutul (principal-start) și sfârșitul (principal-sfârșit) direcției axei principale corespund începutului (inline-start) și sfârșitului (inline-end) ale axei inline.
rând-invers: Totul este la fel ca în rând, doar main-start și main-end sunt schimbate.
coloană: la fel ca și rândul, doar că acum axa principală este direcționată de sus în jos.
coloană-invers: la fel ca și invers, numai axa principală este direcționată de jos în sus.
Puteți vedea cum funcționează acest lucru în exemplul de pe jsfiddle.

În mod implicit, toate elementele flexibile dintr-un container sunt plasate pe o singură linie, chiar dacă nu se potrivesc în container, se extind dincolo de limitele acestuia. Acest comportament este comutat folosind proprietatea flex-wrap. Această proprietate are trei stări:
nowrap(implicit): articolele Flex sunt aliniate într-o singură linie de la stânga la dreapta.
înfășura: elementele flexibile sunt construite în modul multi-linie, transferul se efectuează în direcția axei transversale, de sus în jos.
înfășurare-invers: la fel ca și wrap, dar se înfășoară de jos în sus.
Să ne uităm la un exemplu.

Pentru confort, există o proprietate suplimentară flex-flow, în care puteți specifica simultan flex-direcțieŞi flex-wrap. Arata cam asa: flux flexibil:

Elementele dintr-un container pot fi aliniate folosind proprietatea justifica-conținut de-a lungul axei principale. Această proprietate acceptă până la cinci valori diferite.
flex-start(implicit): Elementele flexibile sunt aliniate la originea axei principale.
flex-end: elementele sunt aliniate la capătul axei principale
centru: Elementele sunt aliniate la centrul axei principale
spațiu-între: Elementele ocupă toată lățimea disponibilă în container, elementele cele mai exterioare sunt presate strâns pe marginile containerului, iar spațiul liber este distribuit uniform între elemente.
spatiu-in jur: Elementele flexibile sunt aliniate astfel încât spațiul liber să fie distribuit uniform între elemente. Dar este de remarcat faptul că spațiul dintre marginea recipientului și elementele exterioare va fi la jumătate față de spațiul dintre elementele din mijlocul rândului.
Desigur, puteți face clic pe un exemplu despre cum funcționează această proprietate.

Asta nu este tot, avem și capacitatea de a alinia elemente de-a lungul axei transversale. Prin aplicarea proprietății alinierea elementelor, care ia și cinci valori diferite, puteți obține un comportament interesant. Această proprietate vă permite să aliniați elementele într-un rând unul față de celălalt.
flex-start: toate elementele sunt împinse la începutul liniei
flex-end: elementele sunt împinse până la capătul liniei
centru: elementele sunt aliniate la centrul rândului
linia de bază: Elementele sunt aliniate la linia de bază a textului
întinde(implicit): elementele sunt întinse pentru a umple întreaga linie.

O altă proprietate similară celei anterioare este alinierea-conținut. Este singurul responsabil pentru alinierea liniilor întregi în raport cu containerul flexibil. Nu va avea niciun efect dacă articolele flexibile ocupă o singură linie. Proprietatea ia șase valori diferite.
flex-start: toate liniile sunt apăsate la începutul axei transversale
flex-end: toate liniile sunt apăsate până la capătul axei transversale
centru: Toate liniile de pachet sunt aliniate la centrul axei transversale
spațiu-între: liniile sunt distribuite de la marginea superioară spre jos, lăsând spațiu liber între linii, în timp ce liniile cele mai exterioare sunt presate pe marginile recipientului.
spatiu-in jur: liniile sunt distribuite uniform în întregul container.
întinde(implicit): liniile sunt întinse pentru a ocupa tot spațiul disponibil.
Puteți încerca cum funcționează elementele de aliniere și conținutul de aliniere în acest exemplu. Am prezentat în mod specific aceste două proprietăți într-un singur exemplu, deoarece interacționează destul de strâns, fiecare realizând propria sa sarcină. Observați ce se întâmplă atunci când elementele sunt plasate pe o linie sau pe mai multe linii.

Am aranjat parametrii unui container flexibil, tot ce rămâne este să ne dăm seama de proprietățile elementelor flexibile.
Prima proprietate cu care ne vom familiariza este comanda. Această proprietate vă permite să schimbați poziția unui anumit element în flux. În mod implicit, toate elementele flexibile au ordine: 0;și sunt construite în ordinea curgerii naturale. În exemplu, puteți vedea cum sunt schimbate elementele dacă li se aplică diferite valori de ordine.

Una dintre proprietățile principale este flex-bază. Cu această proprietate putem specifica lățimea de bază a unui element flexibil. Valoarea implicită este auto. Această proprietate este strâns legată de flex-creștereŞi flex-contractie, despre care voi vorbi puțin mai târziu. Acceptă o valoare a lățimii în px, %, em și alte unități. În esență, aceasta nu este strict lățimea elementului flexibil, este un fel de punct de plecare. Față de care elementul se întinde sau se micșorează. În modul automat, elementul primește o lățime de bază în raport cu conținutul din interiorul său.

flex-creștere pe mai multe resurse are o descriere complet incorectă. Se spune că se presupune că stabilește raportul dintre dimensiunile elementelor din container. De fapt, acest lucru nu este adevărat. Această proprietate specifică factorul de mărire al elementului atunci când există spațiu liber în container. În mod implicit, această proprietate are valoarea 0. Să ne imaginăm că avem un container flex care are o lățime de 500px, în interiorul lui sunt două elemente flex, fiecare cu o lățime de bază de 100px. Acest lucru lasă încă 300 de pixeli de spațiu liber în container. Dacă specificăm flex-grow: 2 pentru primul element, iar flex-grow: 1; Ca urmare, aceste blocuri vor ocupa toată lățimea disponibilă a containerului, doar lățimea primului bloc va fi de 300 px, iar al doilea doar 200 px. Ce s-a întâmplat? Ceea ce s-a întâmplat este că cei 300 px de spațiu liber disponibil în container au fost distribuite între elemente într-un raport de 2:1, +200px pentru primul și +100px pentru al doilea. Acesta este de fapt modul în care funcționează.

Aici trecem fără probleme la o altă proprietate similară, și anume flex-contractie. Valoarea implicită este 1. De asemenea, stabilește un factor pentru modificarea lățimii elementelor, doar în direcția opusă. Dacă recipientul are o lățime Mai puțin decât suma lățimii de bază a elementelor, atunci această proprietate intră în vigoare. De exemplu, containerul are o lățime de 600px, iar baza flexibilă a elementelor este de 300px. Dați primului element flex-shrink: 2; și al doilea element flex-shrink: 1;. Acum să micșorăm containerul cu 300 px. Prin urmare, suma lățimii elementelor este cu 300px mai mare decât containerul. Această diferență este distribuită într-un raport de 2:1, așa că scădem 200px din primul bloc și 100px din al doilea. Noua dimensiune a elementelor este 100px și 200px, pentru primul și, respectiv, al doilea element. Dacă setăm flex-shrink la 0, atunci împiedicăm elementul să se micșoreze la o dimensiune mai mică decât lățimea de bază.

De fapt, aceasta este o descriere foarte simplificată a modului în care funcționează totul, astfel încât principiul general să fie clar. Mai detaliat, dacă cineva este interesat, algoritmul este descris în specificație.

Toate cele trei proprietăți pot fi scrise în formă prescurtată folosind expresia flex. Acesta arată astfel:
flex: ;
Și mai putem scrie două versiuni prescurtate, flex:auto;Şi flex: niciunul;, ceea ce înseamnă flex: 1 1 auto;Şi flex: 0 0 auto; respectiv.

Ultima proprietate a elementelor flexibile rămâne alinierea-sine. Totul este simplu aici, este la fel ca elementele de aliniere pentru un container, ceea ce vă permite să suprascrieți alinierea pentru un anumit element.

Gata, m-am saturat! Dați exemple!

Am rezolvat partea tehnică, s-a dovedit a fi destul de lungă, dar trebuie să intri în ea. Acum putem trece la aplicarea practică.
În timpul dezvoltării acelor „cinci șabloane de aspect responsive cu adevărat utile”, a trebuit să rezolvăm situații tipice pe care dezvoltatorii le întâlnesc destul de des. Cu flexbox, implementarea acestor soluții devine mai ușoară și mai flexibilă.
Să luăm același aspect al 4-lea, pentru că... are cele mai interesante elemente.

Mai întâi, să desemnăm lățimea principală a paginii, să o aliniem la centru și să apăsăm subsolul în partea de jos a paginii. Ca întotdeauna în general.

Html ( fundal: #ccc; min-height: 100%; font-family: sans-serif; display: -webkit-flex; display: flex; flex-direction: coloană; ) body ( marja: 0; padding: 0 15px ; display: -webkit-flex: flex: 10px; : 960px; margine: 430px;

Datorita faptului ca am specificat flex-grow: 1 pentru .main; se întinde la toată înălțimea disponibilă, apăsând astfel subsolul în partea de jos. Bonusul acestei soluții este că subsolul poate avea o înălțime nefixă.

Acum să plasăm logo-ul și meniul în antet.
.logo (dimensiune font: 0; margine: -10px 10px 10px 0; afișare: flex; flex: niciunul; aliniere-element: centru; ) .logo:before, .logo:after (conținut: ""; afișare: bloc ; ) .logo: înainte ( fundal: # 222; lățime: 50 px; înălțime: 50 px; margine: 0 10 px 0 20 px; chenar- rază: 50 %; ) . logo: după ( fundal: # 222; lățime: 90 px; înălțime : 30px; ) .nav ( margine: -5px 0 0 -5px; afișare: -webkit-flex; afișare: flex; flex-wrap: wrap; ) .nav-itm ( fundal: #222; lățime: 130px; înălțime: 50px; dimensiunea fontului: 1.5rem;

Deoarece antetul are flex-wrap: wrap; și justificare-conținut: spațiu-între; Logo-ul și meniul sunt împrăștiate pe diferite părți ale antetului, iar dacă nu există suficient spațiu pentru meniu, acesta se va deplasa elegant sub logo.

Apoi vedem o postare mare sau un banner, este dificil să spunem despre ce este vorba în mod specific, dar nu acesta este ideea. Avem o imagine în dreapta și text cu un titlu în stânga. Eu personal aderă la ideea că orice element ar trebui să fie cât mai flexibil posibil, indiferent dacă aspectul este adaptiv sau static. Deci in aceasta postare avem o bara laterala in care este plasata o poza strict vorbind, nu putem spune exact ce latime avem nevoie, pentru ca azi avem o poza mare, maine avem una mica, si nu vrem sa refacem; elementul de la zero de fiecare dată. Aceasta înseamnă că avem nevoie de bara laterală să ocupe locul de care are nevoie, iar restul spațiului va merge la conținut. Să facem asta:

Caseta (dimensiunea fontului: 1.25rem; înălțimea liniei: 1.5; stilul fontului: cursiv; marginea: 0 0 40px -50px; afișarea: -webkit-flex; afișarea: flex; flex-wrap: wrap; justificarea conținutului: center; .box-base ( margin-left: 50px; flex: 1 0 430px; ) .box-side ( margin-left: 50px; flex: none; ) .box-img (max-lățime: 100%; înălțime: auto)

După cum puteți vedea pentru .box-base, unde avem titlul și textul, am specificat lățimea bazei cu flex-base: 430px;, și, de asemenea, a interzis utilizarea contracției blocului flex-contractie: 0;. Cu această manipulare am spus că conținutul nu poate deveni mai mic de 430px lățime. Și având în vedere faptul că pentru .box indic flex-wrap: wrap;în momentul în care bara laterală și conținutul nu se potrivesc în container.box, bara laterală va cădea automat sub conținut. Și toate acestea fără aplicare @media! Cred că asta este într-adevăr foarte tare.

Rămânem cu conținut în trei coloane. Există mai multe soluții la această problemă, vă voi arăta una dintre ele, există o altă opțiune în celelalte aspecte.
Să creăm un container, să-l numim .content și să-l configurem.
.conținut ( margin-bottom: 30px; display: -webkit-flex; display: flex; flex-wrap: wrap; )

Containerul are trei coloane, .bannere, .postări, .comentarii
.bannere ( flex: 1 1 200 px; ) . postări ( marjă: 0 0 30 px 30 px; flex: 1 1 200 px; ) . comentarii ( marjă: 0 0 30 px 30 px; flex: 1 1 200 px; )

Am dat coloanelor o lățime de bază de 200px, astfel încât coloanele să nu se îngusteze prea mult, dar ar fi mai bine dacă ar fi mutate una sub cealaltă la nevoie.

Conform aspectului, nu ne vom putea lipsi de @media cu conținutul, așa că haideți să mai reglam puțin comportamentul coloanelor pentru lățime<800px и <600px.
@media ecran și (max-width: 800px) ( .bannere ( margin-left: -30px; display: -webkit-flex; display: flex; flex-basis: 100%; ) .posts ( margin-left: 0; ) ) Ecran @media și (lățime maximă: 600px) ( .conținut ( afișare: bloc; ) .bannere ( marjă: 0; afișare: bloc; ) .comments ( marjă: 0; ) )

Aceasta este toată magia atunci când vine vorba de crearea unui aspect pe FlexBox. O altă sarcină care mi-a plăcut este cea de-a 5-a aspect, în special se referă la adaptarea conținutului.

Vedem cum la rezoluția desktop postările sunt construite într-o grilă de trei la rând. Când lățimea ferestrei de vizualizare devine mai mică de 800 px, grila se transformă într-o coloană cu postări, în care fotografia postării este aliniată în partea stângă și dreaptă a conținutului postării, alternativ. Și dacă lățimea este mai mică de 600px, fotografia postată este complet ascunsă.
.grid ( display: -webkit-flex; display: flex; flex-wrap: wrap; justify-content: space-between; ) .grid-itm ( margin-bottom: 30px; flex-basis: calc(33,33% - 30px) * 2/3); display: -webkit-flex: flex-wrap: wrap ) .grid-img ( margine: 0 auto 20px; flex: 0 1 80%; ) 100%; grid-img ( flex: 0 0 auto; ) .grid-itm:nth-child(even) .grid-img ( margin: 0 0 0 30px; order: 2; ) .grid-itm:nth-child (impar) .grid-img ( margine: 0 30px 0 0; ) .grid-cont (flex: 1 1 auto; ) .grid-title ( text-align: left; ) ) @media ecran și (max-width: 600px) ( .grid-img (afișare: niciunul; ) )

De fapt, aceasta este doar o mică parte din ceea ce poate fi implementat cu FlexBox. Specificația vă permite să construiți machete de pagină foarte complexe folosind cod simplu.

Ce altceva de citit