Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between percentage and fr units

Tags:

css

css-grid

I am playing around with CSS Grid Layout and came across a question I cannot find an answer for.

Consider the following example:

:root {    --grid-columns: 12;    --column-gap: 10px;    --row-gap: 10px;  }    .grid {    display: grid;    grid-template-columns: repeat(var(--grid-columns), calc(100% / var(--grid-columns)));    grid-column-gap: var(--column-gap);    grid-row-gap: var(--row-gap);    justify-content: center;		  }     [class*=l-] {    border: 1px solid red;  }    .l-1 {    grid-column-start: span 1;		  }    .l-2 {    grid-column-start: span 2;  }    .l-3 {    grid-column-start: span 3;  }    .l-4 {    grid-column-start: span 4;  }    .l-5 {    grid-column-start: span 5;  }    .l-6 {    grid-column-start: span 6;  }    .l-7 {    grid-column-start: span 7;  }    .l-8 {    grid-column-start: span 8;  }    .l-9 {    grid-column-start: span 9;  }    .l-10 {    grid-column-start: span 10;  }    .l-11 {    grid-column-start: span 11;  }    .l-12 {    grid-column-start: span 12;  }
<div class="grid">    <div class="l-6">Column 1</div>    <div class="l-6">Column 2</div>    <div class="l-3">Column 3</div>    <div class="l-4">Column 4</div>    <div class="l-3">Column 5</div>			    <div class="l-2">Column 6</div>    <div class="l-1">Column 7</div>    <div class="l-10">Column 8</div>    <div class="l-1">Column 9</div>    <div class="l-5">Column 10</div>    <div class="l-5">Column 11</div>    <div class="l-2">Column 12</div>  </div>

As you can see the columns go out of the screen width because of the percentage width set with calc(100% / var(--grid-columns)).

But if I use fr units, it works perfectly:

:root {    --grid-columns: 12;    --column-gap: 10px;    --row-gap: 10px;  }    .grid {    display: grid;    grid-template-columns: repeat(var(--grid-columns), 1fr);     grid-column-gap: var(--column-gap);    grid-row-gap: var(--row-gap);    justify-content: center;		  }    [class*=l-] {    border: 1px solid red;  }    .l-1 {    grid-column-start: span 1;		  }    .l-2 {    grid-column-start: span 2;  }    .l-3 {    grid-column-start: span 3;  }    .l-4 {    grid-column-start: span 4;  }    .l-5 {    grid-column-start: span 5;  }    .l-6 {    grid-column-start: span 6;  }    .l-7 {    grid-column-start: span 7;  }    .l-8 {    grid-column-start: span 8;  }    .l-9 {    grid-column-start: span 9;  }    .l-10 {    grid-column-start: span 10;  }    .l-11 {    grid-column-start: span 11;  }    .l-12 {    grid-column-start: span 12;  }
<div class="grid">    <div class="l-6">Column 1</div>    <div class="l-6">Column 2</div>    <div class="l-3">Column 3</div>    <div class="l-4">Column 4</div>    <div class="l-3">Column 5</div>			    <div class="l-2">Column 6</div>    <div class="l-1">Column 7</div>    <div class="l-10">Column 8</div>    <div class="l-1">Column 9</div>    <div class="l-5">Column 10</div>    <div class="l-5">Column 11</div>    <div class="l-2">Column 12</div>  </div>

The resources used to find an answer:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns

  • https://css-tricks.com/snippets/css/complete-guide-grid/

  • https://www.w3.org/TR/css-grid-1/

Would be great if anyone could explain why the percentage widths make such a difference.

like image 929
Morpheus Avatar asked Jul 13 '17 20:07

Morpheus


People also ask

What is the FR unit?

Thankfully, CSS Grid Layout introduces a new unit of length called fr, which is short for “fraction”. MDN defines the fr unit as a unit which represents a fraction of the available space in the grid container.

What is an FR value?

FR Value means the official closing level of the Reference Item on the Redemption Valuation Date divided by the official closing level of the Index on the Strike Date (expressed as a percentage)

How does FR unit work?

Fr units calculates based on available space. First it will deduct the grid gap from total width and then calculate the proportion. grid-gap: 20px; To avoid this we need to deduct the size of grid-gap from the columns.

What is Fr measurement CSS?

Fr is a fractional unit and 1fr is for 1 part of the available space. The following are a few examples of the fr unit at work. The grid items in these examples are placed onto the grid with grid areas.


1 Answers

fr

The fr unit works only with the free space in the container.

So in your code:

grid-template-columns: repeat(12, 1fr); 

... the free space in the container is distributed equally among 12 columns.

Since the columns are only dealing with free space, grid-column-gap is not a factor. It was subtracted from the container width before the fr length was determined (spec reference).

Here's how the browser does the calculation:

(free space - gutters) / 12  = 1fr 

%

When you're using percentages...

grid-template-columns: repeat(12, calc(100% / 12)); 

... the container is divided into 12 columns, each having a width of 8.33333%. This is an actual length, unlike the fr unit, which only deals with free space.

Both the column lengths and grid gaps are factored into the width.

Here's how the browser does the calculation:

8.33333% * 12 = 100%          + 11 * 10px     = 110px 

There's a clear overflow.

(Note: grid-*-gap properties apply only between grid items – never between items and the container. That's why the number of grid-gaps is 11, not 13.)

This works:

grid-template-columns: repeat(12, calc(8.3333% - 9.1667px)); 

Which breaks down to this:

  • 12 columns

  • the width of each column is determined by taking the full width of the container (100%) and dividing it by 12

    100% / 12 = 8.3333% (individual column width) 
  • then subtract the column gaps (there are 11)

     10px * 11 = 110px (total width of column gaps)  110px / 12 = 9.1667px (amount to be deducted from each column) 

.grid {    display: grid;    grid-template-columns: repeat(12, calc(8.3333% - 9.1667px));    grid-column-gap: 10px;    grid-row-gap: 10px;    justify-content: center;  }    .l-1 { grid-column-start: span 1; }  .l-2 { grid-column-start: span 2; }  .l-3 { grid-column-start: span 3; }  .l-4 { grid-column-start: span 4; }  .l-5 { grid-column-start: span 5; }  .l-6 { grid-column-start: span 6; }  .l-7 { grid-column-start: span 7; }  .l-8 { grid-column-start: span 8; }  .l-9 { grid-column-start: span 9; }  .l-10 { grid-column-start: span 10; }  .l-11 { grid-column-start: span 11; }  .l-12 { grid-column-start: span 12; }  [class*=l-] { border: 1px solid red; }
<div class="grid">    <div class="l-6">Column 1</div>    <div class="l-6">Column 2</div>    <div class="l-3">Column 3</div>    <div class="l-4">Column 4</div>    <div class="l-3">Column 5</div>    <div class="l-2">Column 6</div>    <div class="l-1">Column 7</div>    <div class="l-10">Column 8</div>    <div class="l-1">Column 9</div>    <div class="l-5">Column 10</div>    <div class="l-5">Column 11</div>    <div class="l-2">Column 12</div>  </div>
like image 67
Michael Benjamin Avatar answered Oct 04 '22 10:10

Michael Benjamin