76

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

Andrew Morris
  • 1,602
  • 3
  • 14
  • 26

3 Answers3

138

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>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • 2
    Note that this "continues" counting right through titles; if you want to "reset" the counter (e.g. so that the first row after a title is always white), you'll need to use Jezen's solution. – Eamon Nerbonne Feb 21 '13 at 14:45
  • 1
    @j08691 May I know why it's best to use nth-of-type rather than nth-child? Just curious. – Musikero31 Feb 27 '18 at 03:01
  • 2
    @Musikero31 Because in this question, `nth-child` would count divs *and* h3 elements since they're all children of the parent div container. By using `nth-of-type` on the div in the selector you're effectively filtering out the h3 elements. – j08691 Feb 27 '18 at 13:33
11

You probably want to match on type, not child.

Use :nth-of-type such as

.row:nth-of-type(odd) {
    background: #e0e0e0;
}
Roger Lindsjö
  • 11,330
  • 1
  • 42
  • 53
6

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.

Jezen Thomas
  • 13,619
  • 6
  • 53
  • 91
  • this is inefficient if he wanted to add more or use this for a comment system to make it easier to see separate comments...what he wants should be dynamic – Ilan Biala Feb 21 '13 at 14:33
  • There's no reason why this couldn't be dynamic. – Jezen Thomas Feb 21 '13 at 15:03
  • the wrapping elements with a container and applying css to that container's class is inefficient, not the nth child method. – Ilan Biala Feb 24 '13 at 01:40
  • What the hell are you talking about? First you assert my method isn't dynamic, which is plain incorrect; now you say my method is less efficient. Technically, that may or may not be true, but it is in any case on such a small scale as to make it almost completely unimportant. – Jezen Thomas Feb 24 '13 at 01:53
  • 1
    You are saying to manually wrap every other set, which if he wants to use this for stuff with more than three things and may expand it, is completely inefficient and out of the question. I don't see why you disagree... – Ilan Biala Feb 24 '13 at 01:54