Nick Frost
Nick Frost

Reputation: 37

CSS grid with varying number of elements per row

To make it short; this is what I want my grid to look like:

❌⏹️⏹️❌
⏹️⏹️⏹️⏹️
⏹️⏹️⏹️⏹️
❌⏹️⏹️(❌)

So the second child starts at pos 2, the third wraps to the second row. Same in the last row. This is in one container. I thought about giving every row a container with different grid-template-colums but I try to avoid that because the style for every box is a bit randomized.

Has anyone an Idea? I tried grid-column-start and -end in combination with nth-child and nth-last-child but its not what I'm expecting.

Here is a Codepen to play with: https://codepen.io/nchlsschndr/pen/NWdvjoj

Upvotes: 2

Views: 2097

Answers (3)

Temani Afif
Temani Afif

Reputation: 272648

Simply use

.container :first-child {
  grid-column:2; /* first one start at second row */
}
/* before will fill the top right corner*/
.container::before {
  content:"";
  grid-column:4;
  grid-row:1;
}
/* after will fill the bottom left one */
.container::after {
  content:"";
  grid-row:4;
  grid-column:1;
}

Full code

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  max-width: 500px;
  margin: 0 auto;
  border-radius: 35%;
  background-color: green;
}
.container :first-child {
  grid-column:2;
}
.container::before {
  content:"";
  grid-column:4;
  grid-row:1;
}
.container::after {
  content:"";
  grid-row:4;
  grid-column:1;
}

.box {
  height: 100px;
  margin: -3px;
  border-radius: 20%;
  background-color: darkgreen;
  border: 1px solid black;
}
.box:nth-child(1) {
  transform: translate(2px, 4px) rotate(9deg);
}
.box:nth-child(2) {
  transform: translate(3px, -1px) rotate(4deg);
}
.box:nth-child(3) {
  transform: translate(2px, -4px) rotate(-4deg);
}
.box:nth-child(4) {
  transform: translate(-4px, -2px) rotate(1deg);
}
.box:nth-child(5) {
  transform: translate(-3px, -2px) rotate(8deg);
}
.box:nth-child(6) {
  transform: translate(-2px, -2px) rotate(4deg);
}
.box:nth-child(7) {
  transform: translate(-1px, -4px) rotate(-7deg);
}
.box:nth-child(8) {
  transform: translate(2px, -2px) rotate(10deg);
}
.box:nth-child(9) {
  transform: translate(2px, -1px) rotate(-4deg);
}
.box:nth-child(10) {
  transform: translate(-1px, -2px) rotate(2deg);
}
.box:nth-child(11) {
  transform: translate(-3px, 3px) rotate(2deg);
}
.box:nth-child(12) {
  transform: translate(-4px, -2px) rotate(8deg);
}
.box:nth-child(13) {
  transform: translate(2px, 4px) rotate(4deg);
}
.box:nth-child(14) {
  transform: translate(3px, -4px) rotate(-8deg);
}
.box:nth-child(15) {
  transform: translate(-3px, 4px) rotate(-4deg);
}
.box:nth-child(16) {
  transform: translate(-4px, -4px) rotate(2deg);
}
.box:nth-last-child(1) {
  background-color: red;
}
<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

Upvotes: 1

ciekals11
ciekals11

Reputation: 2155

invisible spacers, change from grid to flex and use of order did the trick. With manipulation on order you can make it responsive as well.
order on MDN

.container {
    display: flex;
    flex-wrap: wrap;
    max-width: 500px;
    margin: 0 auto;
    border-radius: 35%;
    background-color: green;
}

span.spacer {
    flex: 0 0 25%;
    max-width: 25%;
    height: 100px;
}

div.box {
    flex: 0 0 25%;
    max-width: 25%;
    height: 100px;
    margin: -3px;
    border-radius: 20%;
    background-color: darkgreen;
    border: 1px solid black;
}

.spacer:nth-of-type(1) {
    order: 1;
}

.box:nth-of-type(1) {
    order: 2;
    transform: translate(1px, 2px) rotate(1deg);
}

.box:nth-of-type(2) {
    order: 3;
    transform: translate(-2px, 0px) rotate(-5deg);
}

.spacer:nth-of-type(2) {
    order: 4;
}

.box:nth-of-type(3) {
    order: 5;
    transform: translate(4px, -4px) rotate(4deg);
}

.box:nth-of-type(4) {
    order: 6;
    transform: translate(-3px, 0px) rotate(9deg);
}

.box:nth-of-type(5) {
    order: 7;
    transform: translate(2px, 5px) rotate(-3deg);
}

.box:nth-of-type(6) {
    order: 8;
    transform: translate(2px, 4px) rotate(-1deg);
}

.box:nth-of-type(7) {
    order: 9;
    transform: translate(4px, 3px) rotate(-9deg);
}

.box:nth-of-type(8) {
    order: 10;
    transform: translate(-2px, 4px) rotate(-2deg);
}

.box:nth-of-type(9) {
    order: 11;
    transform: translate(-2px, -2px) rotate(1deg);
}

.box:nth-of-type(10) {
    order: 12;
    transform: translate(-2px, -1px) rotate(10deg);
}

.spacer:nth-of-type(3) {
    order: 13;
}

.box:nth-of-type(11) {
    order: 14;
    transform: translate(-4px, 0px) rotate(-2deg);
}

.box:nth-of-type(12) {
    order: 15;
    transform: translate(3px, -3px) rotate(-4deg);
}

.spacer:nth-of-type(4) {
    order: 16;
}

.box:nth-last-child(1) {
    background-color: red;
}
<div class="container">
    <span class="spacer"></span>
    <span class="spacer"></span>
    <span class="spacer"></span>
    <span class="spacer"></span>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</div>

Upvotes: 2

Bobby Mannino
Bobby Mannino

Reputation: 256

<html>
    <div id="grid">
        <div></div>
        <div class="block"></div>
        <div class="block"></div>
        <div></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div></div>
        <div class="block"></div>
        <div class="block"></div>
        <div></div>
    </div>
</html>

<style>
    #grid {
        display: grid;
        width: 200px;
        height: 200px;
        gap: 2px;
        grid-template-columns: repeat(4, minmax(0px, auto));
    }
    .block {
        background: linear-gradient(60deg, red, blue);
        border-radius: 2px;
    }
</style>

I believe this should do what you are asking for, even though you wanted to avoid the grid-template-columns they will auto fit to content as long as there's some in each div

Upvotes: 1

Related Questions