-1

I have made this simple example of my current grid setup:

document.querySelectorAll(".element").forEach(box => 
    box.addEventListener("click", () => box.classList.toggle("compressed"))
)
.container{
  display:grid;
  grid-template-columns: repeat(3, min-content);
  grid-template-rows:repeat(3, min-content);
  grid-auto-flow:column;
  gap:1rem;
}

.element{
  background-color:brown;
  border:1px solid black;
  width:10rem;
  height:10rem;
  text-align:center;
  color:white;
  line-height:10rem;
  font-size:2rem;
}

.elementBig{
  grid-row-end: span 2;
   height:21rem;
}

.compressed{
  height:2rem;
}
<div class="container">
<div class="element elementBig">big</div>
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
<div class="element">5</div>
<div class="element">6</div>
<div class="element">7</div>
<div class="element">8</div>
<div class="element">9</div>
<div class="element">10</div>
</div>

when you click on a cell it's reduced but the next one does not rise up: let's say I click on "big" element, I want that "1" to rise up

in addiction i want rows and columns number to be dynamic so in the real grid i'am using this setup:

--n-colonne: 3; //per impostare massimo numero di colonne a 3 su grandi display
    display: grid;
    $larghezza-senza-spazi: calc(100% - (var(--n-colonne) - 1) * 1rem);
    grid-template-columns: repeat(auto-fill, minmax(max(45rem, ($larghezza-senza-spazi)/var(--n-colonne)), 1fr));
    grid-template-rows: repeat(12, min-content);
    grid-gap: 1rem;

that will need some fix if "grid-auto-flow:column" is to be used

Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
gt.guybrush
  • 1,320
  • 3
  • 19
  • 48

1 Answers1

1

The problem you're facing: A grid has rows and rows have a certain height (in your case: min-content, which is 10rem as long as at least one box in the row is not compressed). In addition to that, your big box is supposed to always take up two rows as per your definition (grid-row-end: span 2;), so resizing the content of the grid-cell won't change anything.

Not sure if grid is the way to go here, there might be a solution in the new masonry addition in CSS3. Maybe give this a read: https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

However: If you can settle on a number of cols (or calculate this somehow by using js), just place your boxes accordingly in cols and it works just fine.

document.querySelectorAll(".element").forEach(box =>
  box.addEventListener("click", () => box.classList.toggle("compressed"))
)
.container {
  display: grid;
  grid-template-columns: repeat(3, min-content);
  grid-auto-flow: column;
  gap: 1em;
}

.element {
  background-color: brown;
  border: 1px solid black;
  width: 10rem;
  height: 10rem;
  text-align: center;
  color: white;
  line-height: 10rem;
  font-size: 2rem;
  margin-bottom: 0.5em;
}

.elementBig {
  grid-row-end: span 2;
  height: 21rem;
}

.compressed {
  height: 2rem;
  overflow: hidden;
}
<div class="container">
  <div class="col1">
    <div class="element elementBig">big</div>
    <div class="element">1</div>
  </div>
  <div class="col2">
    <div class="element">2</div>
    <div class="element">3</div>
    <div class="element">4</div>
  </div>

  <div class="col3">
    <div class="element">5</div>
    <div class="element">6</div>
    <div class="element">7</div>
  </div>

  <div class="col4">
    <div class="element">8</div>
    <div class="element">9</div>
    <div class="element">10</div>
  </div>
</div>

If thats not an option, you can always use flexbox, but it comes with its own challenges:

document.querySelectorAll(".element").forEach(box =>
  box.addEventListener("click", () => box.classList.toggle("compressed"))
)
.container {
  display: flex;
  flex-flow: column wrap;
  width: 100%;
  max-height: 800px;
  gap: 1rem;
}

.element {
  background-color: brown;
  border: 1px solid black;
  width: 200px;
  height: 200px;
  text-align: center;
  color: white;
  line-height: 10rem;
  font-size: 2rem;
}

.elementBig {
  height: 21rem;
}

.compressed {
  height: 2rem;
}
<div class="container">
  <div class="element elementBig">big</div>
  <div class="element">1</div>
  <div class="element">2</div>
  <div class="element">3</div>
  <div class="element">4</div>
  <div class="element">5</div>
  <div class="element">6</div>
  <div class="element">7</div>
  <div class="element">8</div>
  <div class="element">9</div>
  <div class="element">10</div>
</div>
rx2347
  • 1,071
  • 1
  • 6
  • 26
  • column should be dynamic and element should not flow from one column to other. maybe Masonry Layout will be the real solution, i have to study it – gt.guybrush Mar 19 '21 at 14:52
  • just use the first example, add your columns and elements in js? done. – rx2347 Mar 22 '21 at 12:24
  • column number are calculated in css, create entire grid in js is not an option: every component are c# partial views generated server time – gt.guybrush Mar 22 '21 at 15:24