Mestre CSS Flexbox og Grid for avanserte og fleksible sideoppsett.
Avansert CSS – Flexbox og Grid
I kapittel 4.3 vart flexbox og grid kort introduserte. No skal vi gå i djupna på desse to kraftige layout-modulane i CSS. Flexbox og grid har revolusjonert måten vi lagar sideoppsett på – før desse verktøya fanst måtte utviklarar bruke kreative triks med float, tabellar og absolutt posisjonering for å oppnå sjølv enkle layout.
Flexbox er ein eindimensjonal layout som jobbar langs éin akse – anten horisontalt eller vertikalt. Han er perfekt for å fordele plass mellom element i ei rad eller kolonne, sentrere innhald, og lage navigasjonsmenyar og kortlayout.
CSS Grid er ein todimensjonal layout som jobbar med både rader og kolonnar samtidig. Han er ideell for heilskaplege sideoppsett, biletgalleri, dashbord og situasjonar der du treng presis kontroll over plassering i eit rutenett.
Å vite når du skal bruke flexbox og når du skal bruke grid er ein viktig dugleik. Tommelregelen er: bruk flexbox for komponentar og eindimensjonal fordeling, bruk grid for sideoppsett og todimensjonale strukturar. I praksis blir begge ofte brukte saman i same prosjekt.
display: flex på foreldreelementet, som då blir ein flex-container. Alle direkte barn av containaren blir flex-element. Flexbox har to aksar: hovudaksen (som standard horisontal) og kryssaksen (som standard vertikal). Eigenskapar på containaren styrer fordelinga langs desse aksane, medan eigenskapar på barna styrer korleis kvart enkelt element oppfører seg.Når du set display: flex på eit element, får du tilgang til fleire eigenskapar som styrer korleis barna blir arrangerte:
flex-direction – Bestemmer retninga på hovudaksen:
.container {
display: flex;
}
/* Standard: Horisontalt fra venstre til høyre */
.container { flex-direction: row; }
/* Horisontalt fra høyre til venstre */
.container { flex-direction: row-reverse; }
/* Vertikalt fra toppen og ned */
.container { flex-direction: column; }
/* Vertikalt fra bunnen og opp */
.container { flex-direction: column-reverse; }flex-wrap – Bestemmer om elementa blir brotne til ny linje:
/* Ikke bryt linjer (standard, elementene krympes) */
.container { flex-wrap: nowrap; }
/* Bryt til ny linje når plassen er full */
.container { flex-wrap: wrap; }gap – Avstand mellom flex-element:
.container {
display: flex;
gap: 1rem; /* Lik avstand i alle retninger */
gap: 1rem 2rem; /* rad-avstand kolonne-avstand */
}Dei to viktigaste justeringseigenskapane i flexbox er justify-content (fordeling langs hovudaksen) og align-items (justering langs kryssaksen).
justify-content – Fordeler plass langs hovudaksen:
.container {
display: flex;
justify-content: flex-start; /* Elementer til venstre (standard) */
justify-content: flex-end; /* Elementer til høyre */
justify-content: center; /* Elementer sentrert */
justify-content: space-between; /* Lik avstand mellom, ingen i kantene */
justify-content: space-around; /* Lik avstand rundt hvert element */
justify-content: space-evenly; /* Helt lik avstand overalt */
}align-items – Justerer element langs kryssaksen:
.container {
display: flex;
height: 300px;
align-items: stretch; /* Strekk til full høyde (standard) */
align-items: flex-start; /* Juster til toppen */
align-items: flex-end; /* Juster til bunnen */
align-items: center; /* Sentrer vertikalt */
align-items: baseline; /* Juster etter tekstens grunnlinje */
}Sentrering med flexbox – Den enklaste måten å sentrere eit element både horisontalt og vertikalt:
.sentrert-container {
display: flex;
justify-content: center; /* Horisontal sentrering */
align-items: center; /* Vertikal sentrering */
height: 100vh;
}Denne teknikken er ekstremt nyttig og blir brukt overalt i moderne webdesign. Før flexbox var vertikal sentrering ei av dei mest frustrerande oppgåvene i CSS.
Her er eit døme på ei navigasjonslinje med logo til venstre og menyelement til høgre:
<header class="navbar">
<div class="logo">SkoleSaga</div>
<nav class="nav-lenker">
<a href="/">Hjem</a>
<a href="/kurs">Kurs</a>
<a href="/oppgaver">Oppgaver</a>
<a href="/om">Om oss</a>
</nav>
</header>.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background-color: #1a1a2e;
color: white;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
color: #667eea;
}
.nav-lenker {
display: flex;
gap: 1.5rem;
}
.nav-lenker a {
color: white;
text-decoration: none;
padding: 0.5rem 0;
border-bottom: 2px solid transparent;
transition: border-color 0.3s;
}
.nav-lenker a:hover {
border-bottom-color: #667eea;
}justify-content: space-between på .navbar plasserer logoen heilt til venstre og navigasjonen heilt til høgre med all ledig plass imellom. Sjølve navigasjonen er òg ein flex-container med gap: 1.5rem mellom lenkene. Hover-effekten med border-bottom gir ei elegant understreking utan å flytte andre element.
Medan flex-container-eigenskapane styrer heilskapen, kan du òg kontrollere individuelle flex-element:
flex-grow – Kor mykje eit element skal vekse relativt til andre:
.element-a { flex-grow: 1; } /* Får 1 andel av ledig plass */
.element-b { flex-grow: 2; } /* Får 2 andeler av ledig plass */
.element-c { flex-grow: 0; } /* Vokser ikke (standard) */flex-shrink – Kor mykje eit element krympar når plassen er trong:
.element { flex-shrink: 1; } /* Krymper proporsjonalt (standard) */
.element { flex-shrink: 0; } /* Krymper aldri */flex-basis – Startstorleiken til elementet før vekst/krymping:
.element { flex-basis: 200px; } /* Starter med 200px bredde */
.element { flex-basis: 30%; } /* Starter med 30% av containeren */
.element { flex-basis: auto; } /* Bruker innholdets størrelse (standard) */flex-shorthand – Kombinerer grow, shrink og basis:
.element { flex: 1; } /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
.element { flex: 0 0 250px; } /* Ikke voks, ikke krymp, 250px bred */
.element { flex: 2 1 auto; } /* Voks dobbelt, krymp normalt, auto basis */Eit vanleg mønster er sidebar-layout med flexbox:
.side-layout {
display: flex;
gap: 2rem;
}
.sidebar {
flex: 0 0 250px; /* Fast bredde, krymper ikke */
}
.hovedinnhold {
flex: 1; /* Fyller resten av plassen */
}display: grid på foreldreelementet, og strukturen blir definert med grid-template-columns og grid-template-rows. Element kan plasserast automatisk i rekkjefølgje eller manuelt med grid-column og grid-row. Grid er det mest kraftfulle layout-verktøyet i CSS og er ideelt for heilskaplege sideoppsett.Du opprettar eit grid ved å setje display: grid og definere kolonnane:
/* Tre kolonner med fast bredde */
.rutenett {
display: grid;
grid-template-columns: 200px 400px 200px;
gap: 1rem;
}
/* Tre like brede kolonner med fr-enheter */
.rutenett {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 1rem;
}
/* Kortform med repeat() */
.rutenett {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}fr-eininga (fraction) representerer ein del av den tilgjengelege plassen. I 1fr 2fr 1fr får den midtarste kolonnen dobbelt så mykje plass som dei andre:
.layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 1.5rem;
}Rader blir definerte med grid-template-rows:
.layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto; /* header, innhold, footer */
gap: 1rem;
min-height: 100vh;
}Her er den første og siste rada (header og footer) auto-dimensjonerte etter innhaldet, medan den midtarste rada (innhaldet) tek all attverande plass med 1fr.
Du kan plassere element manuelt i gridet med grid-column og grid-row:
.rutenett {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto auto;
gap: 1rem;
}
/* Elementet spenner over kolonne 1 til 3 (to kolonner) */
.bred-element {
grid-column: 1 / 3;
}
/* Elementet spenner over alle 4 kolonner */
.full-bredde {
grid-column: 1 / -1;
}
/* Elementet spenner over 2 rader */
.høy-element {
grid-row: 1 / 3;
}Du kan òg bruke span for å gi opp talet på spor:
.bred-element {
grid-column: span 2; /* Spenner over 2 kolonner */
}
.høy-element {
grid-row: span 3; /* Spenner over 3 rader */
}grid-template-areas gir ein visuell måte å definere layout på:
.side-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar innhold"
"footer footer";
gap: 1rem;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.innhold { grid-area: innhold; }
.footer { grid-area: footer; }Med grid-template-areas kan du «teikne» layouten som ein visuell representasjon i CSS-koden. Kvart ord representerer eit område, og elementa blir kopla til områda med grid-area.
Her er ein komplett sidelayout med header, sidebar, hovudinnhald og footer:
<div class="side-layout">
<header class="topp">
<h1>Min nettside</h1>
<nav>
<a href="/">Hjem</a>
<a href="/artikler">Artikler</a>
<a href="/kontakt">Kontakt</a>
</nav>
</header>
<aside class="venstremeny">
<h3>Kategorier</h3>
<ul>
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
</ul>
</aside>
<main class="hoveddel">
<h2>Siste artikler</h2>
<article>
<h3>Lær CSS Grid</h3>
<p>CSS Grid gjør det enkelt å lage avanserte sideoppsett...</p>
</article>
</main>
<footer class="bunn">
<p>© 2025 Min nettside</p>
</footer>
</div>.side-layout {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"topp topp"
"meny hoveddel"
"bunn bunn";
gap: 0;
min-height: 100vh;
}
.topp {
grid-area: topp;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2c3e50;
color: white;
padding: 1rem 2rem;
}
.topp nav {
display: flex;
gap: 1rem;
}
.topp nav a {
color: white;
text-decoration: none;
}
.venstremeny {
grid-area: meny;
background-color: #ecf0f1;
padding: 1.5rem;
}
.venstremeny ul {
list-style: none;
padding: 0;
}
.venstremeny li {
margin-bottom: 0.5rem;
}
.venstremeny a {
color: #2c3e50;
text-decoration: none;
}
.hoveddel {
grid-area: hoveddel;
padding: 2rem;
}
.bunn {
grid-area: bunn;
background-color: #2c3e50;
color: white;
text-align: center;
padding: 1rem;
}Denne layouten brukar grid-template-areas for ein oversiktleg struktur. Headeren og footeren spenner over heile breidda, medan sidemenyen og hovudinnhaldet deler midtseksjonen. Sjølve headeren brukar flexbox internt for å plassere logoen og navigasjonen – eit godt døme på at grid og flexbox ofte blir brukte saman.
Ein av dei mest nyttige grid-teknikkane er auto-fit og auto-fill med repeat() og minmax(). Dei lagar rutenett som automatisk tilpassar talet på kolonnar til den tilgjengelege plassen, heilt utan media queries:
/* auto-fit: Tilpasser antall kolonner, strekker eksisterende elementer */
.kort-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
/* auto-fill: Tilpasser antall kolonner, beholder tomme spor */
.kort-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}Skilnaden mellom auto-fit og auto-fill:
- auto-fit: Kollapsar tomme spor og lèt eksisterande element strekkje seg. Viss du har tre element i ein brei container, kan dei bli større enn minimum.
- auto-fill: Held på tomme spor sjølv om det ikkje er element som fyller dei. Elementa held på den minimale breidda si.
I dei fleste tilfella er auto-fit det du vil bruke, fordi det gir eit ryddigare resultat utan usynlege tomme kolonnar.
minmax(280px, 1fr) tyder at kvar kolonne er minst 280px brei, men kan vekse for å dele den tilgjengelege plassen. Nettlesaren reknar automatisk ut kor mange kolonnar som får plass:
- Viewport 600px: 2 kolonnar (ca. 280px kvar)
- Viewport 900px: 3 kolonnar (ca. 280px kvar)
- Viewport 1200px: 4 kolonnar (ca. 280px kvar)
Dette er ein ekstremt kraftig teknikk som gir responsivt design utan ein einaste media query.
Både flexbox og grid er layout-verktøy, men dei har ulike styrkar:
| Eigenskap | Flexbox | Grid |
|---|---|---|
| Dimensjonar | Éin (rad ELLER kolonne) | To (rader OG kolonnar) |
| Innhaldsbasert | Ja, elementa avgjer storleik | Nei, rutenettet avgjer storleik |
| Best for | Komponentar, menyar, fordeling | Sideoppsett, rutenett, dashbord |
| Justering | Svært fleksibelt langs éin akse | Presis kontroll i begge aksar |
Bruk flexbox når:
- Du treng å fordele element i ei rad eller kolonne
- Elementa har ulik storleik og skal fordele plass seg imellom
- Du lagar navigasjonsmenyar, verktøylinjer eller kortrekkjer
- Du vil sentrere eit element horisontalt og/eller vertikalt
Bruk grid når:
- Du treng layout med både rader og kolonnar
- Du vil plassere element presist i eit rutenett
- Du lagar heilskaplege sideoppsett med header, sidebar og footer
- Du lagar biletgalleri eller dashbord med ulike kortstorleikar
Bruk begge saman:
I praksis brukar du ofte grid for den overordna sidelayouten og flexbox for komponentar inni grid-cellene. Til dømes kan headeren vere ein grid-area, medan innhaldet inni headeren blir arrangert med flexbox.
Her er eit dashbord som kombinerer grid for overordna layout og flexbox for innhaldet i korta:
<div class="dashboard">
<div class="statistikk-kort bred">
<h3>Besøkende i dag</h3>
<span class="tall">1 247</span>
<span class="endring positiv">+12%</span>
</div>
<div class="statistikk-kort">
<h3>Sidevisninger</h3>
<span class="tall">3 891</span>
<span class="endring positiv">+8%</span>
</div>
<div class="statistikk-kort">
<h3>Avvisningsrate</h3>
<span class="tall">34%</span>
<span class="endring negativ">-2%</span>
</div>
<div class="statistikk-kort">
<h3>Nye brukere</h3>
<span class="tall">189</span>
<span class="endring positiv">+23%</span>
</div>
<div class="statistikk-kort">
<h3>Gjennomsnittlig tid</h3>
<span class="tall">4:32</span>
<span class="endring negativ">-5%</span>
</div>
</div>/* Overordnet layout med Grid */
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.5rem;
padding: 2rem;
background-color: #f0f2f5;
}
/* Element som spenner over to kolonner */
.statistikk-kort.bred {
grid-column: span 2;
}
/* Hvert kort bruker Flexbox internt */
.statistikk-kort {
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: white;
padding: 1.5rem;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
min-height: 120px;
}
.statistikk-kort h3 {
font-size: 0.85rem;
color: #666;
margin: 0;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.tall {
font-size: 2rem;
font-weight: bold;
color: #1a1a2e;
}
.endring {
font-size: 0.9rem;
font-weight: 600;
}
.endring.positiv {
color: #27ae60;
}
.endring.negativ {
color: #e74c3c;
}Dashbordet brukar grid med auto-fit for å automatisk tilpasse korta til skjermbreidda. Det breie kortet spenner over to kolonnar med grid-column: span 2. Inne i kvart kort blir flexbox brukt med flex-direction: column og justify-content: space-between for å fordele overskrift, tal og endringsprosent jamt vertikalt.
Flexbox og Grid er dei to viktigaste layout-verktøya i moderne CSS:
- Flexbox er eindimensjonal og perfekt for å fordele element i ei rad eller kolonne. Dei viktigaste eigenskapane er flex-direction, justify-content, align-items, gap og flex-shorthand.
- CSS Grid er todimensjonal og ideelt for sideoppsett med rader og kolonnar. Dei viktigaste eigenskapane er grid-template-columns, grid-template-rows, grid-template-areas, gap og fr-eininga.
- auto-fit med minmax() gir responsivt rutenett utan media queries.
- grid-template-areas gir ein visuell måte å definere layout i CSS.
- Bruk begge saman: Grid for overordna sidelayout, flexbox for komponentar.
- gap er enklare enn margin for avstand mellom element i både flexbox og grid.
Med god forståing av flexbox og grid kan du lage nesten kva som helst layout utan å ty til gamle teknikkar som float og absolutt posisjonering.
Kva er den viktigaste skilnaden mellom CSS Flexbox og CSS Grid?
Kva gjer følgjande CSS?
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}Kva tyder grid-template-columns: 1fr 2fr 1fr?
Skriv HTML og CSS for eit biletgalleri med CSS Grid. Krava:
- Bruk auto-fit slik at talet på kolonnar tilpassar seg automatisk
- Minimum breidd per bilete: 200px
- Avstand mellom bileta: 1rem
- Bileta skal fylle cellene utan å bli forvrengde (bruk object-fit)
- Kvart bilete skal ha avrunda hjørne
Lag HTML og CSS for ein footer med tre seksjonar side om side:
- Seksjon 1: «Om oss» med ein kort tekst
- Seksjon 2: «Lenker» med ei liste med fire navigasjonslenker
- Seksjon 3: «Kontakt» med e-post og telefonnummer
Bruk flexbox for å plassere seksjonane side om side med lik breidd. Footeren skal ha mørk bakgrunn og kvit tekst.
Lag HTML og CSS for ein komplett sidelayout med CSS Grid og grid-template-areas. Layouten skal ha:
- Header som spenner over heile breidda
- Ein sidebar (250px brei) til venstre
- Hovudinnhald til høgre som fyller resten av plassen
- Footer som spenner over heile breidda
- Sida skal fylle minst heile viewport-høgda
- Bruk grid-template-areas for å definere oppsettet
Kva er skilnaden mellom auto-fit og auto-fill i CSS Grid?
/* Alternativ A */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* Alternativ B */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));Du har ein flex-container med tre element. Kva skjer med breidda til elementa?
.container {
display: flex;
}
.a { flex: 1; }
.b { flex: 2; }
.c { flex: 1; }Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.