2

I want to use css to select all elements until it reaches an element with a specific attribute. i.e.:

<ul>
    <li>...</li>
    <li>...</li>
    <li class="active">...</li>
    <li>...</li>
    <li>...</li>
</ul>

I need to catch all <li> elements that appear before the active one. I know how to catch any group of child elements using nth-child etc., but active changes, so it can't be a static group. And I know I can do it through javascript, but I wan't a css solution.

So is this possible to select all child elements up to a calculated point? Or in other words: is there a way to do a conditional nth-child? I'm willing to change the markup if needed (the attribute doesn't have to be a class, it can be anything).

Until recently I would've thought it's not possible, but after learning about the css attr() I know it's possible to access the DOM attributes, so maybe it's also possible to take it a step further?

yuvi
  • 18,155
  • 8
  • 56
  • 93

1 Answers1

4

You can override css by doing this:

ul > li{
    /* normal styling for li above active */
}

ul > li.active ~ li{
    /* overriding the above stylings for elements after li.active element */
}

if the attribute is not class then you can do ul > li[attrName="active"] ~ li.

Working Fiddle

Working Fiddle (if "active" is in other attribute)

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • Beautiful, just beutiful. Can you explain to me why the `~` does this? I'm familiar with using `+`, and I've read [this](http://stackoverflow.com/questions/15471382/what-does-mean-in-css) but I'm not getting what's going on here? What's the difference from the `+`? – yuvi Mar 29 '14 at 18:26
  • Yes it is a general sibling element which is selecting all the `li` elements which are after the `li` with `active` class/attrName. At first, I applied a common styling to all the `li` elements, then I overrided or gave special styling to the sibling elements of `li.active` by overriding. – Mr_Green Mar 29 '14 at 18:32
  • I get the general idea. What's confusing me is that `~` supposedly matches all direct siblings. It's not the opposite of `+`, right? How does it not apply to the adjacent `li`? – yuvi Mar 29 '14 at 18:39
  • @yuvi each element has only 2 direct siblings, the previous sibling and the next one. `~` is designed to do so and it does not relate to how `+` works, I think. – King King Mar 29 '14 at 18:45
  • @yuvi It did apply also to the adjacent `li`. sorry I am not getting your point.. – Mr_Green Mar 29 '14 at 18:46
  • @Mr_Green Nevermind. The behavior is just still confusing me a little, I'm trying to understand the difference of `~` from `+`... I'll just keep reading about it until I get it. Thanks for your patience – yuvi Mar 29 '14 at 19:00
  • 1
    @yuvi `~` applies styling to all the next sibling elements whereas `+` applies styling to only the adjacent sibling element. ignore this if you are asking something else :) – Mr_Green Mar 29 '14 at 19:02
  • So `+` only applies to the next sibling, and `~` applies to *all* of the next siblings? – yuvi Mar 29 '14 at 19:05
  • Great. That clarifies it, Thanks! – yuvi Mar 29 '14 at 19:08