← Back to all tutorials

Rows

Define grid rows with grid-template-rows — control row heights with fixed sizes, fractions, auto, and minmax for flexible vertical layouts.

Rows

Columns handle the horizontal layout. Rows handle the vertical layout. Together they give you full two-dimensional control.

grid-template-rows

.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 200px 300px 200px;
}

This creates a 3×3 grid where rows are 200px, 300px, and 200px tall.

Using fr with Rows

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

A classic layout pattern: header (auto — sized to content), main content (1fr — takes remaining space), and footer (auto). The container needs an explicit height for fr to work with rows.

Implicit Rows

.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 200px 200px;
    grid-auto-rows: 150px;
}

If there are more items than defined rows can hold, extra rows are created automatically. grid-auto-rows sets the height of these implicit rows. Without it, they default to auto (content height).

minmax with Rows

grid-auto-rows: minmax(100px, auto);

Each row is at least 100px tall but grows to fit its content. This is the most practical setting for rows because it prevents content overflow while maintaining a minimum height.

Row Gap

.container {
    display: grid;
    row-gap: 20px;      /* Gap between rows only */
    gap: 10px 20px;     /* row-gap column-gap */
    gap: 20px;          /* Same gap for both */
}

Key Takeaways

  • grid-template-rows defines explicit row heights
  • grid-auto-rows sets the size of automatically created (implicit) rows
  • minmax(100px, auto) is the best default — minimum height with content flexibility
  • The fr unit with rows requires the container to have an explicit height