3

Problem:

I want to select all the red boxes that are consecutive and change its background color to yellow. But css applied is not working.

Expected result:

2nd red box should turn to yellow.

What I have tried:

I have tried to use + operator to select elements that are consecutive to each other, but it does not give me expected results.

This is the exact code that I use to select consecutive elements that are 1 level deep:

ul li > div.red + ul li > div.red {
  background: yellow;
}

My code:

Here is the code sandbox: https://codesandbox.io/s/divine-wave-1bjmp?file=/main.css

ul {
  list-style-type: none;
}

ul li>div {
  height: 100px;
  width: 100px;
  border: 1px solid black;
  margin: 20px;
}

ul li>div.red {
  background: red;
}

ul li>div.green {
  background: green;
}

ul li>div.red+ul li>div.red {
  background: yellow;
}
<ul>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="green" />
  </li>
  <li>
    <div class="red" />
  </li>
</ul>

Notes:

I am not allowed to make any changes to HTML. This problem should be solved using pure css.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Vishal
  • 6,238
  • 10
  • 82
  • 158

2 Answers2

3

Actually, it's impossible to solve this problem in pure CSS. In fact, there is a CSS relational pseudo-class who could help: :has(). Using it, you could apply the following selector:

ul li:has(div.red) + li > div.red

However, the :has() pseudo-class is not supported in any browser, as you can see in Can I use website. Therefore, the only solution would be modifying the HTML structure or using JavaScript code.

0

You can select the target by it's parent (if it's possible in your original code), then you can do something like this:

ul li:nth-of-type(2) > div.red {
  background: yellow;
}

The Code:

ul {
  list-style-type: none;
}

ul li>div {
  height: 100px;
  width: 100px;
  border: 1px solid black;
  margin: 20px;
}

ul li>div.red {
  background: red;
}

ul li>div.green {
  background: green;
}

ul li:nth-of-type(2) > div.red {
  background: yellow;
}
<ul>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="green" />
  </li>
  <li>
    <div class="red" />
  </li>
</ul>

In case you can use JavaScript, here is the code:

  • Get all red elements
  • Set target (the number of the affected red)
  • Check all red elements, if the target match apply the CSS.

You can declare a new variable to store the color as well if it's going to change at some point. example:

var bgColor = 'yellow';
reds[i].style.background = bgColor;

The Code:

var reds = document.querySelectorAll('.red');
var target = 2;

for (var i = 0; i < reds.length; i++) {
  if (reds[i] == reds[target-1]){
    reds[i].style.background = 'yellow';
  }
}
ul {
  list-style-type: none;
}

ul li>div {
  height: 100px;
  width: 100px;
  border: 1px solid black;
  margin: 20px;
}

ul li>div.red {
  background: red;
}

ul li>div.green {
  background: green;
}
<ul>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="red" />
  </li>
  <li>
    <div class="green" />
  </li>
  <li>
    <div class="red" />
  </li>
</ul>
001
  • 2,019
  • 4
  • 22
  • Thanks for trying to answer, but please read notes section in question. I am not allowed to use anything other than css. – Vishal Jun 16 '21 at 19:15
  • Sorry didn't notice... check now please for a possible method – 001 Jun 16 '21 at 19:22
  • Sorry, i did not mention anywhere, but I would say that number of elements may not be always same, so there can be 3 or 4 or any number of consecutive red elements or any number of consecutive green elements. – Vishal Jun 16 '21 at 19:28