4

For example lets say I have an HTML looking like the one below. Am I not selecting the parent element which is ul?

ul
  margin: 50px

ul.test
  li hello
  li how are u
GramThanos
  • 3,332
  • 1
  • 18
  • 32
EEE
  • 149
  • 1
  • 6
  • Possible duplicate of http://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector – Sam Feb 18 '17 at 07:34
  • You can select elements that *happen to be* parent of other elements (such as your `ul`), but there is no selector for *obtaining the parents* of elements matching some selector (i.e, there is nothing like `parents of li`) – Sam Feb 18 '17 at 07:38
  • i apologize but I still do not get it :/ – EEE Feb 18 '17 at 07:41
  • No, you are selecting THE element ul. You can select its children e.g. `ul li` but you cannot select ul's parent (which may be a div, span or anything else) e.g `div < ul ` (does not exist and would not work) – A. L Feb 18 '17 at 07:49
  • well couldnt i just give the div a class then select the class? – EEE Feb 18 '17 at 07:53
  • Your `ul` selector will match all the `ul` elements in your html, regardless of whether they are parent of other elements or not. I suggest you to check [this question](http://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector) and its answers. – Sam Feb 18 '17 at 07:57
  • *"well couldnt i just give the div a class then select the class?"* - Yes, but that would not be selecting it *as a parent of the ul*, it would be selecting it directly. – nnnnnn Feb 18 '17 at 08:10

1 Answers1

7

In order to understand what they mean you need to understand what selecting means in CSS (parent is easy :).

By selector they mean the element to which CSS applies. So, using CSS, if you have a selector (any selector), you cannot apply changes to any of the parent parts. You can only apply them to its last part. To the child (or, in some cases, to an immediate or distant following sibling).
(The simple rule here is that the part determining which element the styling will apply to is always the last part of the selector).

Let's take this simple selector:

ul { 
  /* rules apply to all ul */
}

I can make a rule to style up all it's children:

ul > * { 
    /* rules apply to * (all children of ul) */
}

But I cannot make a rule to style up its parent:

* < ul { 
  /* rules don't apply. this is invalid */ 
}

Whenever I make a rule, like...

* > ul {
  /* rules apply to any ul that is a child of * (any element) */
}

the style always applies to the last item in the selector, never to one of the parents.

That's why there's no parent selector in CSS. You can't style a parent based on selecting one of its children. You need to select it. Got it?


Heck, I'll give you an example.

Consider this markup, but imagine it 10 times more complex (let's assume there's a bunch of guys adding/removing parts from it so it can have huge depth):

<div>
  <whatever></whatever>
</div>
<span>
  <whatever></whatever>
</span>
<ul>
   <li>
     <whatever></whatever>
   </li>
   <li></li>
   <li>
     <whatever></whatever>
   </li>
 </ul>

Now, please create a CSS that would make all parents (one single level ancestors) of <whatever> have a red background, no matter where they are in DOM. Can you?
Here's some news: you can't.

The closest they got to making this happen was when :has() selector has been proposed, but it's been rejected. This selector would need the CSS parser to go back, and it always goes forward. That's why it's fast, no matter the device/browser/system. CSS is always fast.

Because it has no :has() selector (or < combinator).

Additional note: As @Maximus has noted in comments, shadow DOM elements provide a method to select the top level element of the current shadow DOM instance by using :host. It's not a proper parent selector, as it doesn't provide means to select parent elements inside the shadow DOM, but only the entry point (the contact point with the normal DOM), giving you the option to apply rules to the current shadow DOM instance and not to others.

tao
  • 59,850
  • 12
  • 84
  • 110
  • thank you for your response it was extremely helpful, But if I wanted to style the parent of my ul, lets assume its a div? can't I just style the div in css? – EEE Feb 18 '17 at 08:18
  • *"That's why there's no parent selector in CSS."* - That wasn't an explanation of *why* there is no parent selector. It would certainly be possible to add one to the CSS specification and implement it in browsers. It's just that that has not occurred to date. – nnnnnn Feb 18 '17 at 08:18
  • I believe I have touched that point, @nnnnnn. See last paragraph of my answer. || You're welcome (to [so]), eti. – tao Feb 18 '17 at 08:19
  • Thank you andrei, that was actually lovely, that example really explained it. thank you so much. – EEE Feb 18 '17 at 08:25
  • You're welcome. About your *"can't I style the div"* above: Of course you can, but not based on selecting one of its children. You can't apply rules going up the tree. Only down the tree. To apply rules to the parent div you need to make a rule for it or for one of its parents. – tao Feb 18 '17 at 08:28
  • thank you,Whereas you can easily select an element directly. the point i was missing was that it had to select the above element based on the children. – EEE Feb 18 '17 at 08:45
  • Glad I was able to explain so you understood. Sometimes things we take for granted as ***how they are*** can be difficult to explain. – tao Feb 18 '17 at 08:50
  • possibly you could add that shadow root has some selectors for parents, like `:host` – Max Koretskyi Feb 18 '17 at 09:24
  • @Maximux thank you for the suggestion. Added. I'd estimate my current knowledge level on shadow dom elements and techniques as limited, feel free to make suggestions/ammends, thank you. – tao Feb 18 '17 at 11:53
  • :has() hasn't been rejected yet. It's just that no one has bothered to test it to see if it can be approved for CSS. – BoltClock Feb 18 '17 at 17:11
  • @BoltClock I might be wrong here, but from what I know `:has()` was initially proposed as part of `CSS3` selectors, but at that point was discussed and rejected. I now see it shows up as part of level 4 draft. Please update the answer or provide documentation links so I can provide accurate info and I'll tend it. Thank you. – tao Feb 18 '17 at 17:17
  • @eti: "But if I wanted to style the parent of my ul, lets assume its a div? can't I just style the div in css?" You're not allowed to make any assumptions (on which to construct a selector, or modify the HTML to suit said selector). That's the point of having a parent selector. – BoltClock Feb 18 '17 at 17:17
  • 1
    @Andrei Gheorghiu: I don't think :has() is worth mentioning at this point. No implementations exist outside of jQuery and other non-CSS libraries, and no progress has been made on it in the last 12 months. – BoltClock Feb 18 '17 at 17:18