Skip to content
Home
CSS Grid: The Complete Guide with Examples

CSS Grid: The Complete Guide with Examples

Web Development Web Development 8 min read 1671 words Beginner ExcellentWiki Editorial Team

CSS Grid is the most powerful layout system in CSS. It handles both rows and columns simultaneously, making it ideal for complex page layouts that were previously impossible without JavaScript or fragile float hacks. Unlike Flexbox which works in one dimension at a time, Grid operates in two dimensions and gives you precise control over both axes at once.

Grid vs Flexbox

FlexboxGrid
One-dimensional (row or column)Two-dimensional (row and column)
Content-drivenLayout-driven
Best for nav bars, centering, componentsBest for page layouts, complex grids
Distributes space along a single axisPlaces items in rows and columns simultaneously

The rule of thumb: use Flexbox for layout along one axis (a navigation bar, a row of cards, centering a button), and use Grid when you need both rows and columns (a magazine layout, a dashboard, a photo gallery).

Basic Grid

Setting up a grid is straightforward. Define a container as a grid, then specify your column and row tracks:

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: auto;
  gap: 16px;
---

Creates a three-column grid. Each child becomes a grid item. The gap property (formerly grid-gap) adds spacing between grid cells without adding margin to the items themselves — this avoids the collapsing margin problems that plague float-based layouts.

Grid Template Columns

The grid-template-columns property accepts a wide variety of values and units, giving you enormous flexibility in how columns behave:

/* Fixed columns */
grid-template-columns: 200px 200px 200px;

/* Responsive columns */
grid-template-columns: 1fr 2fr 1fr;    /* 3 columns, middle is twice as wide */
grid-template-columns: repeat(3, 1fr);  /* 3 equal columns */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));  /* responsive! */
grid-template-columns: 200px 1fr 200px;  /* fixed + fluid + fixed */

The fr unit is unique to CSS Grid. It distributes available space proportionally, similar to flex-grow in Flexbox but working in the grid track sizing context. 1fr takes one share of the remaining space, 2fr takes two shares, and so on.

The Responsive Pattern

One of Grid’s most powerful features is creating responsive layouts without media queries:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
---

This auto-creates as many 300px-minimum columns as will fit. On a 1200px viewport, you get four columns. On a 700px viewport, you get two. On a 350px phone, you get one. No media queries needed — the grid adapts automatically to the available space.

auto-fill vs auto-fit: auto-fill preserves empty column tracks (they take up space even when empty), while auto-fit collapses empty tracks to zero width. Use auto-fill when you want consistent column sizing regardless of content, and auto-fit when you want items to expand to fill the available space.

Grid Template Areas

Grid template areas provide the most readable way to define complex page layouts. You create a visual ASCII-art representation of your layout right in your CSS:

.layout {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "sidebar content content"
    "footer  footer  footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
---

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

This approach makes the layout visually obvious in the code. Reordering the layout for different screen sizes becomes as simple as changing the grid-template-areas string in a media query — you don’t need to touch the HTML at all.

Placing Items Explicitly

Grid items automatically fill cells in order, but you can place them explicitly using line numbers, named lines, or spans:

.item {
  grid-column: 1 / 3;      /* span from column line 1 to 3 */
  grid-column: 1 / -1;     /* span entire row */
  grid-column: span 2;     /* span 2 columns */

  grid-row: 1 / 3;
  grid-row: span 2;
---

The -1 value refers to the last line, making grid-column: 1 / -1 a convenient shorthand for spanning the full width. This is particularly useful in dashboard layouts where some widgets need to be wider or taller than others.

Grid Alignment

Grid provides comprehensive alignment control at both the container and item level:

.container {
  display: grid;
  grid-template-columns: repeat(3, 100px);

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

  /* Align the entire grid within the container */
  justify-content: center;   /* horizontal */
  align-content: center;     /* vertical */
---

.item {
  /* Override container alignment for one item */
  justify-self: start;
  align-self: end;
---

This two-tier alignment system is powerful. Container-level properties set defaults for all items, while item-level properties override those defaults for specific elements.

Practical Layouts

Holy Grail Layout

The classic Holy Grail layout (header, nav, main, aside, footer) is trivial with Grid:

body {
  display: grid;
  grid-template:
    "header  header  header" 60px
    "nav     main    aside" 1fr
    "footer  footer  footer" 60px
    / 200px   1fr     200px;
  min-height: 100vh;
---

Card Grid

A responsive card layout that adapts to any screen size:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
---

.card {
  display: flex;
  flex-direction: column;
---

.card-footer {
  margin-top: auto;  /* push footer to bottom of card */
---

Dashboard Layout

For data dashboards where widgets have different sizes:

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

.chart-wide {
  grid-column: span 2;
---

.chart-full {
  grid-column: 1 / -1;
---

Named Grid Lines

Named lines make complex grids more maintainable by giving semantic names to grid lines:

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

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

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

Common Gotchas

  • gap replaces grid-gapgrid-gap is deprecated but still works in older browsers
  • auto-fill vs auto-fitauto-fill keeps empty tracks, auto-fit collapses them
  • Implicit rows — use grid-auto-rows: minmax(100px, auto) for consistent sizing of auto-created rows
  • Overlap — grid items can overlap (positive and negative z-index applies), enabling creative designs without absolute positioning

Related: Learn Flexbox and responsive design.

Grid vs Flexbox Decision

Choose Grid for two-dimensional layouts (rows and columns simultaneously) and Flexbox for one-dimensional layouts (either row or column). Grid excels at page-level layouts and component layouts that need alignment in both directions. Flexbox is ideal for navigation bars, card rows, and centering. The two can be nested — use Grid for the overall page layout and Flexbox for component-level alignment within grid cells.

Subgrid

Subgrid (grid-template-rows: subgrid) allows child elements to align with the parent grid’s track sizing. It solves the classic alignment problem where cards in a grid need their headers, content, and footers to align across rows. Without subgrid, aligning elements across grid items required JavaScript or fixed heights. Subgrid is supported in all modern browsers (2023+).

Web Performance Metrics

Understanding performance metrics helps prioritize optimization efforts. First Contentful Paint (FCP): when the first text or image appears — target under 1.8 seconds. Largest Contentful Paint (LCP): when the main content loads — target under 2.5 seconds. Interaction to Next Paint (INP): responsiveness to user interactions — target under 200 milliseconds. Cumulative Layout Shift (CLS): visual stability — target under 0.1. First Input Delay (FID): time to first interaction — target under 100 milliseconds. Time to First Byte (TTFB): server response time — target under 800 milliseconds. Use Google’s Lighthouse, WebPageTest, and Chrome DevTools to measure these metrics. Real User Monitoring (RUM) captures actual user experiences, which may differ from synthetic tests. Set up dashboards tracking Core Web Vitals and alert when thresholds are breached.

Accessibility Beyond Compliance

Web accessibility ensures your site works for everyone, including people using screen readers, keyboard navigation, or other assistive technologies. WCAG 2.2 guidelines organize requirements into four principles: Perceivable (content must be available to senses), Operable (interface must be usable), Understandable (content and interface must be comprehensible), and Robust (content must work with current and future technologies). Practical steps: use semantic HTML elements (nav, main, aside, article), provide alt text for images, ensure color contrast ratios meet WCAG AA standards (4.5:1 for normal text), support keyboard navigation with visible focus indicators, and test with screen readers (NVDA, VoiceOver, JAWS). Accessibility benefits everyone — captions help users in noisy environments, keyboard navigation helps users with repetitive strain injuries, and high contrast helps users in bright sunlight.

FAQ

What level of expertise is required? The content assumes basic programming knowledge but explains concepts in depth. Beginners may need to reference prerequisite topics.

How do I know if I am implementing this correctly? Write tests that verify behavior, use linters and static analysis, and get code reviews from experienced practitioners.

What are the most common pitfalls? Over-engineering, premature optimization, and neglecting testing are the most frequent mistakes. Start simple, measure, and iterate.

Related Concepts and Further Reading

Understanding css grid requires familiarity with several interconnected ideas and principles that together form a complete picture. Exploring these related concepts deepens your knowledge and provides context that makes the core material more meaningful and applicable. Each concept builds on the others, creating a web of understanding that supports deeper learning and practical application. Taking time to explore how these elements connect reveals patterns that accelerate comprehension and retention of new information.

The relationship between css grid and adjacent fields is worth particular attention. Many of the most important insights emerge at the boundaries between disciplines, where ideas from different areas combine to create new approaches and solutions that neither field could produce alone. Exploring these connections pays dividends in both breadth and depth of understanding, revealing patterns and principles that might otherwise remain hidden from view. Cross-disciplinary knowledge is increasingly valued as problems become more complex and interconnected.

For those looking to go beyond introductory material, several excellent resources provide deeper treatment of specific aspects of css grid. Academic journals, industry publications, authoritative reference works, and online courses each offer different perspectives and levels of detail. The key is to match your reading to your current learning goals and build knowledge progressively, focusing on quality over quantity in your study materials. A well-chosen resource that matches your current level is worth more than dozens of resources that are too basic or too advanced.

Section: Web Development 1671 words 8 min read Beginner 756 articles in section Report inaccuracy Back to top