0

Is it possible to alternately color flexbox rows with pure CSS?

With the code below, I'm able to use nth-child to alternately color individual flex items. Is there a way to alternately color the virtual flex rows created by the CSS flex using pure CSS?

I'm giving my flex items here a fixed height and width, but in reality they could be any size.

.flexbox{
display:flex;
flex-wrap: wrap;
width: 600px;
}

.flex-item{
border: 1px solid black;
height: 150px;
width:150px;
}

.flex-item:nth-child(odd){
background-color: #ddd;
}

.flex-item:nth-child(2n - 1){
height:200px;
}
<div class="flexbox">
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
</div>
caitlin
  • 2,769
  • 4
  • 29
  • 65
  • 1
    Unrelated to the question but useful, if you use outline instead of border then the ’borders’ of each box will overlap, so two boxes side-by-side have a single 1px line. They don’t add to width calculations either :) – Ric May 10 '19 at 08:13

1 Answers1

3

Use repeating-linear-gradient on the main container:

.flexbox {
  display: flex;
  flex-wrap: wrap;
  max-width: 600px;
  background:
    repeating-linear-gradient(to bottom,red 0 150px,blue 150px 300px);
}

.flex-item {
  border: 1px solid black;
  height: 150px;
  width: 150px;
  box-sizing:border-box;
}
<div class="flexbox">
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
</div>

If the height of the elements is unknown here is a bad hack that allow you to have different coloration but as a derivation from the same color.

This hack rely on the fact that element are aligned at the top.

.flexbox {
  display: flex;
  flex-wrap: wrap;
  overflow:hidden;
  position:relative;
  z-index:0;
  background:rgba(255,0,0,0.2);
}


.flex-item {
  border: 2px solid black;
  width: 150px;
  box-sizing:border-box;
  position:relative;
}
.flex-item:before {
  content:"";
  position:absolute;
  z-index:-1;
  left:-2px;
  right:-2px;
  bottom:100%;
  height:300vh;
  background:rgba(255,0,0,0.2);
}
.flex-item:last-child:before {
  right:-200vw;
}
<div class="flexbox">
  <div class="flex-item" style="height:50px;"></div>
  <div class="flex-item" style="height:80px;"></div>
  <div class="flex-item" style="height:150px;"></div>
  <div class="flex-item" style="height:110px;"></div>
  <div class="flex-item" style="height:120px;"></div>
  <div class="flex-item" style="height:90px;"></div>
  <div class="flex-item" style="height:100px;"></div>
  <div class="flex-item" style="height:130px;"></div>
  <div class="flex-item" style="height:150px;"></div>
</div>

There is a small drawback due to wrapping but if the width is fixed it should work fine.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415