3

I'm dynamically adding and removing classes to and from elements on specific JS events. What I would like to do is select the last child element that has none these classes with CSS.

Example #1

<container-element>
  <h2></h2>
  <div class='some-class'></div>
  <div></div>
  <div></div> <!-- select this div -->
</container-element>

Example #2

<container-element>
  <h2></h2>
  <div></div>
  <div></div> <!-- select this div -->
  <div class='some-class'></div>
</container-element>

Is it possible to write a CSS selector to do this?

Something like container-element > div:not(.select):last-of-type?

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • @fstanis im not trying to select the last element WITH a class. im trying to select the last element WITHOUT a class. – oldboy May 26 '19 at 00:22
  • Well, unfortunately, since the linked "last child with a specific class" is impossible in pure CSS, the same goes for this. – fstanis May 26 '19 at 00:23
  • Specifically, I believe the workarounds presented in the other question apply here as well. – fstanis May 26 '19 at 00:25
  • @fstanis youre 100% sure its impossible?? – oldboy May 26 '19 at 00:27
  • @fstanis isnt it possible using some sort of attribute selector like `[class~='list']:last-of-type`? – oldboy May 26 '19 at 00:29
  • Check the discussion in that other answer - there's a lot of useful information on how that works and I believe it wouldn't work in your case. – fstanis May 26 '19 at 00:36
  • Are there any other targetable features in your HTML? Total number of siblings? Element types? – Michael Benjamin May 26 '19 at 00:54
  • as you said *adding and removing classes to and from elements on specific JS events.* --> so I am pretty sure you can handle this with JS – Temani Afif May 26 '19 at 01:11
  • @TemaniAfif i def can, but as we talked about before: better to use CSS if possible – oldboy May 26 '19 at 03:37
  • @TemaniAfif found a way to do it with pure HTML and CSS that is pretty darn simple. im gon post my answer below – oldboy May 26 '19 at 03:55

3 Answers3

2

Per this answer, the solution would technically be container-element > div:nth-last-child(1 of :not(.select)).

However, this of S clause in :nth-last-child is still not supported by any browser other than Safari.

fstanis
  • 5,234
  • 1
  • 23
  • 42
1

You're saying: select the last sibling that doesn't contain a class attribute.

I don't believe it's possible with currently available CSS.

You're asking a waterfall (the cascade) to run upward. The browser needs to check the last element, then check the ones that came before it. This is not how CSS works.

div:not(.some-class):last-of-type won't work because the browser doesn't move up automatically to the next sibling.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Of course I can do this with JS, but preferred a pure CSS solution. Supposedly a pure CSS solution is not possible, so the next best thing is an CSS solution with a little extra HTML.

The trick was to add a class, not-selected, to all of the elements, then remove this class from the element that you want to target with the CSS selector.

And the CSS selector would be div:not([class*='not-selected']).

div:not([class*='not-selected']) {
  background: red;
}
<button type='button'>
  <h2>title</h2>
  <div class='not-selected'>option one</div>
  <div>option two</div>
  <div class='not-selected'>option three</div>
</button>
oldboy
  • 5,729
  • 6
  • 38
  • 86