4

I have a CSS grid that is set to auto-fill the columns, to display as many items on a row as will fit.

This is done with: grid-template-columns: repeat(auto-fill, minmax(10em, 1fr));

I would like to be able to resize selected grid items, which I am trying with:

resize: both;
overflow: auto;

This works at a basic level, but the content will overlap/stretch over adjacent grid items when resized horizontally:

Unwanted overlapping behaviour

When resized vertically, the rows below are instead pushed down, so there is no overlap: Wanted resize behaviour

This is the behaviour I want horizontally too.

I understand this is likely to do with using auto-fill for the columns, as when tracks are explicitly defined the stretching works the same on both axes.

.grid {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, 10em);
  /* grid-template-columns: repeat(auto-fill, minmax(10em, 1fr)); */
}

.grid>div {
  background-color: #eeeeff;
  padding: 0.5rem;
}

.resize {
  resize: both;
  overflow: auto;
}
<div class="grid">
  <div class="resize">Resize Me</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
</div>

JSFiddle

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Alfie
  • 2,341
  • 2
  • 28
  • 45
  • You need only in grid only? or is it ok If I use flex? – Manjuboyz Apr 16 '20 at 14:59
  • @Manjuboyz If it works, flex is fine. Ideally the horizontally pushed content will flow to the next rows if possible, rather than increasing the width of the page. – Alfie Apr 16 '20 at 15:01
  • 1
    It works like that because the height is a variable, which means we need a variable width to do the same thing horizontally, this will prevent `auto-fill` from doing what it's doing, In grid you're creating columns/rows which you put your elements, not simply aligning elements. As of now there's no way of targeting those columns/rows. – Rainbow Apr 16 '20 at 16:09

2 Answers2

2

You can use flex to achieve this:

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid>div {
  border: 1px solid red;
  width: 150px;
}

.grid>div {
  background-color: #eeeeff;
  margin: 1em;
  padding: 10px;
}

.resize {
  resize: both;
  overflow: auto;
  border: 1px solid red;
}
<html>

<body>
  <div class="grid">
    <div class="resize">Resize Me</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
    <div>Item</div>
  </div>
</body>

</html>
Manjuboyz
  • 6,978
  • 3
  • 21
  • 43
  • @Alfie as I said in the answer you can do some css to alter positions and size but the actual is working as you seek. Let me know. – Manjuboyz Apr 16 '20 at 15:04
  • I just verified its responsiveness too, it works! let me know if it satisfies your business! – Manjuboyz Apr 16 '20 at 15:09
  • Thanks for the answer, it is nice but not quite what I need. Too much of the grid behaviour is lost which breaks my design (specifically, the minmax() of the column sizes and its scaling when the page is resized). – Alfie Apr 16 '20 at 15:11
  • Hmmmm... the issue what I saw was with `grid-template-columns:` this is making the cells not to move!. – Manjuboyz Apr 16 '20 at 15:24
  • @Alfie check the answer now, I was able to make it clean by giving width to those cells and again move would be same in using `grid` too so you can't expect more that as far as I recall. – Manjuboyz Apr 16 '20 at 15:35
  • Thanks - I have accepted your answer for now as it does technically do what I asked. However, it would be great to see a grid only answer as there are nuances to grid that are much better for my particular needs. – Alfie Apr 16 '20 at 15:54
  • Hi @Manjuboyz, Is it possible to achive the same result with css Grid (While Resizing should not affect another div block) – Hasansab Takked May 25 '22 at 09:20
1

The way you have it defined, the resize works on the items, but not on the column tracks. That's why you're seeing the overlap when resizing horizontally. The columns are fixed in place, based on the grid-template-columns rule 1.

The only way to make the column tracks resize with the items would be if the columns were set to auto (content-based sizing), but this cannot co-exist with auto-fill or auto-fit2.

You don't have this resizing problem in the vertical direction because you haven't defined any rows. Therefore, the grid defaults to grid-auto-rows: auto (again, content-based sizing), and the items and row tracks resize in harmony.

But since you want horizontal wrapping, you can't use this technique for the columns. It's clearly a limitation in grid layout.

Try flexbox instead, which isn't a great alternative in this case (especially because it still doesn't support the gap property3), but it may get you a step closer to your goal.

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid > div {
  width: 10em;
  margin: 5px;
  background-color: #ccc;
  padding: 0.5rem;
}

.resize {
  resize: both;
  overflow: auto;
  border: 1px solid red;
}
<div class="grid">
  <div class="resize">Resize Me</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
  <div>Item</div>
</div>

jsFiddle demo

References:

  1. Aligning grid items across the entire row/column (like flex items can)
  2. Why doesn't min-content work with auto-fill or auto-fit?
  3. How to set gaps (gutters) in a flex container?, Setting distance between flex items
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701