6

Let's say we have a list of items, with splitter elements (<h3>), for example dates :

<h2>Big Header</h2>
<div id='container'>
    <h3>Week Title A</h3>
    <span>Day 1</span>
    <span>Day 2</span>
    <span>Day 3</span>
    <span>Day 4</span>
    <span>Day 5</span>
    <span>Day 6</span>
    <span>Day 7</span>
    <h3>Week Title B</h3>
    <span>Day 1</span>
    <span>Day 2</span>
    <span>Day 3</span>
    <span>Day 4</span>
    <span>Day 5</span>
    <span>Day 6</span>
    <span>Day 7</span>
</div>

And lets say we have a CSS style that is applied to Even <span>s, like so:

#container span:nth-of-type(even){
    color: red;
}

This will produce the following output:

   /** layout / setup only **/
   #container {
      background-color: aqua;
      margin:1rem;
      padding:1rem;
   }
   span {
      display:block;
    }


   /** This below is the focus **/
   #container span:nth-of-type(even){
        color: red;
        font-weight:bold;
    }
    <h2>Big Header</h2>
    <div id='container'>
        <h3>Week Title A</h3>
        <span>Day 1</span>
        <span>Day 2</span>
        <span>Day 3</span>
        <span>Day 4</span>
        <span>Day 5</span>
        <span>Day 6</span>
        <span>Day 7</span>
        <h3>Week Title B</h3>
        <span>Day 1 B</span>
        <span>Day 2</span>
        <span>Day 3</span>
        <span>Day 4</span>
        <span>Day 5</span>
        <span>Day 6</span>
        <span>Day 7</span>
    </div>

Now, we see that Week A's, day's 2,4,6 are red - which is intended. But on Week B, the odd numbered days are red. This is not what's required.

Without editing the HTML (which is generated by a third party), can we get the CSS to always colour the even <span>s listed directly after the H3 element?

I have looked at code for :nth-of-type() and can't see a way to do this, and have tried using the CSS + operator which also doesn't do this (eg h3 + span:nth-of-type(even){ ).

Intended result on this example would be that across any weeks, the even numbered days are marked as red.

Also tried:

   #container > h3 ~ span:nth-of-type(even){
        color: red;
        font-weight:bold;
    }

But this doesn't seem to work, perhaps nth-of-type can't target siblings like this?

How can this be achieved? We can not edit the HTML that is sent from a third party.

2
  • Seems similar to stackoverflow.com/questions/50454489/…. I don't think there's a clean CSS only way to do this. Commented Sep 10 at 16:20
  • @j08691 thanks yes this does look similar, but I couldn't find that one when searching for solutions. thanks. Commented Sep 10 at 16:39

1 Answer 1

3

Since you always(?) have one h3 followed by seven span, :nth-child(odd) does the trick:

/** layout / setup only **/
   #container {
      background-color: aqua;
      margin:1rem;
      padding:1rem;
   }
   span {
      display:block;
    }

   #container span:nth-child(odd){
        color: red;
        font-weight:bold;
    }
<h2>Big Header</h2>
    <div id='container'>
        <h3>Week Title A</h3>
        <span>Day 1</span>
        <span>Day 2</span>
        <span>Day 3</span>
        <span>Day 4</span>
        <span>Day 5</span>
        <span>Day 6</span>
        <span>Day 7</span>
        <h3>Week Title B</h3>
        <span>Day 1 B</span>
        <span>Day 2</span>
        <span>Day 3</span>
        <span>Day 4</span>
        <span>Day 5</span>
        <span>Day 6</span>
        <span>Day 7</span>
    </div>

UPDATE:
If the number of "days" will be small, as you said "5-12 rows", you might resort to an uglier, but still pure CSS solution using something like this:

/** layout / setup only **/
#container {
  background-color: aqua;
  margin: 1rem;
  padding: 1rem;
  font-size: 8px;
}

span {
  display: block;
}

#container h3+span+span,
#container h3+span+span+span+span,
#container h3+span+span+span+span+span+span,
#container h3+span+span+span+span+span+span+span+span,
#container h3+span+span+span+span+span+span+span+span+span+span,
#container h3+span+span+span+span+span+span+span+span+span+span+span+span,
#container h3+span+span+span+span+span+span+span+span+span+span+span+span+span+span {
  color: red;
  font-weight: bold;
}
<h2>Big Header</h2>
<div id='container'>
  <h3>Week Title 0</h3>
  <span>Day 1</span>
  <span>Day 2</span>
  <span>Day 3</span>
  <span>Day 4</span>
  <h3>Week Title A</h3>
  <span>Day 1</span>
  <span>Day 2</span>
  <span>Day 3</span>
  <span>Day 4</span>
  <span>Day 5</span>
  <span>Day 6</span>
  <h3>Week Title B</h3>
  <span>Day 1 B</span>
  <span>Day 2</span>
  <span>Day 3</span>
  <span>Day 4</span>
  <span>Day 5</span>
  <span>Day 6</span>
  <span>Day 7</span>
  <span>Day 8</span>
  <span>Day 9</span>
  <span>Day 10</span>
  <span>Day 11</span>
  <span>Day 12</span>
  <span>Day 13</span>
  <span>Day 14</span>
  <span>Day 15</span>
</div>

Sign up to request clarification or add additional context in comments.

7 Comments

But for the first/third/fifth weeks this will change the "odd" days when we want to change only the "even" days. Also worth noting the number of spans in a "set" will be unknown.
If you have one header and seven days, it's eight children total, which is even number. If you multiply an even number by an odd number or an even number you always result with an even number. Therefore odd weeks remain correct. Regarding the unknown number of days in a week, I assumed it's always seven as in your published question. My solution works for any odd number of days.
Yes, but there's no way of being sure there are always going to be 7 spans. there will be X number of Spans between headers.
What would be maximum X then?
Unknown at present. The data is given by a third party and will probably be small numbers, eg 5-12 rows but each "set" (in this example set of "Days" in Weeks) will be different.
Updated my answer to handle 5-15 rows. Ugly and simple =))
[deleted]
[deleted]
Unfortunately, this is not a universal solution. If you just to continue the list a bit, see codepen.io/imhvost/pen/bNVyjqm (pay attention to the end columns). Your previous solution (which you removed for some reason) with double span+span was better.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.