Change grid layout depending on number of elements

Viewed 133

I have a wrapper that can have 1-5 elements.

<div class="wrapper">
  <div class="element"></div>
</div>

I'd like to change the layout in which they're displayed depending on the number of them:

  • 1 element: 1x1, 33.3% width

enter image description here

  • 2 elements: 2x1, 33.3% width

enter image description here

  • 3 elements: 3x1, 33.3% width

enter image description here

  • 4 elements: 2x2, 50% width

enter image description here

  • 5 elements: 3x2, 33.3% width

enter image description here

How can I do this without JavaScript?

This is the Codepen for reference.

body {
  padding: 20px;
}

.wrapper {
  width: 500px;
  padding: 5px 10px;
  margin: 10px 0;
  border: 2px dashed #5f5f5f;
  display: flex;
  flex-wrap: wrap;
}

.element {
  font-family: Helvetica, sans-serif;
  background-color: #ededed;
  flex: 33.3%;
  max-width: 33.3%;
  margin: 10px 0;
}

.wrapper.with-4-elements .element {
  flex: 50%;
  max-width: 50%;
}

.wrapper-with-5-elements .element:nth(4),
.wrapper-with-5-elements .element:nth(5) {
  flex: 50%;
  max-width: 50%;
}
<div class="wrapper with-1-element">
  <div class="element">Element 1</div>
</div>

<div class="wrapper with-2-elements">
  <div class="element">Element 1</div>
  <div class="element">Element 2</div>
</div>

<div class="wrapper with-3-elements">
  <div class="element">Element 1</div>
  <div class="element">Element 2</div>
  <div class="element">Element 3</div>
</div>

<div class="wrapper with-4-elements">
  <div class="element">Element 1</div>
  <div class="element">Element 2</div>
  <div class="element">Element 3</div>
  <div class="element">Element 4</div>
</div>

<div class="wrapper with-5-elements">
  <div class="element">Element 1</div>
  <div class="element">Element 2</div>
  <div class="element">Element 3</div>
  <div class="element">Element 4</div>
  <div class="element">Element 5</div>
</div>

1 Answers

You can do it like below using CSS grid:

.wrapper {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 5px;
  border: 1px solid;
  padding: 10px;
  margin: 10px;
}
.element {
  grid-column: span 2;
  height: 20px;
  background: red;
}
/* the case with 4 elements */
.element:first-child:nth-last-child(4),
.element:first-child:nth-last-child(4) ~ *{
  grid-column: span 3;
}
<div class="wrapper">
  <div class="element"></div>
</div>

<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>

And with flexbox:

.wrapper {
  display: flex;
  flex-wrap: wrap;
  border: 1px solid;
  gap: 5px;
  padding: 10px;
  margin: 10px;
}
.element {
  flex: 0 0 calc((100% - 10px)/3); /* 10px = 2 * gap */
  height: 20px;
  background: red;
}
/* the case with 4 elements */
.element:first-child:nth-last-child(4),
.element:first-child:nth-last-child(4) ~ *{
  flex: 0 0 calc((100% - 5px)/2);
}
<div class="wrapper">
  <div class="element"></div>
</div>

<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>
<div class="wrapper">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</div>

Related