CSS Tutorial
CSS Grid
Grid is two-dimensional layout: rows and columns at once. Tracks, areas, and gap do the work.
Rows and columns together
Flexbox lines items on one axis. Grid paints a table of tracks — columns and rows — then places items in cells. A studio homepage with a banner, a main story, a hours aside, and a footer is a grid. You describe the tracks on the parent. The children sit in cells, or span several.
display: grid on the container. grid-template-columns names the column tracks.gap is the alley between tracks. You do not need extra wrapper divs for every column.
Tracks with grid-template-columns
A track can be a length, a percent, fr (a fraction of leftover space), orminmax(). Repeat is a shortcut: repeat(3, 1fr) is three equal columns.
| Template | Meaning |
|---|---|
1fr 1fr 1fr | Three equal columns |
repeat(3, 1fr) | The same, shorter |
200px 1fr | Fixed sidebar, fluid main |
minmax(12rem, 1fr) minmax(12rem, 1fr) | Two columns that cannot crush below 12rem |
auto 1fr auto | Content, leftover, content — a header bar |
Example
<style>
body {
font-family: system-ui, sans-serif;
color: #0c4a6e;
background: #f0f9ff;
margin: 1.25rem;
}
.desks {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem;
}
.desk {
padding: 0.85rem 1rem;
background: #fff;
border: 1px solid #7dd3fc;
border-radius: 0.5rem;
}
h2 { margin: 0 0 0.3rem; font-size: 1rem; color: #0d9488; }
p { margin: 0; color: #475569; font-size: 0.9rem; }
</style>
<h1>Harbor studio</h1>
<div class="desks">
<article class="desk"><h2>Tide</h2><p>Window seat</p></article>
<article class="desk"><h2>Pier</h2><p>Quiet corner</p></article>
<article class="desk"><h2>Loft</h2><p>Two chairs</p></article>
</div>gap on a grid is both column gap and row gap. Write gap: 1rem 1.5rem if row and column alleys should differ. Preview at /css/try and change repeat(3, 1fr)to 1fr 2fr 1fr — the middle desk grows.
A sidebar with 1fr
fr takes leftover space after fixed tracks. A hours column of 12rem plus1fr for the article is the classic page. On a narrow preview the two columns stay side by side until you add a media query (next chapter) or auto-fit.
Example
<style>
body {
font-family: system-ui, sans-serif;
color: #0c4a6e;
background: #f0f9ff;
margin: 1.25rem;
}
.page {
display: grid;
grid-template-columns: 1fr 10rem;
gap: 1rem;
}
article, aside {
padding: 1rem;
border-radius: 0.55rem;
}
article { background: #fff; border: 1px solid #bae6fd; }
aside { background: #ccfbf1; color: #0f766e; }
h2 { margin: 0 0 0.4rem; font-size: 1.05rem; }
p { margin: 0; }
</style>
<h1>Harbor studio</h1>
<div class="page">
<article>
<h2>Darkroom hours</h2>
<p>Book the enlarger in 60-minute slots. Chemistry is included.</p>
</article>
<aside>
<h2>Open</h2>
<p>8–16</p>
</aside>
</div>Named areas, briefly
grid-template-areas lets you draw the page with words. Each string is a row. Repeated names span cells. Children opt in with grid-area: header. It is the same grid as numeric lines — just labeled so a layout reads like a sketch.
Example
<style>
body {
font-family: system-ui, sans-serif;
color: #0c4a6e;
background: #f0f9ff;
margin: 1.25rem;
}
.studio {
display: grid;
grid-template-columns: 1fr 9rem;
grid-template-areas:
"header header"
"main aside"
"footer footer";
gap: 0.65rem;
}
.studio > * { padding: 0.75rem 0.9rem; border-radius: 0.45rem; }
header { grid-area: header; background: #0ea5e9; color: #fff; }
main { grid-area: main; background: #fff; border: 1px solid #7dd3fc; }
aside { grid-area: aside; background: #ccfbf1; }
footer { grid-area: footer; background: #0d9488; color: #fff; font-size: 0.9rem; }
h1, h2 { margin: 0 0 0.3rem; font-size: 1rem; }
p { margin: 0; }
</style>
<div class="studio">
<header><h1>Harbor studio</h1></header>
<main><h2>Print shop</h2><p>Giclée on cotton rag.</p></main>
<aside><p>Lane 12</p></aside>
<footer>Open 8–16</footer>
</div>A period . in the area string is an empty cell. Every row must have the same number of tokens. If the sketch does not rectangularize — a name that is not a solid rectangle — the browser drops the template.
Flex or grid?
- One row or one column of components: flex.
- A page with rows and columns that must line up in both directions: grid.
- A card row that wraps: either. Flex wrap is simpler.
auto-fitplusminmaxis grid’s version.
You can nest them. A grid page can hold a flex header. A flex card can hold a tiny grid of icons. Pick the tool for the box in front of you, not one tool for the whole site.
Worked examples
The short listings above show one property. These sheets paint documents you would actually ship: a lab dashboard, a clinic form, a marks table, a nav bar.
CSS does not invent meaning. HTML already said what the pieces are. Cascade, specificity, and the box model decide how they look. The numbers are classroom values — current, pH, pulse, 3-4-5 — so the style has something real to sit on.
Preview them in the CSS editor at /css/try. Change one property and watch the page paint. The tags stay the same.
Statistics
A marks board in two columns
Grid is two-dimensional: rows and columns at once. 1fr 1fr splits leftover space. gap is the alley. Named areas pin header/main/side without nested floats.
auto-fit minmax is a card gallery that adds columns as the viewport grows. Span 2 is a banner row.
Example
<style>
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.grid div { background: #e0f2fe; padding: 0.5rem; }
</style>
<div class="grid"><div>Ada 72</div><div>Ben 81</div><div>Cara 64</div><div>Dee 90</div></div>Chemistry
A page: head, main, side
grid-template-areas is a drawing of the lab site. Each child sets grid-area. Change the drawing for a phone in a media query — same HTML.
Example
<style>
.page {
display: grid;
grid-template-areas: "head head" "main side";
gap: 0.4rem;
}
header { grid-area: head; background: #166534; color: #fff; padding: 0.4rem; }
main { grid-area: main; background: #dcfce7; padding: 0.4rem; }
aside { grid-area: side; background: #e0f2fe; padding: 0.4rem; }
</style>
<div class="page">
<header>Titration</header>
<main>Run 1: 24.8 mL</main>
<aside>HCl vs NaOH</aside>
</div>