Dan Gamble
Dan Gamble

Reputation: 4155

How to use a CSS grid with percentages and an unknown amount of columns?

This is the layout I'm trying to achieve:

Enter image description here

I'm currently doing it by:

HTML

<div class="ft-Footer_Columns">
  <div class="ft-Footer_Column ft-Footer_Column-about">
    <h4 class="ft-Footer_Title">Title 1</h4>

    <p class="ft-Footer_Text">Text 1</p>
  </div>

  <div class="ft-Footer_Column ft-Footer_Column-links">
    <h4 class="ft-Footer_Title">Title 2</h4>

    <p class="ft-Footer_Text">Text 2</p>
  </div>

  <div class="ft-Footer_Column ft-Footer_Column-contact">
    <h4 class="ft-Footer_Title">Title 3</h4>

    <p class="ft-Footer_Text">Text 3</p>
  </div>
</div>

CSS

.ft-Footer_Columns {    
  display: grid;
  grid-column-gap: calc(20px * 2);
  grid-template-columns: calc(5 / 12)fr calc(4 / 12)fr calc(3 / 12)fr;
}

This seems like quite a hacky way to achieve what I want.

Ideally I want to be able to do:

.ft-Footer_Columns {    
  display: grid;
  grid-column-gap: calc(20px * 2);
  grid-template-columns: calc(5 / 12 * 100%) calc(4 / 12 * 100%) calc(3 / 12 * 100%);
}

But this currently does 100% + ((20px * 2) * 2).

How would I achieve this percentage / fractal based layout without the hacky calc()FR way?

Upvotes: 12

Views: 44584

Answers (2)

Alper OZBEK
Alper OZBEK

Reputation: 89

If you can define a minimum width value to the columns, the following code would be a good solution for establishing equal-width columns without overflow. I defined the value 100px here, but of course, you can change the value as you wish. The browser will try to put all the columns in a row by shrinking the width down to min-width. If there is overflow, it will put the remain columns second row. But the width of the columns would be the same anyway.

`

.ft-Footer_Columns {
    display: grid;
    grid-column-gap:20px;
    grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

`

Upvotes: 3

Michael Benjamin
Michael Benjamin

Reputation: 371063

Since you don't know the number of columns, you don't use the grid-template-columns property. This property defines an explicit grid, meaning the tracks are explicitly defined.

You may be looking for grid-auto-columns. This property defines the width of columns that are automatically created (this would be the implicit grid).

Try this:

grid-auto-columns: 1fr

With the fr unit, only the free space is distributed. This would be the space left after the gutters are factored in.

7.2.3. Flexible Lengths: the fr unit

A flexible length or <flex> is a dimension with the fr unit, which represents a fraction of the free space in the grid container.

free space

Equal to the available grid space minus the sum of the base sizes of all the grid tracks (including gutters), floored at zero. If available grid space is indefinite, the free space is indefinite as well.

Also – when you do have a defined number of columns – since we're dealing with proportions, you could match the fr values to your desired percentages. Something like this:

grid-template-columns: 42fr 33fr 25fr (instead of 42% 33% 25%).

One advantage of using fr here is that the gutter size is automatically deducted (to establish the free space, which is the only space fr uses). With percentages, you need to use calc().

Upvotes: 25

Related Questions