This posting was taken with permission of Russ Weakley from the http://www.webstandardsgroup.org
Today, Amit posted a piece of CSS code to the list. I remember when I first started getting into CSS, code like this would make me freak out:
div.content [href^="http:"] { background: transparent url('path/to/aoutside.gif') 100% 50% no-repeat; padding-right: 10px; }
So, for those that are reasonably new to CSS, I'd thought I'd break it down into bite size pieces.
The basics
A simple rule set looks like this:
selector { property: value; }
More here: http://css.maxdesign.com.au/selectutorial/rule.htm
For example, if you want to change the appearance of every "a" element on your page, you would use code like this:
a {background: green;}
The "a" is the selector. The "background" is the property, and "green" is the value.
If you want to be more specific, and style all "a" elements inside a specific container, you would use a descendant selector: http://css.maxdesign.com.au/selectutorial/selectors_descendant.htm
A descendant selector could look like this:
#nav a {background: green;}
Now, only "a" elements within the #nav container will be styled with a green background.
Attribute selectors
Attribute selectors are much more powerful than simple selectors or descendant selectors as you can select not only elements, ids and classes, but the attributes within elements. Even better, you can select values associated with attributes within these elements.
More here: http://css.maxdesign.com.au/selectutorial/selectors_attribute.htm
It all sounds too good, doesn't it? Of course, IE5, 5.5 and 6 (as well as Mac IE5) do not support these selectors. But let's ignore that for a second...
A sample attribute selector
What if we wanted to style any "a" elements with an attribute of "href"? We could do this with an attribute selector like this:
a[href] {background: green;}
Now, any any "a" element that has an attribute of "href" will be styled with a green background.
Attribute selector using "value"
What if you wanted to style only links that went to a certain page? You could refine your attribute selector still more, by using an attribute and a value:
a[href="fun.htm"] { background: green; }
Now, any "a" element that has an attribute of "href" and a value of "fun.htm" will be styled with a green background.
You can also set up attribute selectors to select space separated instances of a value and hyphen separated instances of a value, but that is another story.
Selecting any external link on a page
What if you want to select any external link on the page? Amit chose to do this using a CSS3 attribute selector. They will not work in browsers that do not support them, but look cool in browsers that do. As long as the CSS3 selector does not contain critical information that may negatively affect users on older browsers, this is an acceptable option - depending on the site, the audience etc.
The name for the particular selector Amit used is called a "Substring matching attribute selector". These selectors match substrings in the value of an attribute. The particular one we want to use will select prefix values. It looks like this:
[att^=val]
This represents the "att" attribute whose value begins with the prefix "val" - http://www.w3.org/TR/2001/CR-css3-selectors-20011113/#attribute-selectors
In this case, the substring we want is simply "http:". This will select any link that has a prefix of "http:", but will ignore any link that do not have this prefix. There is a good chance that this will now select only external links. The selector is:
a[href^="http:"] {background: green;}
Now, any "a" element that has an "href" with a prefix of "http:" will be styled with a green background.
Adding a descendant selector
What if you only wanted to style external links within a certain container?
This can be achieved by using the attribute selector above, with additional descendant selectors.
Let's assume that the external links to be styled are inside a div, and that we have styled the div with a class called "content":
<div class="content">... </div>
The rule set would now be:
div.content a[href^="http:"] { background: green; }
Now, only links within a div that is set with a class called "content" will be selected. Inside this container, any "a" element that has an "href" with a prefix of "http:" will be styled with a green background.
The final touches...
Amit, being the clever guy he is, has decided to style these external links with a small icon. So, all we need to do is replace the "background: green" with a background image. Here is the original code sample:
div.content a[href^="http:"] { background: transparent url('path/to/aoutside.gif') 100% 50% no-repeat; padding-right: 10px; }
Instead of a green background, we now have a transparent background, with an image called "aoutside.gif" applied as a background and set to no repeat. It is also positioned at the very right of the a element (using 100%) and set to sit in the vertically in the middle of the a element (using 50%). Finally, to push the content within the "a" element off the background image, a small amount of padding is applied to the right (padding-right: 10px).
So there you have it. I hope this did not add to any confusion.
Purists, who wish to find fault with any of the sloppy descriptions above may start abusing me now.
Thanks
Russ
Selectors explained
You have to be willing for the ^= trick to not pass a CSS validator even though it is valid per CSS3 candidate recommendations.
From alistapart's going to print article:
!IMPORTANT: As mentioned, ^= is a CSS3 selector. The W3C CSS validator can only test for compliance with CSS1 and CSS2. Unable to understand the CSS3 selector, the W3C validator will report it as an error, even though it is perfectly valid per the CSS3 Selectors Candidate Recommendation.
Good, topic, Tony, albeit a bit advanced for some who are just wrapping their heads around contextual selectors.
DE
Selectors explained
I think I would have to agree with david that although a good piece , it is slightly advanced in nature and the statement:
So, for those that are reasonably new to CSS
makes me think that newbies will find it just a wee bit confusing.
The title could maybe be better off being;
"Advanced Selectors Explained"
Hugo.