Robert C
Robert C

Reputation: 806

CSS Grid, Auto Fill + Widths Set By Content

I want each button to retain its unique width (currently based on text width), and for the buttons to automatically be placed in the next row when there's no more room horizontally.

Using grid-auto-flow: column allows for the buttons to retain their width, but then they do not wrap. Using grid-template-columns: repeat(auto-fill, minmax(1rem, 15rem)) allows them to wrap, but then they lose their individual widths.

Codesandbox: https://codesandbox.io/s/jovial-shannon-btp3x?file=/src/styles.css

.grid {
  margin-top: 1rem;
  margin-left: 0.1rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(1rem, 11.3rem));
  max-width: 100%;
  grid-row-gap: 2.5rem;
  grid-column-gap: 2.5rem;
}

.button {
  padding: 1rem;
  outline: 1px solid rgba(110, 110, 110, 0.34);
  color: white;
  background-color: #1d1f1f;
  font-family: Calibri;
  font-size: 1.4rem;
  font-weight: bold;
}
<div class="grid">
  <button class="button">
        <span class="button-text">
          ab
        </span>
      </button>
  <button class="button">
        <span class="button-text">
          abcd
        </span>
      </button>
  <button class="button">
        <span class="button-text">
          abcdefg
        </span>
      </button>
  <button class="button">
        <span class="button-text">
          abcdefghij
        </span>
      </button>
  <button class="button">
        <span class="button-text">
          abcdefghijklm
        </span>
      </button>
  <button class="button">
        <span class="button-text">
          abcdefghijklmnop
        </span>
      </button>
</div>

Upvotes: 5

Views: 5468

Answers (2)

weo3dev
weo3dev

Reputation: 329

What you are looking for is "grid-auto-flow" which can be set to column or row. For a quick visual reference, MDN's page is a good one.

CSS Grid is meant as a layout tool, much like we had for print materials way back before the internet. Columns do not need to be the same width and rows, likewise, do not have to be the same height. In fact, CSS Grid is literally the layout tool we were hoping to have two decades ago because laying things out on a rigid every-column-is-the-same-width foundation gets redundant and boring.

Furthermore, CSS grid allows things like overlap, media-query-less layout adjustments and auto placement, and I could go on and on.

Bonus tip: look up grid areas. Read about them here.

Upvotes: 0

Michael Benjamin
Michael Benjamin

Reputation: 371073

I want each button to retain its unique width (currently based on text width), and for the buttons to automatically be placed in the next row when there's no more room horizontally.

Using grid-template-columns: repeat(auto-fill, minmax(1rem, 15rem)) allows them to wrap, but then they lose their individual widths.

Well, the buttons are contained within columns. And columns (like rows) have fixed lengths across the grid container.

It appears that what you're actually requesting is flexible column lengths that would adjust to fit the varying widths of their cells. That wouldn't be a grid and, therefore, is not possible in grid layout.

Here's an illustration of what I'm saying:

enter image description here

A grid is a matrix of intersecting fixed-width columns and fixed-height rows. You can adjust the width of the buttons within their tracks, but that would only lead to unsightly gaps between them.


Using grid-auto-flow: column allows for the buttons to retain their width, but then they do not wrap.

Yes, because with grid-auto-flow: column (and no defined rows), all buttons exist in a single row and have their own column.

enter image description here

To your second point, they have no reason to wrap without auto-fill or auto-fit, and even if they could, you would then encounter the same problem described in the previous section.


Consider flexbox, which isn't limited by column and row tracks. Although you'll need to hack your way to gutters, as the gap properties with flex are currently supported in Firefox only.

.grid {
  display: flex;
  flex-wrap: wrap;
  row-gap: 2.5rem;     /* FF only */
  column-gap: 2.5rem;  /* FF only */
}

.button {
  max-width: 11.3rem;
  min-width: 1rem;
  padding: 1rem;
  outline: 1px solid rgba(110, 110, 110, 0.34);
  color: white;
  background-color: #1d1f1f;
  font-family: Calibri;
  font-size: 1.4rem;
  font-weight: bold;
}
<div class="grid">
  <button class="button">
    <span class="button-text">
      ab
    </span>
  </button>
  <button class="button">
    <span class="button-text">
      abcd
    </span>
  </button>
  <button class="button">
    <span class="button-text">
      abcdefg
    </span>
  </button>
  <button class="button">
    <span class="button-text">
      abcdefghij
    </span>
  </button>
  <button class="button">
    <span class="button-text">
      abcdefghijklm
    </span>
  </button>
  <button class="button">
    <span class="button-text">
      abcdefghijklmnop
    </span>
  </button>
</div>

jsFiddle demo

Upvotes: 1

Related Questions