search

CSS Grid Fr Unit Explained

CSS Grid introduced a flexible unit called fr (fractional unit). 1fr represents one fraction of the available space in a grid container.

If you’ve worked with percentages or px for column widths, the fr unit feels similar but handles remaining space automatically – no manual calculations needed.

The grid items in the examples below are positioned using the grid areas property:

.grid-wrap {
    max-width: 100%;
    margin: 3em auto;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 50px 150px 50px;
    grid-template-areas: "head head2 . side" "main main2 . side" "footer footer footer footer";
}

Each of the four columns occupies the same width (space) in the grid.

Head
Head 2
Main
Main 2
Side
Footer

Examples of Using fr

Here’s a similar grid, but with different fr values. Notice how the column widths adjust:


.grid-wrap {
    /* ... */
  
    grid-template-columns: 1fr 1fr 40px 20%;
    grid-template-rows: 100px 200px 100px;

    /* ... */
}

Head
Head 2
Main
Main 2
Side
Footer

In the final example, the sidebar occupies 2fr of the space. Its width matches the combined width of the first and second columns.


.grid-wrap {
    /* ... */
  
    grid-template-columns: 1fr 1fr 40px 2fr;
    grid-template-rows: 100px 200px 100px;
  
    /* ... */
}
Head
Head 2
Main
Main 2
Side
Footer

fr vs Percentages

At first glance, fr and % seem interchangeable. Three columns of 33.33% look the same as 1fr 1fr 1fr – until you add a gap.

Percentages are calculated from the container’s total width. They don’t account for gaps. A 3-column grid with 33.33% 33.33% 33.33% and a 20px gap adds up to 100% of the width plus 40px of gaps, causing horizontal overflow:

/* Overflows - 99.99% + 40px of gaps > container width */
grid-template-columns: 33.33% 33.33% 33.33%;
gap: 20px;

/* Works - fr accounts for gaps automatically */
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;

The fr unit avoids this because the browser subtracts gaps first, then divides the remaining space among the fr tracks. No overflow, no manual math.

This is the main reason to prefer fr over % in grid layouts. Percentages still have a role when you need a column to stay at an exact proportion regardless of gaps, but for most layouts fr is the safer choice.

Mixed Units

You can mix fr with other unit types in the same declaration – percentages, fixed px values, or auto. The browser allocates fixed and percentage tracks first, then distributes the remaining space among the fr tracks.

Here’s how the calculation works step by step on an 800px container with grid-template-columns: 300px 10% 1fr 2fr:

  1. Fixed tracks first: 300px is reserved.
  2. Percentage tracks: 10% of 800px = 80px.
  3. Remaining space: 800 – 300 – 80 = 420px.
  4. Distribute among fr tracks: 420px ÷ 3 total fr = 140px per fr. The 1fr column gets 140px, the 2fr column gets 280px.

If there’s a gap, it’s subtracted in step 3 as well. With gap: 20px and 3 gaps between 4 columns, the remaining space would be 420 – 60 = 360px, giving 120px per fr.

main {
  width: 800px;
  display: grid;
  grid-template-columns: 300px 10% 1fr 2fr;
  /* Result: 300px  80px  140px  280px */

  grid-template-rows: auto;
}

fr vs auto

The auto keyword sizes a column to fit its content. The fr unit distributes remaining space regardless of content size.

When you combine them, auto columns shrink-wrap their content first, then fr columns split whatever is left:

grid-template-columns: auto 1fr auto;
/* sidebar | flexible main | sidebar */

This is a common pattern for page layouts where sidebars should be as wide as their content, and the main area fills the rest. It also works nicely with the aspect-ratio property for grid cards that maintain proportions.

fr with repeat() and minmax()

The fr unit pairs well with responsive grid patterns that avoid media queries. Using repeat() with minmax() creates grids that automatically wrap items to the next row:

grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

Each column is at least 250px wide. When there’s extra space, the 1fr maximum distributes it evenly across columns.

As the viewport shrinks, columns drop to a new row instead of getting squeezed below 250px. If you care about rendering speed, check my post on CSS Grid and web performance.

The difference between auto-fill and auto-fit: auto-fill keeps empty tracks when space is available, while auto-fit collapses them so existing items stretch to fill the row.

Common Pitfalls

A few things that trip up developers working with the fr unit for the first time:

1. fr doesn’t work outside Grid

Unlike % or px, the fr unit only applies to grid-template-columns and grid-template-rows. Using it in width, margin, or Flexbox properties has no effect.

2. Overflow with large content

An fr column can grow beyond its calculated fraction if its content doesn’t fit. To prevent this, use minmax(0, 1fr) instead of 1fr:

/* Default: fr uses content size as minimum */
grid-template-columns: 1fr 1fr;

/* Force minimum to 0 - content will overflow instead of expanding */
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);

3. fr doesn’t work inside calc()

The fr unit is a <flex> data type, not a <length> like px or %. That means calc(1fr - 20px) is invalid and will be ignored. If you need a minimum size with flexible growth, use minmax() instead: minmax(200px, 1fr).

4. Gaps eat into fr space

The gap property is deducted before fr values are calculated. A 3-column 1fr 1fr 1fr grid with a 20px gap actually gives each column (total - 40px) / 3, not total / 3.

FAQs

What does 1fr mean in CSS Grid?
1fr means one fraction of the available space in a grid container. If you have grid-template-columns: 1fr 1fr 1fr, the container's width (minus any gaps) is divided into three equal columns.
What is the difference between fr and percentage in CSS Grid?
Percentages are calculated from the container's total width, including gaps. The fr unit distributes the remaining space after fixed sizes, percentages, and gaps are subtracted. This makes fr safer for grids with gaps because it won't cause overflow.
Can I use fr outside of CSS Grid?
No. The fr unit only works inside grid-template-columns and grid-template-rows. It has no effect in Flexbox, width, margin, or any other CSS property.
What is the difference between fr and auto in CSS Grid?
auto sizes a track to fit its content. fr distributes remaining space regardless of content. When used together, auto tracks are calculated first, then fr tracks split whatever space is left.
Why is my fr column wider than expected?
By default, the minimum size of an fr track is auto, which means content can push the column wider than its fractional share. To fix this, use minmax(0, 1fr) instead of 1fr so the column can shrink below its content size.
How does the gap property affect fr values?
Gaps are deducted from the container's available space before fr units are calculated. For example, a 900px container with gap: 30px and 1fr 1fr 1fr gives each column 280px, not 300px, because two 30px gaps total 60px.
Can I use fr inside calc()?
No. The fr unit is a <flex> data type, not a <length>. Writing calc(1fr - 20px) is invalid CSS and will be ignored. If you need a flexible column with a minimum size, use minmax(20px, 1fr) instead.
How many pixels is 1fr?
There's no fixed pixel value. 1fr is a fraction of the remaining space after fixed sizes, percentages, and gaps are subtracted. In a 900px container with one 300px column and two 1fr columns, each 1fr resolves to 300px. Change the container width or the fixed column and the pixel value changes with it.

Summary

I use the fr unit in almost every grid I build. It removes the guesswork of calculating percentages and adapts naturally when you add or remove columns. Mixed with px, auto, and minmax(), it covers most layout needs without a single media query.

If you’re getting started with Grid, the complete guide covers the full picture – tracks, placement, alignment, and more.

Join the Discussion
3 Comments  ]
  • Matt 13 March 2024, 16:50

    Hmm… seems to me there might be an error(s) on the page as the examples don’t seem to be displaying correctly at all, whereas the original post you referenced/translated from (re; alligator, which actually redirects to digitalocean) displays perfectly/as intended.

    Lots of confusion here. ¯\_(ツ)_/¯

    • רועי יוסף 14 March 2024, 0:16

      Hey Matt!

      I appreciate you notifying me about the errors. It’s been fixed!

      All the best 🙂

      • Matt Rock 14 March 2024, 15:15

        Beauty!

        Cheers, Roee

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo