2

I want to make the first and last .highlighted elements red. The highlighted classes which are in the middle should be purple. Seeking dynamic CSS solution for any number or arrangement of .highlighted

.highlighted {
  background: purple;
}

.highlighted:first-child,
.highlighted:last-child {
  background: red;
}
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
Can Karakoyun
  • 171
  • 1
  • 1
  • 10
  • 1
    _"Could I solve this issue with only CSS?"_ - no. Not only can :first-child/:last-child and the class selector not be combined _that_ way (they can of course, but it means something different), you also only got _one_ single child per parent here. – CBroe Mar 17 '23 at 06:45
  • Yes, I know that but I want to try my chance with asking. Thought maybe missing something :D I am using a library it's rendering like this. I should write JS for customizing. Thanks! – Can Karakoyun Mar 17 '23 at 06:58
  • 1
    You can select the first one by `td:not(:has(.highlighted))+td:has(.highlighted) .highlighted`. But I don't think there is a way to select the last one by css. And firefox does not support `has()` . – Shuo Mar 17 '23 at 07:15
  • @Shuo at least on my Edge/Chrome on Windows10 I have to remove the tds from your selector. I don't understand why as your solution ought I think to work, and mine shouldn't. Is there something specal about td elements that means they seem to be almost ignored? Or...? – A Haworth Mar 17 '23 at 07:36
  • I wrapped these tds by `` and `` tags.
    – Shuo Mar 17 '23 at 07:53
  • @shuo yes, I hadn't realised that a browser will ignore tds if not properly within trs. – A Haworth Mar 17 '23 at 08:13

1 Answers1

2

[I didn't understand why the snippet below, which leaves out the tds from the selectors, worked. I now do as @temaniafif has pointed out that the tds are ignored if not properly within trs etc. I leave this post here for a bit though to see if further info comes in.].

You can do this with pure CSS for those browsers which have implemented the CSS :has. [not true as far as I understand it now]

At the time of posting this, this is most of the major browsers except Firefox which will only implement :has if the user has set a flag.

What this snippet does is color all .highlight red. Then colors purple everything that is .highlighted and preceded by a .highlighted. Then colors the last one red again because it is not followed by a .highlighted.

.highlighted {
  background: red;
}

.highlighted+.highlighted {
  background: purple;
}

.highlighted:has(+ :not(.highlighted)) {
  background: red;
}
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span class="highlighted">Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
<td>
  <span>Test</span>
</td>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • Works for me in Chromium but not Firefox even with the has flag enabled, on FF only the first is red with has enabled – Zach Jensz Mar 17 '23 at 07:45
  • td elements are only valid inside tr (that should be inside table) so the browser will remove them – Temani Afif Mar 17 '23 at 07:48
  • @TemaniAfif thanks - that has stopped me worrying! Will experiment with putting in a proper table. – A Haworth Mar 17 '23 at 07:49
  • Firefox removes the trs but still whitespace nodes, maybe there's a discrepancy with how each engine handles those and + – Zach Jensz Mar 17 '23 at 07:50
  • @ZachJensz looks like this could be so. I realise my 'answer' isn't an answer but leave it up for a bit to see as I'm learning stuff from the comments. – A Haworth Mar 17 '23 at 08:11