1

I need to create the grid items shown as in the image attached. First Item need to be of 45% and second and third Item need to be 52.5%, and rest items need to be of 50% each. I can not change the HTML as all the grid child coming from a Loop. So I am not able to achieve it by the CSS written, check snippet, By my css its only possible to have the width of left side all items 50%, or 45%, but how to change the width of items from 4 to rest of the items.

Is it possible without changing the HTML?

enter image description here

.atul {
  display: grid;
  grid-template-columns: 45% 52.5%;
  grid-template-rows: auto;
  grid-gap: 2.5%;
  grid-template-areas: "card1 card2" 
                       "card1 card3";
}

.card:nth-child(1) {
  grid-area: card1;
}

.card:nth-child(2) {
  grid-area: card2;
}

.card:nth-child(3) {
  grid-area: card3;
}
<div class="atul">
  <div class="card" style="background-color: red;">Card 1</div>
  <div class="card" style="background-color: green;">Card 2</div>
  <div class="card" style="background-color: yellow;">Card 3</div>
  <div class="card" style="background-color: skyblue;">Card 4</div>
  <div class="card" style="background-color: skyblue;">Card 5</div>
  <div class="card" style="background-color: skyblue;">Card 6</div>
  <div class="card" style="background-color: skyblue;">Card 7</div>
  <div class="card" style="background-color: skyblue;">Card 8</div>
  <div class="card" style="background-color: skyblue;">Card 9</div>
  <div class="card" style="background-color: skyblue;">Card 10</div>
  <div class="card" style="background-color: skyblue;">Card 11</div>
  <div class="card" style="background-color: skyblue;">Card 12</div>
  <div class="card" style="background-color: skyblue;">Card 13</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Atul Rajput
  • 4,073
  • 2
  • 12
  • 24

1 Answers1

4

To make this work you need to find a common divider for all three lengths (42.5%, 48.75% and 52.5%). With a common divider you can create the right number of columns to accommodate each grid area.

In my example below, I created 400 columns of .25% width each (400 * .25 = 100%).

It then spanned grid areas across the correct number of columns:

45.00 / .25 = 180

48.75 / .25 = 195

52.50 / .25 = 210

It may not be exactly what you're looking for, but hopefully the concept helps you move forward.

No changes to the HTML.

.atul {
  display: grid;
  grid-template-columns: repeat(400, .25%);
  grid-auto-rows: 50px; /* for demo only */
  grid-row-gap: 30px;   /* note that you need to create column gaps through
                           the proper distribution of columns, because if you
                           use `grid-column-gap`, it will add a gap between
                           all 400 columns */
}

.card:nth-child(1) {
  grid-column: 1 / 180;
  grid-row: 1 / 3;
}

.card:nth-child(2) {
  grid-column: -1 / -210; /* starting at the end line of the grid
                             (works only in explicit grids) */
  grid-row: 1 / 2;
}

.card:nth-child(3) {
  grid-column: -1 / -210;
  grid-row: 2 / 3;
}

/* starting at the 4th item, target even items only */
.card:nth-child(n + 4):nth-child(even) {
  grid-column: 1 / 195;
}

.card:nth-child(n + 4):nth-child(odd) {
  grid-column: -1 / -195;
}

.card:nth-child(4),
.card:nth-child(5) {
  grid-row: 3;
}

.card:nth-child(6),
.card:nth-child(7) {
  grid-row: 4;
}

.card:nth-child(8),
.card:nth-child(9) {
  grid-row: 5;
}

.card:nth-child(10),
.card:nth-child(11) {
  grid-row: 6;
}

.card:nth-child(12),
.card:nth-child(13) {
  grid-row: 7;
}
<div class="atul">
  <div class="card" style="background-color: red;">Card 1</div>
  <div class="card" style="background-color: green;">Card 2</div>
  <div class="card" style="background-color: yellow;">Card 3</div>
  <div class="card" style="background-color: skyblue;">Card 4</div>
  <div class="card" style="background-color: skyblue;">Card 5</div>
  <div class="card" style="background-color: skyblue;">Card 6</div>
  <div class="card" style="background-color: skyblue;">Card 7</div>
  <div class="card" style="background-color: skyblue;">Card 8</div>
  <div class="card" style="background-color: skyblue;">Card 9</div>
  <div class="card" style="background-color: skyblue;">Card 10</div>
  <div class="card" style="background-color: skyblue;">Card 11</div>
  <div class="card" style="background-color: skyblue;">Card 12</div>
  <div class="card" style="background-color: skyblue;">Card 13</div>
</div>

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    This is something like out of the box, Perfect, Thanks a ton. I have seen your SO account, you have a fan now :) – Atul Rajput Apr 13 '20 at 17:48
  • what grid-column: -1 / -210; this minus number does here, is it starts from the end of the grid container, something like flex-end – Atul Rajput Apr 13 '20 at 17:57
  • Yes. The count starts from the last line in the grid. https://stackoverflow.com/q/57268090/3597276 – Michael Benjamin Apr 13 '20 at 17:58
  • Just one last question, When I was using the grid-gap: 2.5% in my old example, I had a wrapper of class atul and background color on it, the grid items were going outside that parent wrapper. Don't know why this was happening. I hope I can make you understand what was the problem. I just want to understand why that was happening? – Atul Rajput Apr 13 '20 at 18:06
  • 1
    You have no height set on the container. So the browser calculates: (1) the height of the items, then (2) the height of the container, and then (3) adds the grid row gaps. Because the height of the container is set before the grid row gaps are factored in, there is an overflow. If you remove the grid gap rule you'll see everything fits nicely. – Michael Benjamin Apr 13 '20 at 18:15
  • Set a height on the container, and the problem is resolved (as long as the height of the container is larger than the sum of the content and gaps). https://jsfiddle.net/7rtk6dy9/1/ – Michael Benjamin Apr 13 '20 at 18:17