CSS Grid och Flexbox: Komplett guide till modern layout
Flexbox för endimensionella flöden. Grid för tvådimensionella strukturer. Container queries för komponent-responsivitet. Allt med praktiska kodexempel.
Bild: Ferenc Almasi / Unsplash
CSS-layout har gått från en mardröm av floats och clearfixes till två verktyg som faktiskt gör vad du förväntar dig: Flexbox och Grid. Tillsammans löser de i princip alla layout-problem du stöter på i modern webbutveckling.
Den här guiden går igenom båda systemen med praktiska exempel. Inte teori om specifikationen, utan det du behöver för att bygga responsiva layouts som fungerar i alla moderna webbläsare.
Flexbox: Endimensionell layout
Flexbox hanterar layout i en riktning — antingen horisontellt (rad) eller vertikalt (kolumn). Det är rätt verktyg för navigeringsmenyer, kortlistor, centreringar och alla situationer där element ska fördelas längs en axel.
/* Grundläggande flex-container */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
gap: 1rem;
}
/* justify-content styr HUR element fördelas längs huvudaxeln */
/* align-items styr positionering TVÄRS mot huvudaxeln */
/* Centrera vad som helst — vertikalt och horisontellt */
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Flex-items: Kontrollera hur element växer och krymper */
.sidebar {
flex: 0 0 280px; /* Krymper inte, växer inte, alltid 280px */
}
.main-content {
flex: 1; /* Tar resterande utrymme */
}
/* flex: 1 är shorthand för:
flex-grow: 1; — Får växa
flex-shrink: 1; — Får krympa
flex-basis: 0%; — Startar från 0 */Flexbox: Responsiv navigation
Ett av de vanligaste flexbox-mönstren: en navbar med logga till vänster och menylänkar till höger, som stackar på mobil.
/* Desktop: logga vänster, nav höger */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
/* Mobil: stacka vertikalt */
@media (max-width: 768px) {
.header {
flex-direction: column;
gap: 1rem;
}
.nav-links {
flex-direction: column;
align-items: center;
gap: 0.5rem;
}
}Flexbox: Kortlayout med lika höjd
Flex-items i samma container får automatiskt lika höjd. Det löser det klassiska problemet med kort som har olika mycket innehåll men ska se enhetliga ut.
/* Kort-container */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
/* Varje kort tar 1/3 av bredden (minus gap) */
.card {
flex: 1 1 calc(33.333% - 1rem);
min-width: 280px;
display: flex;
flex-direction: column;
}
/* Knappen längst ner, oavsett innehållsmängd */
.card-body {
flex: 1; /* Tar allt tillgängligt utrymme */
}
.card-footer {
margin-top: auto; /* Pushar ner till botten */
}CSS Grid: Tvådimensionell layout
Grid hanterar rader och kolumner samtidigt. Det är rätt verktyg för sidlayouter, bildgallerier, dashboards och alla situationer där du behöver kontrollera placering i ett rutnät.
/* Grundläggande grid */
.page-layout {
display: grid;
grid-template-columns: 250px 1fr 250px;
grid-template-rows: auto 1fr auto;
gap: 1rem;
min-height: 100vh;
}
/* Namngivna grid-areas — läsbart och kraftfullt */
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
grid-template-columns: 250px 1fr 250px;
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* Responsivt: kollapsa till en kolumn på mobil */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"content"
"sidebar"
"aside"
"footer";
grid-template-columns: 1fr;
}
}Grid: Automatiskt responsiva gallerier
Den mest använda CSS Grid-tekniken: auto-fill med minmax(). Den skapar ett responsivt rutnät utan en enda media query.
/* Magisk responsiv grid — inga media queries */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
/* auto-fill: Fyll raden med så många kolumner som får plats */
/* minmax(280px, 1fr): Varje kolumn minst 280px, max lika delade */
/* Resultat:
- 1200px bred: 4 kolumner
- 900px bred: 3 kolumner
- 600px bred: 2 kolumner
- 400px bred: 1 kolumn
Helt automatiskt. */
/* auto-fill vs auto-fit:
auto-fill: Behåller tomma kolumner (element expanderar INTE)
auto-fit: Kollapsar tomma kolumner (element EXPANDERAR)
I de flesta fall vill du auto-fill */Grid: Placera element exakt
Till skillnad från Flexbox kan du med Grid placera element på exakta positioner i rutnätet. Det ger dig kontroll som tidigare krävde absolut positionering.
/* Dashboard-layout med varierande storlekar */
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 1rem;
}
/* Stort widget — tar 2 kolumner och 2 rader */
.widget-large {
grid-column: span 2;
grid-row: span 2;
}
/* Bred widget — hela bredden */
.widget-wide {
grid-column: 1 / -1; /* Från första till sista kolumnen */
}
/* Exakt placering */
.widget-topright {
grid-column: 4;
grid-row: 1;
}När Flexbox, när Grid?
Det behöver inte vara ett antingen-eller. De löser olika problem och fungerar utmärkt tillsammans. Tumregeln är enkel.
/* FLEXBOX: En dimension, innehållsstyrd layout
- Navigeringsmenyer
- Knapprader
- Centrering
- Element som ska fördelas jämnt
- När innehållet styr storleken */
/* GRID: Två dimensioner, layoutstyrd
- Sidlayouter (header/sidebar/content/footer)
- Bildgallerier
- Dashboards
- Formulär med labels och inputs
- När layouten styr innehållet */
/* KOMBINERAT: Grid för sidlayout, Flex inuti komponenterna */
.page {
display: grid;
grid-template-columns: 240px 1fr;
}
.toolbar {
display: flex;
gap: 0.5rem;
align-items: center;
}Moderna CSS-tekniker: Container Queries
Media queries reagerar på viewportens storlek. Container queries reagerar på komponentens storlek. Det är en grundläggande förändring i hur vi tänker på responsivitet.
/* Definiera container */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* Reagera på containerns bredd, inte viewportens */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
/* Samma komponent, olika layout beroende på
var den placeras — sidebar vs main content */Vanliga misstag och lösningar
Flexbox och Grid är intuitiva, men det finns fallgropar som dyker upp i nästan varje projekt.
/* MISSTAG 1: Texten svämmar över containern */
.flex-item {
min-width: 0; /* Fix: Tillåt element att krympa under content-size */
}
/* MISSTAG 2: Bilder respekterar inte grid-cellen */
.grid-item img {
width: 100%;
height: 100%;
object-fit: cover; /* Fyll utan att förvränga */
}
/* MISSTAG 3: Gap fungerar inte i äldre Safari */
/* gap i Flexbox stöds sedan Safari 14.1 (2021) */
/* Om du måste stödja äldre: */
.legacy-flex {
display: flex;
flex-wrap: wrap;
margin: -0.5rem; /* Negativt margin-hack */
}
.legacy-flex > * {
margin: 0.5rem;
}
/* MISSTAG 4: Grid-items med auto-höjd i strict containers */
/* Lösning: Sätt explicit min-height eller använd minmax() */
.grid {
grid-template-rows: minmax(100px, auto);
}Komplett sidlayout: Responsiv app
Ett fullständigt exempel som kombinerar Grid och Flexbox i en responsiv applikationslayout.
/* App-layout med Grid */
.app {
display: grid;
grid-template-areas:
"nav header"
"nav main"
"nav main";
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr;
height: 100vh;
}
/* Header med Flexbox */
.app-header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
border-bottom: 1px solid #e2e8f0;
}
/* Navigation med Flexbox (vertikal) */
.app-nav {
grid-area: nav;
display: flex;
flex-direction: column;
padding: 1rem;
gap: 0.25rem;
background: #1e293b;
}
/* Main content med Grid (dashboard-kort) */
.app-main {
grid-area: main;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
padding: 2rem;
overflow-y: auto;
}
/* Mobil: Göm sidebar, visa som overlay */
@media (max-width: 768px) {
.app {
grid-template-areas:
"header"
"main";
grid-template-columns: 1fr;
}
.app-nav {
position: fixed;
inset: 0;
z-index: 50;
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.app-nav.open {
transform: translateX(0);
}
}Summering
Flexbox och Grid har ersatt alla de layout-hack vi använde i tio år. Flexbox för endimensionella flöden (menyer, knappar, centrering). Grid för tvådimensionella strukturer (sidlayouter, gallerier, dashboards). Kombinera dem: Grid för den övergripande strukturen, Flexbox inuti komponenterna.
Container queries tar det vidare genom att göra layout beroende av komponentens storlek istället för viewportens. Det ändrar inte grundprinciperna, men det gör komponenterna mer portabla. Börja med auto-fill + minmax() — den enskilt mest användbara CSS-tekniken du kan lära dig i dag.
Vill du se hur Grid och Flexbox passar in i den bredare webbutvecklingsbilden? Läs vår kompletta webbutvecklingsguide. Bygger du med React? Se hur React Server Components påverkar hur du strukturerar dina layouts.