Introduktion till CSS Grid

CSS Grid Layout är det mest kraftfulla layout-systemet i CSS. Till skillnad från Flexbox som är endimensionell, är Grid tvådimensionell - du kan kontrollera både rader och kolumner samtidigt.

Varför CSS Grid?

Före Grid

Traditionella layouts krävde komplexa float-tricks eller flexbox-workarounds:

/* Komplext grid med float */
.container::after {
  content: "";
  display: table;
  clear: both;
}

.item {
  float: left;
  width: calc(33.333% - 20px);
  margin: 10px;
}

Med Grid

/* Enkelt och kraftfullt */
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

Grundläggande Koncept

Grid Container & Grid Items

<div class="grid-container"> <!-- Grid Container -->
  <div class="grid-item">1</div> <!-- Grid Item -->
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
</div>
.grid-container {
  display: grid; /* Aktiverar CSS Grid */
}

Grid Lines & Tracks

Grid Lines:
│ 1 │ 2 │ 3 │ 4 │
┌───┬───┬───┐
│ A │ B │ C │ ← Row Track
├───┼───┼───┤
│ D │ E │ F │
└───┴───┴───┘
  ↑   ↑   ↑
Column Tracks

Container Properties

display: grid

Aktiverar grid:

.container {
  display: grid;        /* Block-level grid */
  display: inline-grid; /* Inline-level grid */
}

grid-template-columns

Definierar kolumner:

/* Fast bredd */
.grid {
  grid-template-columns: 200px 200px 200px;
}

/* Flex units (fr) */
.grid {
  grid-template-columns: 1fr 1fr 1fr;
}

/* Blandning */
.grid {
  grid-template-columns: 200px 1fr 2fr;
  /* 200px, 1 del, 2 delar av remaining space */
}

/* repeat() */
.grid {
  grid-template-columns: repeat(3, 1fr);
  /* Samma som: 1fr 1fr 1fr */
}

/* auto-fill & auto-fit */
.grid {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  /* Responsive grid utan media queries! */
}

grid-template-rows

Definierar rader:

.grid {
  grid-template-rows: 100px 200px auto;
}

/* Implicit rows (auto-skapade) */
.grid {
  grid-auto-rows: 150px; /* Höjd på implicit rows */
}

gap (grid-gap)

Mellanrum mellan celler:

.grid {
  gap: 20px;              /* Alla gaps */
  gap: 20px 40px;         /* Row Column */
  row-gap: 20px;          /* Bara mellan rader */
  column-gap: 40px;       /* Bara mellan kolumner */
}

grid-template-areas

Namngivna områden:

.grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 20px;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }

Visuellt:

┌─────────────────────────┐
│        header           │
├────────┬─────────┬──────┤
│sidebar │ content │ aside│
├────────┴─────────┴──────┤
│        footer           │
└─────────────────────────┘

Item Properties

grid-column & grid-row

Placera items:

/* Från line 1 till line 3 (spans 2 columns) */
.item {
  grid-column: 1 / 3;
}

/* Span syntax */
.item {
  grid-column: span 2; /* Span 2 columns */
  grid-row: span 3;    /* Span 3 rows */
}

/* Shorthand */
.item {
  grid-column: 1 / 3;  /* Start / End */
  grid-row: 2 / 4;
}

/* Negative indexing (från slutet) */
.item {
  grid-column: 1 / -1; /* Hela bredden */
}

Praktiskt exempel:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.featured {
  grid-column: 1 / 3;  /* Spans 2 columns */
  grid-row: 1 / 3;     /* Spans 2 rows */
}

Resultat:

┌─────────┬───┬───┐
│         │ 2 │ 3 │
│    1    ├───┼───┤
│(featured)│ 4 │ 5 │
└─────────┴───┴───┘

Alignment

justify-items & align-items

Alignment av alla items:

.grid {
  justify-items: start | end | center | stretch;  /* Horizontal */
  align-items: start | end | center | stretch;    /* Vertical */
}

/* Shorthand */
.grid {
  place-items: center; /* Både justify och align */
}

justify-content & align-content

Alignment av hela gridet:

.grid {
  justify-content: start | end | center | stretch | space-between | space-around;
  align-content: start | end | center | stretch | space-between | space-around;
}

/* Shorthand */
.grid {
  place-content: center; /* Centrera hela gridet */
}

justify-self & align-self

Alignment av enskild item:

.item {
  justify-self: center; /* Horizontal */
  align-self: end;      /* Vertical */
}

Praktiska Exempel

1. Holy Grail Layout

.page {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  min-height: 100vh;
  gap: 20px;
}

.header { grid-area: header; }
.nav    { grid-area: nav; }
.main   { grid-area: main; }
.aside  { grid-area: aside; }
.footer { grid-area: footer; }

2. Responsive Card Grid

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

/* Ingen media query behövs! Cards wrappar automatiskt */

3. Magazine Layout

.magazine {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

.featured {
  grid-column: 1 / 8;  /* 7 columns */
  grid-row: 1 / 3;     /* 2 rows */
}

.article-1 {
  grid-column: 8 / 13; /* 5 columns */
}

.article-2 {
  grid-column: 8 / 13;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 200px;
  gap: 10px;
}

.gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Highlight vissa bilder */
.gallery .wide {
  grid-column: span 2;
}

.gallery .tall {
  grid-row: span 2;
}

5. Dashboard Layout

.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(100px, auto);
  gap: 1.5rem;
}

.widget-large {
  grid-column: span 2;
  grid-row: span 2;
}

.widget-wide {
  grid-column: span 2;
}

.widget-tall {
  grid-row: span 2;
}

Minmax() Function

Flexibel storlek med gränser:

/* Minst 200px, max 1fr */
.grid {
  grid-template-columns: repeat(3, minmax(200px, 1fr));
}

/* Auto-responsiv */
.grid {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

/* Rows med min höjd */
.grid {
  grid-auto-rows: minmax(100px, auto);
}

Auto-fill vs Auto-fit

auto-fill

Skapar så många kolumner som får plats (tom space kvar):

.grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

Resultat (bred skärm):

┌───┬───┬───┬───┬─────┐
│ 1 │ 2 │ 3 │ 4 │(tom)│
└───┴───┴───┴───┴─────┘

auto-fit

Kollapsar tomma kolumner:

.grid {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

Resultat (bred skärm):

┌─────┬─────┬─────┬─────┐
│  1  │  2  │  3  │  4  │
└─────┴─────┴─────┴─────┘

Grid vs Flexbox

Använd Grid för:

  • ✅ Två-dimensionella layouts (rader OCH kolumner)
  • ✅ Page layouts
  • ✅ Complex overlapping
  • ✅ Fixed track sizes
  • ✅ Magazine-style layouts

Använd Flexbox för:

  • ✅ En-dimensionella layouts (rad ELLER kolumn)
  • ✅ Navigation bars
  • ✅ Button groups
  • ✅ Small components
  • ✅ När flex grow/shrink behövs

Ofta används båda:

.page {
  display: grid; /* Overall structure */
  grid-template-columns: 200px 1fr;
}

.nav {
  display: flex; /* Items inside nav */
  gap: 1rem;
}

Responsive Grid Patterns

Pattern 1: Auto-fit Cards

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 2rem;
}

/* Ingen media query! */

Pattern 2: RAM Pattern

.container {
  display: grid;
  grid-template-columns: 1fr min(65ch, 100%) 1fr;
}

.container > * {
  grid-column: 2;
}

.full-bleed {
  grid-column: 1 / -1; /* Break out */
}

Pattern 3: Sidebar

.layout {
  display: grid;
  grid-template-columns: minmax(200px, 25%) 1fr;
  gap: 2rem;
}

@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

Pattern 4: Pancake Stack

.page {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* Header och footer auto, content fyller */

Named Lines

Namnge grid lines:

.grid {
  display: grid;
  grid-template-columns: 
    [sidebar-start] 200px 
    [sidebar-end content-start] 1fr 
    [content-end];
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
}

.content {
  grid-column: content-start / content-end;
}

Implicit vs Explicit Grid

.grid {
  display: grid;
  /* Explicit grid */
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px;
  
  /* Implicit grid (auto-skapade rows) */
  grid-auto-rows: 150px;
  grid-auto-flow: row; /* eller column */
}

Subgrid

Modern feature för nested grids:

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

.child {
  display: grid;
  grid-column: span 2;
  /* Ärver parent's columns */
  grid-template-columns: subgrid;
}

Common Patterns

Centering

.center-everything {
  display: grid;
  place-items: center; /* Båda axlarna */
  min-height: 100vh;
}

12-Column Grid System

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

.col-6 { grid-column: span 6; }
.col-4 { grid-column: span 4; }
.col-3 { grid-column: span 3; }

Masonry Layout (pseudo)

.masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 10px;
  gap: 10px;
}

.masonry-item {
  /* JS: Calculate rows needed based on content height */
  grid-row: span var(--rows);
}

Note: True masonry coming with grid-template-rows: masonry

Browser Support

CSS Grid har utmärkt stöd:

  • Chrome 57+
  • Firefox 52+
  • Safari 10.1+
  • Edge 16+

Feature queries:

@supports (display: grid) {
  .container {
    display: grid;
  }
}

/* Fallback */
.container {
  display: flex; /* Äldre browsers */
}

Performance Tips

1. Använd fr över procent

/* ✅ Bättre performance */
grid-template-columns: 1fr 2fr 1fr;

/* ❌ Långsammare */
grid-template-columns: 25% 50% 25%;

2. Undvik onödiga nästlade grids

/* ❌ Overkill */
.parent { display: grid; }
.child { display: grid; }
.grandchild { display: grid; }

/* ✅ Bättre */
.parent { display: grid; }
.child { display: flex; } /* Eller inget */

Debugging Grid

Browser DevTools

Chrome/Edge/Firefox har grid inspectors:

  1. Inspektera grid container
  2. Aktivera “grid” badge
  3. Se lines, gaps, areas

Grid Overlay

.grid {
  display: grid;
  
  /* Development only */
  background: 
    repeating-linear-gradient(
      to right,
      red 0,
      red 1px,
      transparent 1px,
      transparent calc(100% / 12)
    );
}

Best Practices

  1. Använd semantic HTML - Grid ändrar bara visuell layout
  2. Mobile-first - Börja med enkel layout
  3. Named areas för complex layouts
  4. Auto-fit/fill för responsiveness
  5. Testing - Testa olika content lengths

Common Pitfalls

1. Glöm minmax()

/* ❌ Kan bli för smalt */
grid-template-columns: repeat(auto-fit, 1fr);

/* ✅ Sätt minimum */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

2. Overflow problem

/* ❌ Kan orsaka scroll */
.item {
  grid-column: 1 / 13; /* Om bara 12 columns */
}

/* ✅ Använd -1 för sista line */
.item {
  grid-column: 1 / -1;
}

3. Gap vs Margin

/* ✅ Använd gap istället för margin */
.grid {
  gap: 1rem; /* Ingen margin på första/sista */
}

/* ❌ Undvik */
.item {
  margin: 0.5rem; /* Problem med kanter */
}

Verktyg

Testa Grid interaktivt:

Slutsats

CSS Grid är det kraftfullaste layout-systemet i CSS:

Perfekt för:

  • Page layouts
  • Dashboards
  • Image galleries
  • Magazine layouts
  • Complex UIs

Lär dig dessa först:

  • display: grid
  • grid-template-columns/rows
  • gap
  • grid-column/row
  • repeat() och minmax()
  • auto-fit

Med dessa kan du skapa nästan vilken layout som helst!