Morten Hjort
Morten Hjort

Reputation: 1012

Select nth-child in pairs (repeating pattern)?

I'm trying to build a grid that has divs whose width follow a specific pattern. In the grid the first 3 divs should have their width as 33.333%, the next 2 should have width as 50%, the next 3 again width: 33.3333% followed by next 2 with width: 50% and so on (infinite).

The CSS3 nth-child seems like a good fit for this, but no matter what I do, it screws up as the numbering because I am having to use :nth-child two times. This must be solvable in a smartly CSS manner? Is there a way that I can assign width based on this pattern without having to manually set the width for each individual div one by one?

Upvotes: 2

Views: 2000

Answers (1)

Harry
Harry

Reputation: 89760

Judging by your question, it seems like out of every 5 elements you need the first 3 to have width as 33.33% and the next two to have width as 50%.

So, you should use the nth-child with multiplier as 5n. The first three elements in every set of five would then be 5n-4, 5n-3, 5n-2 whereas the next two would be 5n-1 and 5n. Using these in the nth-child selector like in the below snippet would achieve what you are looking for.

div {
  float: left;
  height: 50px;
  border: 1px solid;
}
div:nth-child(5n-4),
div:nth-child(5n-3),
div:nth-child(5n-2) {
  width: 33.33%;
}
div:nth-child(5n-1),
div:nth-child(5n) {
  width: 50%;
}
* {
  box-sizing: border-box;
}
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

As pointed out by Abhitalks in comments, this could be further simplified by setting one of the width as default for all div elements and then overriding it. For example, we could set width: 33.33% as default for all div elements and then override it to width: 50% for just 5n and 5n-1 alone.

div {
  float: left;
  height: 50px;
  width: 33.33%;
  border: 1px solid;
}
div:nth-child(5n-1),
div:nth-child(5n) {
  width: 50%;
}
* {
  box-sizing: border-box;
}
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

Upvotes: 6

Related Questions