Ali
Ali

Reputation: 267077

Preventing items in a css grid from stretching to fill space

I have a list of 3 buttons I'm trying to display in a grid.

The text of the buttons is dynamic, it could be one word or a full sentence.

I'd like each button's width to be determined thru its content. Make it wide if its a long sentence, keep it small if its 1 word. Example:

example buttons

On larger screens, I want them to show up in 1 row like the above. On smaller screens I want it to move stuff to the next line if there isn't enough width to show them all in 1 row:

responsive example

I've been really struggling with getting this to work, because whenever I set grid on the container, the buttons are stretched horizontally to fill up all the space. Or, they're moved to 1 button per row, and still stretched horizontally all the way.

I've tried setting min-width on everything, I've tried auto-fill / auto-fit and all the different justify and align properties and nothing gives me the result I want.

The solution that's working for me now is to just not use any grids and just set a margin top & right on the buttons themselves, and they're aligning themselves the way I want. But I feel like it should be doable through grids.

Is that possible or is the better solution to not use grids for this?

Upvotes: 8

Views: 10828

Answers (5)

oldboy
oldboy

Reputation: 5954

#grid {
  resize: horizontal;
  overflow: auto;
  display: grid;
  
  /* if only you could replace 150px with fit-content... */
  grid-template-columns: repeat(auto-fit, minmax(150px, auto));
  
max-width: 80%;
border: black solid 2px;
box-sizing: border-box;
}

.items {
  white-space: nowrap;
  max-width: fit-content;
  min-width: fit-content;
background: pink;
border: red solid 2px;
box-sizing: border-box;
}
<div id='grid'>
  <div class='items'>Elephants are cool.</div>
  <div class='items'>Snails are small.</div>
  <div class='items'>Lions</div>
  <div class='items'>Leopards are spotted and spotted in the wild.</div>
</div>

The demo is very close to what you want, but I cannot figure out how to make the track size responsive to each item.

Upvotes: 0

Sudhanshu Sharma
Sudhanshu Sharma

Reputation: 101

try this on button's CSS class

.btn{width:fit-content;}

Upvotes: 10

GaryTsukla
GaryTsukla

Reputation: 103

I found myself struggling with this problem today. I had a button at the end of the grid that was stretching to fill the grid cell, but I didn't want that (it looked really weird).

After I didn't find the answer here, I looked elsewhere and found the answer. So, here it is...

On each item in the grid, you can use align-self:start; and it won't stretch to fill the container. Something like this:

.container > *{
    align-self:start;
}

Source: https://yoksel.github.io/grid-cheatsheet/#section-align-self

Upvotes: 6

JSvanBaaren
JSvanBaaren

Reputation: 1

You could try something like this.

.basic-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr))
}
<section class="basic-grid auto-fit">
  <div class="card">1</div>
  <div class="card">2</div>
  <div class="card">3</div>
  <div class="card">4</div>
</section>

I recommend watching this video to learn a bit more about grids. https://www.youtube.com/watch?v=705XCEruZFs

Upvotes: -1

Cristian Sarghe
Cristian Sarghe

Reputation: 790

Is this not what you want? The elements will not cover the whole space if you do not specify them to do that.

.container {
  display: flex;
  flex-direction: row;
  resize: both;
  width: 300px;
  border: 1px solid blue;
  overflow: auto;
  flex-wrap: wrap;
}

.container > * {
  padding: 5px;
  border: 1px solid green;
  margin: 5px;
  white-space: nowrap;
}
<div class="container">
  <div>First medium</div>
  <div>Second</div>
  <div>Third very large</div>
</div>

Upvotes: 1

Related Questions