CSS div alternating colour

CssHtmlZebra Striping

Css Problem Overview


I'm trying to zebra stripe my divs in my website, sounds simple enough, however I've found that when I added a header in between the rows of my divs it seems to count the header in the odd/even styling

HTML

<div class="container">
    <h3>Title</h3>
    <div class="row">Content</div>
    <div class="row">Content</div>
    <h3>Title</h3>
    <div class="row">Content</div>
    <div class="row">Content</div>
    <div class="row">Content</div>
    <h3>Title</h3>
    <div class="row">Content</div>
    <div class="row">Content</div>
    <div class="row">Content</div>
    <div class="row">Content</div>
</div>

CSS

.container {
    width:600px;
    margin:0 auto;
}

.row {
    line-height:24pt;
    border: solid 1px black;
}

.row:nth-child(odd) {
    background: #e0e0e0;
}

h3 {
    line-height:36pt;
    font-weight:bold;
    color:blue;
}

fiddle

I would have thought that the code already in the fiddle would basically ignore the header and carry on striping, but it appears that it considers the header as a child

Css Solutions


Solution 1 - Css

Don't use nth-child, use nth-of-type

div.container > div:nth-of-type(odd) {
    background: #e0e0e0;
}

.container {
  width: 600px;
  margin: 0 auto;
}

.row {
  line-height: 24pt;
  border: solid 1px black;
}

div.container>div:nth-of-type(odd) {
  background: #e0e0e0;
}

h3 {
  line-height: 36pt;
  font-weight: bold;
  color: blue;
}

<div class="container">
  <h3>Title</h3>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <h3>Title</h3>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <h3>Title</h3>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <h3>Title</h3>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
  <div class="row">Content</div>
</div>

Solution 2 - Css

You probably want to match on type, not child.

Use :nth-of-type such as

.row:nth-of-type(odd) {
    background: #e0e0e0;
}

Solution 3 - Css

The easiest solution is of course just to wrap the elements you want striped.

Your updated jsFiddle.

HTML

<div class="container">
    <h3>Title</h3>
    <div class="zebra">
        <div class="row">Content</div>
        <div class="row">Content</div>
    </div>
    <h3>Title</h3>
    <div class="zebra">
        <div class="row">Content</div>
        <div class="row">Content</div>
        <div class="row">Content</div>
    </div>
    <h3>Title</h3>
    <div class="zebra">
        <div class="row">Content</div>
        <div class="row">Content</div>
        <div class="row">Content</div>
        <div class="row">Content</div>
    </div>
</div>

CSS

.row:nth-child(odd) {background: #e0e0e0;}

Bear in mind also that if browser support is important to you, you might want to generate additional classes for zebra-striping server side instead.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrew MorrisView Question on Stackoverflow
Solution 1 - Cssj08691View Answer on Stackoverflow
Solution 2 - CssRoger LindsjöView Answer on Stackoverflow
Solution 3 - CssJezen ThomasView Answer on Stackoverflow