About the indirect adjacent combinator (~) in CSS
Similar to the CSS Adjacent Sibling Combinator that I wrote about before, the indirect adjacent combinator is pretty nifty and supported by IE7+, FF2+, Opera 9.5+, Safari 3+, and even Konqueror. It is actually part of the CSS3 spec but it’s surprisingly well supported. Here’s how to use it and what it does:
Using the CSS Indirect Adjacent Combinator
h3 ~ p {
color: #FFFFFF;
padding-left: 20px;
border-left: 3px solid;
}
This would affect each <p> element that is a sibling of a preceding <h3> element. This is different from the Adjacent Sibling Combinator (+) in that it affects all following <p> siblings instead of just the immediate sibling. Let us see an example:
CSS Indirect Adjacent example
Example 1: Adjacent Sibling combinator (h4 + p) test:
Heading 4
Paragraph 1 - This should be gray and red
Paragraph 2 - This should NOT be red
Example 2: Indirect Adjacent Sibling combinator (h4 ~ p) test:
Heading 4
Paragraph 1 - This should be gray and red
Paragraph 2 - This should also be gray and red!!
Here is the CSS for the above example:
#indirect-example1 h4 + p,
#indirect-example2 h4 ~ p {
background-color: #CCC; color: #F00;
}
Cool, yes? So you see how you can use this instead of the (+) selector to apply styles to the elements you want in basically everything except IE6-! This is a good example of something used for progressive enhancement that should be used to add detail to elements to give your users more information.
Update: Sorry for the name confusion. The latest draft of the CSS3 spec calls this the "General Sibling Combinator" and I didn’t think it had changed from "Indirect Adjacent Combinator" when I first learned of it so I used the latter. My apologies!
Have you ever used this? What was your experience and what ideas do you have for this CSS gem?
A 25 year-old programmer for
I can see this being extremely helpful, especially in the first case you presented. I’ll share this with my team!
In the future, or in non IE6 places, you’ll be able to avoid a wrapping div via this selector.
With all the stuff slowly being added onto it, I’m half-expecting CSS to be turing-complete one day.
If the is not wrapped by a parent tag how can it be a sibling of said tag? Siblings need parents, don’t they? In XML/XHTML a parent is a containing tag, right?
Or maybe I am missing the point somewhere?
Interesting post Eric.
Stephen, the p tags are siblings of the h4 tag because they share the same parent (#indirect-example). Sibling is a brother/sister relationship.
@Sam:
That’s a really keen observation. Every millisecond counts and perhaps it might shave some off, eh?
@David and Casey:
Thanks, I appreciate it.
The latest working draft of the Selectors spec calls this the “General sibling combinator”.
Thanks for this post. I’ve not encountered that CSS operator before but I’ll file it away and see if I can come up with a use for it.
Rather than writing “h4 + p, h4 ~ p {…}”, wouldn’t “h4 ~ p {…}” accomplish the same result?
@Leo:
h4 + p {} is just the first example and h4 ~ p {} is for the second. You’re right that combining them would be redundant as h4 ~ p acts on all elements that h4 + p affects.
re.: ideas on how use the ~ selector: I’ve posted some techniques off the top of my head here: http://lhorie.blogspot.com/2008/06/using-selector-in-css.html
I’d like to see what other things people can come up with.
@Leo:
Those are some good ideas. It seems to be easily applicable to anything that you have more than 1 in sequence, and obviously lists come to mind. I’m sure there are genius applications here and I encourage everyone’s input :)
label ~ input {} also seems to be a nice use
Unfortunately too many of my visitors still use IE6 :P I keep telling them to switch but they just aren’t listening.
I’m gonna use it into one of my personnal web app. It’s very cool that IE7 supports this.