CSS Grid layout for two-dimensional design

Alex Chang Feb 2026
1 tab
/* Basic grid container */
.grid-container {
  display: grid;

  /* Define columns: 3 equal columns */
  grid-template-columns: 1fr 1fr 1fr;
  /* Same as: */
  grid-template-columns: repeat(3, 1fr);

  /* Define rows */
  grid-template-rows: 100px auto 50px;

  /* Gap between items */
  gap: 1rem;
  /* Or separately: */
  row-gap: 1rem;
  column-gap: 1.5rem;
}

/* Grid item positioning */
.grid-item {
  /* Span multiple columns/rows */
  grid-column: 1 / 3; /* start line / end line */
  grid-row: 1 / 2;

  /* Span notation */
  grid-column: span 2; /* span 2 columns */
  grid-row: span 3;

  /* Shorthand */
  grid-area: 1 / 1 / 3 / 4; /* row-start / col-start / row-end / col-end */
}

/* Common grid layouts */

/* 1. Basic 12-column grid system */
.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

.col-4 {
  grid-column: span 4; /* 4 of 12 columns */
}

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

.col-8 {
  grid-column: span 8;
}

/* 2. Named grid template areas */
.page-layout {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  gap: 1rem;
  min-height: 100vh;
}

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

/* Stack on mobile */
@media (max-width: 768px) {
  .page-layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "aside"
      "footer";
  }
}

/* 3. Auto-fit responsive grid (no media queries!) */
.auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
}

/* auto-fill creates empty tracks, auto-fit collapses them */
.auto-fill-grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* 4. Card grid with variable sizing */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.featured-card {
  grid-column: span 2; /* featured cards span 2 columns */
}

/* 5. Dense grid (fills gaps) */
.masonry-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: 100px;
  gap: 0.5rem;
  grid-auto-flow: dense; /* fill gaps */
}

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

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

/* 6. Holy Grail layout */
.holy-grail {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
  /* Same as:
    grid-template-rows: auto 1fr auto;
    grid-template-columns: auto 1fr auto;
  */
  min-height: 100vh;
}

.holy-grail-header {
  grid-column: 1 / 4; /* span all columns */
}

.holy-grail-footer {
  grid-column: 1 / 4;
}

/* 7. Asymmetric grid */
.asymmetric-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: repeat(3, auto);
  gap: 1rem;
}

.feature {
  grid-column: 1;
  grid-row: 1 / 3; /* span 2 rows */
}

/* 8. Nested grids */
.outer-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
}

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

/* 9. Explicit placement */
.explicit-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}

.item-a {
  grid-column: 1 / 3;
  grid-row: 1;
}

.item-b {
  grid-column: 3 / 5;
  grid-row: 1 / 3;
}

.item-c {
  grid-column: 1;
  grid-row: 2 / 4;
}

/* 10. Alignment within grid */
.aligned-grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(2, 100px);
  gap: 10px;

  /* Align all items */
  justify-items: center; /* horizontal */
  align-items: center;   /* vertical */

  /* Align grid within container */
  justify-content: center;
  align-content: center;
}

.aligned-item {
  /* Override for specific item */
  justify-self: start;
  align-self: end;
}

/* Advanced techniques */

/* Spanning with line names */
.named-lines {
  display: grid;
  grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
  grid-template-rows: [header-start] auto [header-end content-start] 1fr [content-end];
}

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

/* Subgrid (modern browsers) */
.parent-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.subgrid-item {
  display: grid;
  grid-template-columns: subgrid; /* inherit parent columns */
  grid-column: span 3;
}

/* Implicit grid (auto-generated rows) */
.implicit-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px; /* height of implicit rows */
  gap: 1rem;
}

/* Responsive grid utilities */
@media (min-width: 768px) {
  .md\:grid-cols-2 {
    grid-template-columns: repeat(2, 1fr);
  }

  .md\:grid-cols-3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1024px) {
  .lg\:grid-cols-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Grid with minmax for flexible sizing */
.flexible-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 1rem;
}
1 file · css Explain with highlit

CSS Grid provides two-dimensional layout control for rows and columns simultaneously. I use display: grid to create grid containers. The grid-template-columns and grid-template-rows properties define track sizes. The fr unit distributes available space proportionally. The repeat() function creates multiple tracks efficiently. The grid-gap (now gap) adds spacing between grid items. Using grid-column and grid-row positions items explicitly. The grid-template-areas property creates named layout regions. The auto-fit and auto-fill keywords enable responsive grids without media queries. Grid excels at complex layouts.