What I Want From CSS3 - Part 2 | January 22, 2006

CSS allows you to move down through the document tree and select elements based on their ancestry. So you can style one element that is a descendant of another element. For more control you can use the child selector to style the direct children of particular element, rather than all of its descendants. The child selector is usually used in situations where you know the parent and want to style the children.


<div id="parent">This is the parent
  <div>This is the child (I want to style this)
    <div>This is the grandchild</div>
  </div>
</div>

#parent>div {...}

The problem is, I often find myself in the reverse situation, where I know the child and want to style its parent.


<div>This is the parent (I want to style this)
  <div id="child">This is the child
    <div>This is the grandchild</div>
  </div>
</div>

Currently the only way you can do that is to identify the parent by using a class or id name.


<div id="parent">This is the parent (I want to style this)
  <div>This is the child
    <div>This is the grandchild</div>
  </div>
</div>

#parent {...}

However this means adding extra mark-up to your documents and forms a bit of a code dependancy, where removing the child necessitates removing the identifier on the parent. This can be done programatically, but is less than ideal.

What I really want is a parent selector. That way, you could simply do this:


div<#child {...}

It’s a little more difficult to read as it doesn’t follow the current expectation that the right most selector refers to the element being styled. However it wouldn’t have an adverse effect on the cascade and could come in extremely handy in certain situations.

Posted at January 22, 2006 11:33 AM

Comments

Dave said on January 22, 2006 6:04 PM

Wow, I never thougt about this sort of function. Thinking about it now though, I’d probably use it quite a lot.

Mike D. said on January 22, 2006 6:09 PM

Andy: Interesting. I talked with an ex W3C member a few months ago about this and he said that “reverse inheritance” is “public enemy #1” to some people. I didn’t really understand the reason why, but whatever.

My biggest use for this is when I’m using dotted underlines sitewide for text-anchors (via the “border” property) and I need a rule that says “whenever an image is inside of an anchor tag, kill the anchor tag’s border style”. Seems like a simple enough request, you’d think…

Anton said on January 22, 2006 6:10 PM

You can also style the parent with a back-to-back styleing like this (which I presume you knew, right?):

#parent {…}
#parent>div {…}

Just an easy override system. Sure, a reverse-selector would be fantastic, but that doesn’t mean that you have to add extra markup like you said.

Jon B said on January 22, 2006 6:24 PM

I would have thought a better way of signifying a parent selector would be like:

#child < parent {...}

Obviously remove the spaces (your formatter made the necessary)

This way the styled element is still on the right and the starting element is still on the left - just makes more sense to me to do it that way and use just the < to indicate the relationship.

Geoffrey Sneddon said on January 22, 2006 6:41 PM

Can you guess exactly what I was thinking I needed earlier today? The parent selector.

Strange…

Sebastian said on January 22, 2006 6:44 PM

Yeah, very nice idea. I want this two. CSS has two many limits currently and this is definitly one we should really fix. Thank you, Andy, for making it public.

Guido said on January 22, 2006 7:21 PM

I’ve realized I needed this just too many times. It’s great that you mentioned it, I fully agree.

James AkaXakA said on January 22, 2006 9:13 PM

Yep, want that too.

Also, a reverse adjacent selector would be very handy. Then div p+p-p could select the first p’s, but only if there’s a second one.

Andy Budd said on January 22, 2006 9:29 PM

Anton: Just noticed an error in my code which I’ve updated. What I’m trying to say is that if you want to style a parent element based on the existence of a child element, the only way you can do it is to add a class or id to the parent. However the link isn’t maintained in the CSS. If you removed the child, you’d want the parent to go back to its default styling. However in this example you’d actually have to remove the class or id, which is a really bad situation to be in. You couldn’t edit the CSS because you may be using the same class or id in another place on your site.

Jon B: You could do it that way round and the element you’d be styling would remain on the right. However the selectors are no longer written in the order they appear in the document tree, which I think is important. I also think the meaning of the selectors symbol gets lost as it’s no longer visually indicating the hierarchical relationship.

Andy Budd said on January 22, 2006 9:45 PM

Funny. I was also going to mention a “reverse adjacent selector” as well but couldn’t think of a good name. The opposite of adjacent (i.e. next to) is nonadjacent which obviously wouldn’t work. I thought of saying “preceding sibling selector” but wasn’t sure.

Michel Fortin said on January 22, 2006 9:59 PM

I think one problem with the parent selector is one of implementation. Not that it’s impossible to add support for it in a browser — it certainly is — but at what price? I’m pretty sure a lot of speed optimisations would need to be thrown away to work with a parent selector.

This makes me think of regular expressions for searching patterns in text. Simple expressions makes scanning pretty efficient. But the more complex your expression, the the more care you must put into writing it. If you don’t, parsing can become pretty slow and even get you in a never-ending loop. Limiting CSS selectors to simple things makes sure all websites are fast by preventing anyone from making “low-performance” selectors, and I think that is good.

I’ve never ever written web browser code so I may be in the wrong however.

Conceptually, there is also the problem of incremental rendering. While the browser loads the page, elements are added as they arrive and the browser can’t apply the right style to the parent until the every child has been loaded. This problem also apply to a reverse adjacent selector. Is this important? I’m not sure, but it could for some applications.

Steve Ganz said on January 22, 2006 10:45 PM

I think you hit the nail on the head, Michel. It turns out that these complexities are what have prevented implementors from trying to solve this problem thus far.

Andy Budd said on January 22, 2006 11:27 PM

Interesting. It looks like a parent selector or similar would be covered under and old, and presumably discounted, :matches and :has pseudo-class.

More details here

Nathan Smith said on January 23, 2006 12:09 AM

I agree, that would be incredibly handy, being able to style a parent. However, then we wouldn’t be using “Cascading” Style Sheets. I suppose we would call it “Swimming up-stream!”

Guy Carberry said on January 23, 2006 12:54 PM

Since i first started with CSS ive been wanting this. Always ahd to achieve it us JS. Would be lovely to have this ability in CSS3.

Craig Morey said on January 23, 2006 4:10 PM

I’m behind you with parent selectors, it would make some dynamically produced sites easier to style. Also on my hit list is something like :odd :even selectors to tiger stripe stuff like tables. ok, thats a bit specific, but something more extensible than :first-child would be useful for styling a series of items (and would be used every)

Andy Budd said on January 23, 2006 4:36 PM

The nth-child selector will enable you to do “tiger striping” in CSS3. Unfortunately none of the major browsers support it at the moment, as far as I know.

Anton said on January 23, 2006 5:09 PM

Ah, I see what you mean now.

Okay, so let’s try it from another approach…
Instead of detecting a parent from the child, why not suggest a conditional operator/logic on the parent. So that a style is applied only if a particular condition is true.

It could look a bit like this:
#parent[>div] { style; }

Or, use a NOT operator to test for anti-children:
#parent!>div { style; }

In this example, the #parent has a particular appearance in every case except that where it contains a div.

Anyway, your idea is still fantastic, I’m just playing devil’s advocate and coming up with ideas that could still use the standard parent>sibling system.

Dylan Schiemann said on January 23, 2006 5:26 PM

I proposed this exact syntax back in 2000 (and maybe others before me did so as well).

As Mike D. said above, there is a big resistance to this.

Sean Hogan said on January 24, 2006 6:00 AM

XPath

Jason Beaird said on January 24, 2006 3:13 PM

Why is this “reverse inheritance”/parent selection idea such an enemy. It may be a bit hard to grasp the concept, but if you’ve ever had to parse xml, you know that stepping up and down the parent/child tree is essential. I like the concept personally, and I think it has great benefits for css.

Andy Budd said on January 24, 2006 4:06 PM

Anton, that’s essentially what the proposed :matches and :has pseudo-classes do that I mentioned previously.

Jason, It seems that the resistance is mostly revolving around performance and rendering issues. A parent selector seems to be a request that pops up quite frequently on the W3C CSS mailing list and has generated quite a bit of discussion. Sadly it’s not going to happen in CSS3 but would be a useful addition to CSS4 (like that’s going to happen!)

James AkaXakA said on January 24, 2006 9:53 PM

CSS4: The 2010 release..and 2016 implementation.

Andy Budd said on January 24, 2006 10:05 PM

James, 2010 release and 2016 implementation sounds more like CSS3 to me. By the time CSS4 comes out we’ll all be wearing jet-packs and living on Mars ;-)

James AkaXakA said on January 25, 2006 12:18 PM

Wooooooooooooo! Jet-packs!

The future is now!