Flexbox lanserades i alla större webbläsare runt 2015 och löste omedelbart problemet som utvecklare hade hackat runt i ett decennium: vertikal centrering. Men de flesta lärde sig det bakvänt — de memorerade justify-content: center från ett fuskblad utan att förstå varför det fungerar. När layouten inte beter sig som förväntat gör den kunskapsluckan en femminutersuppgift till en timme av försök och misstag. Den här guiden bygger den mentala modellen först, och täcker sedan varje egenskap som faktiskt spelar roll i verkliga projekt.
Den mentala modellen: en axel i taget
Kärnkonceptet i Flexbox är att det lägger ut element längs en enda axel. Det finns en huvudaxel — riktningen elementen flödar i — och en korsaxel, som löper vinkelrätt. Den kritiska insikten som nästan varje nybörjare missar: flex-direction bestämmer vilken axel som är vilken. Allt annat följer av det.
/* Default: main axis runs LEFT → RIGHT, cross axis runs TOP → BOTTOM */
.container {
display: flex;
flex-direction: row; /* default */
}
/* Rotated: main axis now runs TOP → BOTTOM, cross axis runs LEFT → RIGHT */
.container {
display: flex;
flex-direction: column;
}
/*
justify-content → controls alignment on the MAIN axis
align-items → controls alignment on the CROSS axis
This is why centering something in both axes looks like this:
*/
.center-both {
display: flex;
justify-content: center; /* horizontally centred (main axis = row) */
align-items: center; /* vertically centred (cross axis) */
}flex-direction: column kontrollerar justify-content inte längre horisontell justering — det kontrollerar vertikal justering, eftersom huvudaxeln har roterat. align-items kontrollerar nu det horisontella. Ha den rotationen i åtanke när något inte justeras där du förväntar dig.Behållaregenskaper
Dessa egenskaper placeras på flex-behållaren — föräldraelementet med display: flex. De kontrollerar hur alla underordnade element distribueras och justeras.
/* display: flex makes the element a block-level flex container.
display: inline-flex makes it inline (sits in text flow). */
.nav {
display: flex;
}
/* flex-direction — which way does the main axis run? */
.nav {
flex-direction: row; /* left to right (default) */
flex-direction: row-reverse; /* right to left */
flex-direction: column; /* top to bottom */
flex-direction: column-reverse; /* bottom to top */
}
/* flex-wrap — what happens when items overflow the container? */
.card-grid {
flex-wrap: nowrap; /* all items forced onto one line (default) */
flex-wrap: wrap; /* items wrap onto additional lines */
flex-wrap: wrap-reverse; /* items wrap in reverse order */
}
/* gap — space between items. Modern approach; avoids margin hacks. */
.card-grid {
gap: 1.5rem; /* same in both directions */
gap: 1rem 2rem; /* row-gap column-gap */
}Egenskapen gap förtjänar ett särskilt omnämnande. Innan den existerade var det vanliga mönstret att lägga till marginaler på flex-objekt och sedan avbryta de yttre kanterna med negativa marginaler. gap ersätter allt det rent — använd det överallt istället.
/* justify-content — alignment on the MAIN axis */
.nav {
justify-content: flex-start; /* packed to start (default) */
justify-content: flex-end; /* packed to end */
justify-content: center; /* packed to centre */
justify-content: space-between; /* first/last at edges, equal gaps between */
justify-content: space-around; /* equal space around each item */
justify-content: space-evenly; /* equal space between every gap */
}
/* align-items — alignment on the CROSS axis (single line) */
.nav {
align-items: stretch; /* items fill cross-axis height (default) */
align-items: flex-start;/* items align to start of cross axis */
align-items: flex-end; /* items align to end of cross axis */
align-items: center; /* items centred on cross axis */
align-items: baseline; /* items aligned by their text baseline */
}
/* align-content — cross-axis alignment when there are MULTIPLE lines
(only takes effect with flex-wrap: wrap and enough items to wrap) */
.card-grid {
flex-wrap: wrap;
align-content: flex-start; /* rows packed to top */
align-content: center; /* rows centred vertically */
align-content: space-between; /* rows spread out with space between */
}Här är ett riktigt navigeringsfält som kombinerar dessa. Logotypen sitter till vänster och navigeringslänkarna skjuts till höger med margin-left: auto — ett klassiskt Flexbox-trick. Metoden med justify-content: space-between fungerar också, men auto-marginalteknik är mer flexibel när du har mer än två grupper.
/* Nav: logo left, links right */
.site-nav {
display: flex;
align-items: center;
gap: 1rem;
padding: 0 2rem;
height: 64px;
background: #1a1a2e;
}
.site-nav .logo {
font-size: 1.25rem;
font-weight: 700;
color: #fff;
text-decoration: none;
}
.site-nav .nav-links {
display: flex;
align-items: center;
gap: 1.5rem;
margin-left: auto; /* pushes everything after it to the right */
list-style: none;
margin-top: 0;
margin-bottom: 0;
padding: 0;
}
.site-nav .nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.9rem;
}
.site-nav .nav-links a:hover {
color: #fff;
}Objektegenskaper
Dessa egenskaper placeras på flex-objekt — direkta barn till flex-behållaren. De kontrollerar hur enskilda objekt växer, krymper och storleksanpassar sig.
flex-grow— hur mycket av det tillgängliga utrymmet det här objektet tar. Standard0(väx inte). Sätt till1på ett objekt så tar det allt återstående utrymme.flex-shrink— hur mycket det här objektet krymper relativt till andra när det inte finns tillräckligt med utrymme. Standard1. Sätt till0för att förhindra att ett objekt krymper.flex-basis— den initiala storleken på objektet innan någon tillväxt eller krympning. Kan vara en längd (250px,30%) ellerauto(använd objektets innehållsstorlek).align-self— åsidosätteralign-itemsför ett specifikt objekt. Accepterar samma värden:auto,flex-start,flex-end,center,baseline,stretch.order— ändrar visuell ordning utan att röra HTML. Standard0. Lägre värden visas först. Använd sparsamt — det bryter tabb-ordningen och orsakar tillgänglighetsproblem för tangentbords- och skärmläsaranvändare.
/* Classic sidebar + main content layout */
.app-layout {
display: flex;
min-height: 100vh;
}
.sidebar {
flex: 0 0 280px; /* don't grow, don't shrink, always 280px wide */
background: #f5f5f5;
padding: 2rem 1.5rem;
}
.main-content {
flex: 1; /* grow to fill all remaining space */
padding: 2rem;
min-width: 0; /* critical: prevents content overflow in flex children */
}
/* Responsive: stack vertically on mobile */
@media (max-width: 768px) {
.app-layout {
flex-direction: column;
}
.sidebar {
flex: none; /* reset — don't use flex-basis on column layout */
}
}min-width: 0: som standard kan flex-objekt inte krympa under sin minimala innehållsstorlek. Om du har ett långt ord eller en bred tabell inuti ett flex-objekt, kommer det att svämma över istället för att radbryta. Att lägga till min-width: 0 till flex-objektet löser detta. Det uppstår ständigt med huvudinnehållsområdet i sidofältslayouter.flex-kortformen förklarad
Kortformen flex packar flex-grow, flex-shrink och flex-basis i en deklaration. W3C-specifikationen definierar en handfull nyckelordsvärden som täcker de vanliga fallen, och de förväxlas ofta med varandra.
/* flex: 1
Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: 0%
Meaning: grow and shrink freely; start from zero (ignore content size).
All items with flex: 1 share space equally, regardless of content.
Most common choice for "fill available space". */
.tab { flex: 1; }
/* flex: auto
Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: auto
Meaning: grow and shrink freely; start from the item's content size.
Items with more content get more space — proportional, not equal. */
.column { flex: auto; }
/* flex: none
Expands to: flex-grow: 0; flex-shrink: 0; flex-basis: auto
Meaning: completely rigid — don't grow, don't shrink, stay at content size.
Use for items that should never flex (icons, avatars, fixed labels). */
.avatar { flex: none; }
/* flex: 0 0 200px
Explicit: don't grow, don't shrink, always exactly 200px.
Same as writing out all three values. More readable for fixed-size items. */
.sidebar { flex: 0 0 200px; }
/* Practical difference: flex: 1 vs flex: auto in a tab bar
With flex: 1 → all tabs are equal width regardless of label length
With flex: auto → "Settings" tab is wider than "Home" tab */
.tabs { display: flex; }
.tab-equal { flex: 1; } /* equal width tabs */
.tab-auto { flex: auto; } /* content-sized tabs */Vanliga verkliga layouter
Här är fyra mönster du regelbundet kommer att använda — byggda med ingenting annat än Flexbox.
/* 1. Sticky footer
The footer always sits at the bottom, even on short pages.
body (or .app-shell) becomes a column flex container. */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
main {
flex: 1; /* expands to push footer down */
}
footer {
/* stays at the bottom */
}/* 2. Centred modal / hero content
Both axes centred — the Flexbox vertical-centring party trick. */
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.hero-content {
max-width: 640px;
text-align: center;
color: #fff;
}/* 3. Nav bar: logo left, links right */
.site-nav {
display: flex;
align-items: center;
padding: 0 2rem;
height: 64px;
}
.site-nav .nav-links {
margin-left: auto; /* auto margin consumes all free space to its left */
display: flex;
gap: 1.5rem;
list-style: none;
padding: 0;
margin-top: 0;
margin-bottom: 0;
}/* 4. Card row that wraps on mobile */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 280px; /* grow and shrink, but never below 280px wide */
background: #fff;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
/* On wide screens: 3-4 cards per row.
On narrow screens: cards wrap into their own rows automatically.
No media query needed for the wrap itself — flex-wrap handles it. */Flexbox vs Grid — när ska man använda vad
Den här frågan dyker upp hela tiden, och svaret är enklare än de flesta artiklar gör det: Flexbox är för endimensionella layouter. CSS Grid är för tvådimensionella layouter. Om du lägger ut objekt i en enda rad eller en enda kolumn — ett navigeringsfält, en knappgrupp, en kortrad — är Flexbox rätt verktyg. Om du behöver kontrollera både rader och kolumner samtidigt — en helsideslayout, ett fotomosaik, ett formulärnät — ta till Grid istället.
I praktiken använder du båda i samma projekt. Grid hanterar sidnivåstrukturen (sidhuvud, sidofält, huvud, sidfot). Flexbox hanterar komponenterna inom dessa regioner (navigeringsfältet, kortinnehållet, knappklustret inuti en modal). De kompletterar varandra snarare än konkurrerar.
flex-wrap: wrap kan göra detta, men objekt i samma visuella rad har ingen relation till varandra — deras höjder är oberoende. Grids implicita radstorlek hanterar detta automatiskt. Om du behöver att korten i en radbruten rad alla är av samma höjd OCH att deras interna element justeras över korten, är Grid renare.Sammanfattning
Flexbox mentala modell är: välj en riktning, förstå vilka egenskaper som kontrollerar vilken axel, välj sedan om objekt ska växa, krympa eller förbli fasta. När det klickar blir fuskbladet en referens — inte en krycka. MDN Flexbox-guiden är den bästa referensen för kantfall, och CSS-Tricks komplett guide är fortfarande det mest användbara visuella fuskbladet. För produktionsanvändning är webbläsarstödet i princip universellt — inga prefix behövs. W3C-specifikationen är värd att bläddra igenom om du någonsin stöter på ett genuint förvirrande kantfall — algoritmen är exakt dokumenterad och besvarar de flesta "varför beter sig det här på det här sättet"-frågor.