Rows, Columns and Tracks in CSS Grid
What You Learn From This Page
- How rows, columns, tracks, lines, cells, and areas relate.
- How to define fixed, flexible, intrinsic, and constrained track sizes.
- How fr, repeat(), minmax(), fit-content(), auto-fit, and auto-fill behave.
- How explicit and implicit tracks are created and controlled.
- How gaps participate in sizing without becoming tracks.
- How content and intrinsic minimums influence Grid calculations.
- How to build card, form, page-shell, sidebar, and article layouts.
- How to diagnose overflow and inspect actual track sizes.
Introduction
CSS Grid is a system of lines and the spaces between those lines. Vertical divisions form column tracks, horizontal divisions form row tracks, and their intersections form cells. Grid items are placed into individual cells or rectangular areas that span several tracks. Once these terms are clear, track definitions become much easier to read and debug.
Track sizing is more powerful than assigning widths and heights to child elements. The Grid container can combine stable dimensions, content-driven dimensions, flexible fractions, minimums, maximums, and repeated patterns. The browser then resolves those instructions against the container's available space and the intrinsic sizes of the content.
This means Grid is not simple percentage arithmetic. A fraction receives a share of flexible space, gaps are removed before that space is distributed, and long content can establish minimum contributions. Strong Grid code treats those rules as part of the layout model rather than fighting the result with offsets.
What Is a Grid Column?
A Grid column is a vertical track between two vertical grid lines. The grid-template-columns property creates explicit column tracks and defines how each one is sized.
.container {
display: grid;
grid-template-columns: 200px 1fr 1fr;
}
This grid has three columns. The first is fixed at 200 pixels, and the other two share remaining flexible space equally. Because three tracks need a boundary on each side and between each pair, the structure has four column lines.
What Is a Grid Row?
A Grid row is a horizontal track between two horizontal grid lines. Explicit rows are defined with grid-template-rows.
.container {
display: grid;
grid-template-rows: 100px auto 1fr;
}
The first row is fixed, the second responds to content and constraints, and the third is flexible when the Grid container has definite available block space. A fractional row does not automatically fill the viewport; there must be space in the relevant axis to distribute.
What Is a Grid Track?
A track is formally the space between two adjacent grid lines. It can be a column track or a row track. The word does not refer to an HTML element and does not describe only a narrow line. It describes the full strip through which Grid cells and areas are formed.
Rows and columns are therefore types of tracks. The terminology matters because many sizing rules apply to either axis. When documentation discusses track sizing, the same concepts may govern a horizontal row or a vertical column depending on the property.
Grid Lines Create Track Boundaries
Lines are numbered from the beginning and end of the explicit grid. Three columns produce lines 1 through 4. Two rows produce lines 1 through 3. Items can use those endpoints to choose where they start and end.
.featured {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
The item spans the tracks between column lines 1 and 3 and row lines 1 and 3. That creates a rectangular area covering two columns and two rows. Endpoints are lines, so the ending number is not the count of tracks occupied.
Cells and Areas
A Grid cell is one row-and-column intersection, similar to a single cell in a table. A Grid area is any rectangular region made from one or more cells. An item auto-placed without a span generally starts in one cell, while a featured item can cover a larger area.
An area must remain rectangular. A single Grid item cannot occupy a disconnected or L-shaped collection of cells. This rectangular model is what allows rows and columns to remain coordinated across a two-dimensional layout.
Defining Explicit Tracks
Tracks declared by grid-template-columns and grid-template-rows belong to the explicit grid. Explicit tracks provide known line boundaries and can be referenced with positive or negative line numbers.
.report {
display: grid;
grid-template-columns: 10rem 2fr 1fr;
grid-template-rows: auto minmax(12rem, 1fr);
}
The declaration establishes three explicit columns and two explicit rows. Additional tracks can still be generated if placement or content extends outside this template.
Fixed Track Sizes
A fixed length such as 200px creates a definite track. Fixed tracks are appropriate when a dimension truly must remain stable, such as a known icon rail or a print-oriented template. They become fragile when applied to dynamic text, reusable components, or page structures that must fit narrow containers.
Prefer relative units such as rem when a stable region should scale with typography. Even then, provide a structural change when the sum of stable tracks and gaps no longer leaves usable content space.
Flexible Tracks with fr
The fr unit represents a fraction of available flexible Grid space. Two 1fr tracks share that space equally; 1fr 2fr divides it into three shares and gives two shares to the second track.
.layout {
display: grid;
grid-template-columns: 1fr 2fr;
}
A fraction is not a literal percentage. Fixed tracks, intrinsic content contributions, gaps, and constraints are considered before or during track sizing. The final pixel sizes depend on the complete layout context.
How Remaining Space Is Distributed
Suppose an 800-pixel container uses 200px 1fr 2fr without gaps. After the fixed 200-pixel track is assigned, 600 pixels remain. Three fractional shares divide that space, producing approximately 200 pixels for the 1fr track and 400 pixels for the 2fr track.
If gaps are added, they are accounted for before the remaining space is divided. This is one reason fractional tracks are often safer than percentages when a design has gutters.
Use repeat() for Repeated Definitions
The repeat() function expresses repeated track patterns without duplicating values. Four equal columns can be written as repeat(4, 1fr). A distinct leading track can be followed by a repeated group.
.data-grid {
display: grid;
grid-template-columns: 12rem repeat(3, minmax(0, 1fr));
}
Repeat improves readability and maintenance. Changing the repeated pattern once updates every generated track in that group.
Content-Sized auto Tracks
An auto track responds to content, available space, and alignment conditions. A common pattern uses an auto-sized label or control region followed by a flexible content track.
.property-row {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 1rem;
}
Auto is context-sensitive rather than a promise to equal the longest unwrapped content. It is often a practical starting point when a track should fit its content while the neighboring track absorbs change.
min-content and max-content
min-content asks for the smallest intrinsic width the content can occupy without avoidable overflow, often producing aggressive wrapping at available breakpoints. max-content asks for the width the content would prefer without wrapping.
These keywords are useful when intrinsic behavior is itself the design requirement. A navigation label column might use max-content to align all following content after the longest label. However, an unexpectedly long label can make that track dominate the layout, so production content still needs testing.
Bound Content with fit-content()
fit-content() allows a track to respond to content while limiting its growth. A sidebar can remain compact for short navigation but stop expanding beyond a useful maximum.
.documentation {
display: grid;
grid-template-columns: fit-content(20rem) minmax(0, 1fr);
gap: 2rem;
}
The function is useful when pure max-content could become too wide and a fixed track would waste space for short content.
Constrain Tracks with minmax()
minmax() defines a lower and upper track size. The browser keeps the track within those boundaries as available space and content change.
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(12rem, 1fr));
gap: 1rem;
}
Each card column should remain at least 12rem and can grow to share extra space. If the container becomes narrower than three minimums plus gaps, the fixed count does not automatically wrap; the grid can overflow. Use an intrinsic repetition pattern or a breakpoint when column count should adapt.
Why minmax(0, 1fr) Matters
A plain 1fr track has an automatic minimum that can honor the minimum content contribution of its items. A long unbroken string, table, image, or preformatted block can therefore force the track wider than expected. minmax(0, 1fr) explicitly permits the track to shrink below that intrinsic minimum.
.two-column-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
The Grid item may also need min-width: 0, and its content may need wrapping or controlled overflow. Track flexibility does not change the internal behavior of every descendant.
Build Intrinsic Grids with auto-fit
auto-fit works with repeated track patterns to fit as many columns as the container can support. Empty tracks collapse, allowing existing items to stretch through the remaining space.
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
gap: 1rem;
}
As space changes, the layout can move naturally from four columns to three, two, and one without viewport-specific media queries. The nested min() keeps the preferred minimum from exceeding an unusually narrow container.
auto-fill Versus auto-fit
auto-fill creates as many potential tracks as fit and retains empty track slots. auto-fit follows a similar fitting process but collapses empty tracks, allowing occupied tracks to expand. The difference is most visible when there are fewer items than available columns.
For many responsive card collections, auto-fit produces the expected stretching behavior. Use auto-fill when preserving the potential track structure is part of the design. Test both with one item, a partially filled row, and a full row.
Implicit Tracks
When items require rows or columns beyond the explicit template, Grid creates implicit tracks. A three-column grid with six auto-placed items naturally generates a second row even if no explicit row template exists.
Implicit tracks make dynamic lists practical. They can also reveal placement mistakes. If an item is assigned to column line 8 in a three-column template, the browser may create implicit columns to satisfy that request, making the layout far wider than expected.
Control Implicit Rows and Columns
grid-auto-rows and grid-auto-columns control the sizes of generated tracks. A minimum with an automatic maximum is safer than a rigid row height when content can vary.
.results {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-auto-rows: minmax(10rem, auto);
gap: 1rem;
}
Every implicit row is at least 10rem but can grow for longer content. Fixed implicit rows may clip or overlap content when text expands.
Track Gaps Are Not Tracks
gap creates gutters between adjacent tracks, but a gap is not itself a track and cannot contain a Grid item. Three column tracks have two internal column gaps. Row and column gaps can be controlled together or separately.
.grid {
row-gap: 2rem;
column-gap: 1rem;
}
/* Equivalent */
.grid {
gap: 2rem 1rem;
}
Container-level gaps are clearer than adding regular margins to every Grid item. They also participate predictably in the remaining-space calculation.
Avoid Percentage Tracks Plus Gaps
Two tracks sized at 50 percent already consume the full container width. Adding a gap places extra width between them and can cause overflow. Fractions divide the space remaining after gaps, so 1fr 1fr is usually safer for equal flexible columns.
.comparison {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
}
Percentages remain valid when their specific containing-block relationship is needed, but their interaction with gaps and intrinsic sizing should be deliberate.
Place Items Across Tracks
Items can span a number of tracks or specify explicit start and end lines. span 2 describes a two-track extent without hard-coding an endpoint. 1 / -1 spans from the first to the final explicit line.
.featured { grid-column: span 2; }
.section-heading { grid-column: 1 / -1; }
Negative line numbers count backward from the end of the explicit grid. They are useful when responsive templates change the number of explicit columns.
Name Important Grid Lines
Named lines replace numeric endpoints with structural language. Multiple names can identify the same boundary when one region ends and another begins.
.layout {
display: grid;
grid-template-columns:
[sidebar-start] 18rem
[sidebar-end content-start] minmax(0, 1fr)
[content-end];
}
.main {
grid-column: content-start / content-end;
}
Named lines help complex but stable templates communicate intent. They are unnecessary overhead for a simple auto-placed card grid.
Page Shell Rows
A header, main region, and footer form a natural three-row grid. Content-driven outer rows and a flexible middle row create a sticky-footer effect without removing any region from normal flow.
.page {
min-height: 100dvh;
display: grid;
grid-template-rows: auto 1fr auto;
}
The footer reaches the bottom when content is short and moves downward when main content grows. If the main region must scroll internally, its minimum sizing and overflow behavior need separate consideration.
Sidebar and Main Columns
Documentation and dashboard shells often combine a stable navigation track with a flexible application track.
.dashboard {
display: grid;
grid-template-columns: 16rem minmax(0, 1fr);
gap: 2rem;
}
The main track's zero minimum protects the container from intrinsic overflow. At narrow widths, change to one column or an alternate navigation pattern instead of compressing both regions below usability.
Three-Column Content Layouts
A page can use stable side regions around flexible main content, but the combined minimum must remain realistic.
.content-layout {
display: grid;
grid-template-columns: 15rem minmax(0, 1fr) 15rem;
gap: 2rem;
}
Do not preserve all three columns at every width. Responsive design should change the structure when sidebars leave insufficient reading space, often moving secondary content below the main region or into a disclosure.
Create a Readable Article Track
Grid can center a readable content column between flexible outer tracks. A character unit expresses a typographic line-length target.
.article-frame {
display: grid;
grid-template-columns: 1fr minmax(0, 65ch) 1fr;
}
.article-content {
grid-column: 2;
}
Full-bleed media or callouts can occupy wider lines while ordinary prose stays in the center track. Preserve semantic source order and avoid making every paragraph an independently placed item unless the layout requires it.
Align Form Labels and Controls
A form with aligned labels can use a content-sized first track and a flexible second track. The longest label influences the shared label column.
.form {
display: grid;
grid-template-columns: max-content minmax(0, 1fr);
gap: 1rem;
}
On narrow screens, a single-column form is often easier to read and operate. Grid controls visual placement, but label associations, help text, and errors still require correct semantic HTML.
Images and Replaced Content
Large images can contribute intrinsic widths that expand tracks. A responsive image baseline prevents media from exceeding its available box.
img {
max-width: 100%;
height: auto;
}
Embedded media, canvases, tables, and other replaced or intrinsically sized content may need their own constraints. Fix the source of the minimum rather than hiding overflow at the Grid container.
Long Text and User-Generated Content
Unbroken strings can reveal intrinsic-size assumptions. A flexible track with a zero minimum and a Grid item that can shrink provides the geometry; text wrapping provides the content policy.
.grid-item {
min-width: 0;
overflow-wrap: anywhere;
}
Use aggressive wrapping only where breaking identifiers is acceptable. Code samples and data tables may need contained horizontal scrolling instead.
Track Sizing Is Content-Aware
The browser considers intrinsic content sizes, explicit minimums and maximums, available space, gaps, and flexible factors. That is why two apparently equal fractional columns can behave unexpectedly when one contains a wide child. Grid is honoring sizing constraints, not ignoring the fraction.
When a layout surprises you, inspect the computed track size and the item's min-content contribution before changing the template. Often the correct fix is a minimum reset or content constraint rather than a new hard-coded width.
Rows Are Not Flexbox Wrapping
Grid does not wrap items in the same conceptual way as Flexbox. The container creates tracks and auto-placement assigns items to cells. Responsive repetition may change how many explicit columns exist, causing items to occupy additional rows, but the underlying model remains track-based.
This distinction explains why Grid columns align across rows while wrapped Flexbox lines size independently. Choose Grid when those shared tracks are part of the requirement.
Definite and Indefinite Available Space
Track sizing depends on whether the Grid container has a definite size in the relevant axis. A container with a resolved inline size usually gives column fractions a clear amount of space to divide. Row fractions are more subtle when the container's block size is content-driven, because there may be no definite remaining height to distribute.
This explains why grid-template-rows: auto 1fr auto is most meaningful in a page shell that also has a definite or minimum viewport-related block size. Without that context, the fractional row can behave closer to content sizing because the container grows with its content. Adding an arbitrary fixed height merely to make 1fr visible is usually the wrong fix; first decide whether a constrained-height layout is actually required.
Percentages also depend on a definite containing size. If a percentage row is resolved against an indefinite height, its behavior may not match a percentage column in a width-constrained page. When an axis should remain content-driven, prefer auto, intrinsic keywords, or a minimum with an automatic maximum.
Minimums, Maximums, and Clamping
Every track sizing function provides a minimum and maximum behavior, whether those boundaries are explicit or implied. A fixed length effectively fixes both. A flexible track has an intrinsic automatic minimum unless that minimum is replaced. minmax() makes the boundary visible in the authored code.
When the requested minimums cannot fit, Grid does not magically make the container larger and remain responsive at the same time. Three tracks with a 16rem minimum plus two gaps require enough inline space for that total. A fixed repeat count will overflow or compress surrounding layout when the container is narrower. An auto-fit pattern changes track count, while a media or container query can switch to a different template.
Maximums should also reflect content goals. A track with minmax(12rem, 30rem) stops growing at 30rem and may leave unused container space depending on the rest of the template and content distribution. A maximum of 1fr instead lets the track share flexible space. Choose boundaries from usability requirements, not from values that happened to match one screenshot.
Subpixel Distribution and Visual Rounding
Available space often cannot be divided into whole CSS pixels. Three equal fractional columns inside a width that is not divisible by three produce fractional computed sizes. Browsers distribute rounding so the complete grid still fits the container. Individual tracks may therefore differ by a tiny rendered amount even though all were defined as 1fr.
Do not repair this normal behavior with hard-coded widths or negative margins. Such corrections usually create a real mismatch at another viewport or device pixel ratio. Use the Grid overlay and computed layout information when exact track measurements matter, and judge equality by the declared sizing relationship rather than expecting every screenshot measurement to be numerically identical.
Hairline borders and transformed descendants can make subpixel differences more noticeable. Keep decorative effects separate from track math, use consistent box sizing, and test at more than one zoom level before concluding that the Grid algorithm is incorrect.
Writing Modes and Logical Axes
Rows and columns are visual descriptions, but Grid also operates in logical writing directions. Columns generally progress along the inline axis, while rows progress along the block axis. In right-to-left text, the inline start side changes, and line numbering begins from the corresponding side of the Grid container.
Negative line numbers and named lines are often more adaptable than assuming a physical left or right endpoint. Logical margins, padding, and inset properties also reduce direction-specific overrides around Grid items. Test the actual dir="rtl" state because translated content length and directional icons can reveal issues beyond line numbering.
Vertical writing modes further demonstrate why logical thinking matters. A column remains associated with the inline progression of that writing mode rather than a permanently memorized physical direction. Most applications use horizontal writing, but understanding the model prevents physical assumptions from leaking into reusable layout utilities.
Production Track Testing
Test a Grid with the smallest and largest realistic item counts. A single item reveals how auto-fit stretches occupied tracks, a partially filled row reveals the difference from auto-fill, and a large data set reveals implicit-row behavior. Include items that span tracks at different source positions because spans can create holes or move later content.
Stress every intrinsic input: long headings, translated labels, unbroken identifiers, wide images, code samples, tables, validation errors, and delayed content. Test 200 and 400 percent zoom as well as narrow containers embedded inside otherwise wide pages. A track system is responsive only when it responds to its own available space and content, not just the top-level viewport.
Verify visual and DOM order together. Responsive templates may move side regions or full-width items, but keyboard and assistive-technology order generally follows the source. Track sizing can solve presentation without changing semantics, so keep task sequence correct in the HTML.
Finally, test loading and empty states. Skeleton items may have different minimums from final content, and removing all cards can expose a container whose height or alignment depended accidentally on populated tracks. A reliable design defines how the component behaves before, during, and after data arrives.
Common Mistakes and Better Choices
| Mistake | Better Approach |
|---|---|
| Confusing tracks with cells | Remember a track is a full row or column strip |
| Thinking columns are DOM elements | Treat them as layout regions created by CSS |
| Using many rigid pixel tracks | Combine stable, flexible, and constrained sizing |
| Using 1fr without checking minimums | Use minmax(0, 1fr) where shrinking is required |
| Fixed row heights for dynamic text | Use content sizing or minmax(minimum, auto) |
| Percentage columns totaling 100% plus gap | Use fractional tracks |
| Ignoring automatically created tracks | Inspect and configure grid-auto-rows or columns |
| Treating fr as a fixed percentage | Reason about remaining flexible space |
Debug with Grid Overlays
Browser developer tools can draw line numbers, track boundaries, gaps, and named areas. Enable the Grid overlay before estimating dimensions visually. It immediately shows whether a surprising region is explicit or implicit and whether an item spans the intended endpoints.
Inspect computed styles and track sizes, then locate the content establishing any unexpected minimum. Verify the container's available width, padding, and gaps. A correct diagnosis is faster than adding offsets that mask the sizing rule.
1. Confirm the explicit row and column templates
2. Display line numbers and implicit tracks
3. Check fixed sizes, gaps, and available space
4. Inspect intrinsic minimums of Grid items
5. Verify spans and negative line endpoints
6. Test long content and narrow containers
7. Change the layout model only after identifying the cause
A Responsive Track Strategy
Track choices often progress from fixed to flexible, then constrained flexible, then intrinsic responsive. A prototype may begin with two fixed columns. A production version might use fractions, add minimum boundaries with minmax(), and finally allow column count to respond through auto-fit.
Use the simplest level that satisfies real content. More advanced functions are useful when they encode a requirement, but they should not replace clear breakpoints when the component needs a genuinely different structure.
Rows, Columns, and Tracks Summary
| Concept | Meaning |
|---|---|
| Column | A vertical Grid track |
| Row | A horizontal Grid track |
| Track | Space between adjacent Grid lines |
| Grid line | A boundary separating tracks |
| Grid cell | One row-and-column intersection |
| Grid area | A rectangular region of one or more cells |
| Explicit track | A track declared in a template |
| Implicit track | A track generated automatically as needed |
Common Interview Questions
What is a Grid track? It is the space between two adjacent grid lines and can be a row track or column track.
What is the difference between a row and a column? A row is a horizontal track; a column is a vertical track.
What does 1fr mean? It means one share of the available flexible Grid space, not a fixed percentage.
What does repeat() do? It repeats a track definition a fixed or intrinsic number of times.
What does minmax() do? It gives a track a minimum and maximum sizing boundary.
What are implicit tracks? They are rows or columns created automatically when placement requires space outside the explicit grid.
How are implicit row sizes controlled? Use grid-auto-rows.
Why use minmax(0, 1fr)? It allows a flexible track to shrink below its automatic intrinsic minimum and helps prevent content-driven overflow.
What is the difference between auto-fit and auto-fill? Both fit repeated tracks, but auto-fit collapses empty tracks while auto-fill preserves potential empty slots.
Practical Review Checklist
- Distinguish lines, tracks, cells, and areas.
- Use fr for shares of flexible space, not as a percentage assumption.
- Use repeat() for repeated track patterns.
- Use minmax() to express responsive lower and upper boundaries.
- Use auto-fit with minmax() for intrinsic repeated grids.
- Use minmax(0, 1fr) when intrinsic minimums cause overflow.
- Prefer fractions over percentage tracks when gaps are present.
- Avoid fixed row heights for unpredictable content.
- Understand which tracks are explicit and which are implicit.
- Configure implicit track sizing when consistency matters.
- Use gap rather than child margins for track gutters.
- Constrain images, tables, code, and long text appropriately.
- Use Grid overlays to inspect actual line and track behavior.
Key Takeaway
Grid lines create boundaries, adjacent lines create row and column tracks, track intersections create cells, and one or more cells form areas occupied by Grid items. Template properties define the explicit structure, while the browser creates implicit tracks when content needs additional space.
Choose track sizes according to the relationship: stable lengths for genuinely fixed regions, fractions for flexible shares, intrinsic keywords for content-driven dimensions, and minmax() for useful boundaries. Account for gaps and intrinsic minimums, test dynamic content, and inspect the actual grid with browser tools. Those practices turn Grid sizing from trial and error into a predictable layout system.