Most people who learned CSS within the last 5 or 6 years are very familiar with the properties (z-index, float, text-align, etc.) and selectors (specify a class with “.className”, an id with “#theID”, and etc.) that CSS and CSS2 specified, and the finer points of these properties have been discussed and explained at length. For example, I have recently seen several articles on the z-index and float properties, and how to use them in a cross-browser compatible way. The CSS and CSS2 specifications are, on the whole, very useful (though not without their problems).
The World Wide Web Consortium (W3C – if you’re not familiar with it, they’re the people who write the documentation and standards on the most significant client-/browser-side programming languages and document structure formats [HTML, XHTML, CSS, JavaScript, XML, and so on]) within the last few years has expanded the list of properties and selectors that browsers should be able to support with CSS3. Although not all browsers currently support all of these (only Opera 9.5, Konqueror 3.5.4, and Safari 3.1 support all of them; Firefox 3+’s support is partial) I’m going to spend the next few posts giving an introduction to at least the most useful ones.
(Note: If you’ve used jQuery, you’ve almost certainly been exposed to jQuery’s selectors. What you may not know, however, is that many of these selectors are actually valid CSS3. jQuery expands on the CSS selectors and pseudo-selectors significantly, however, so don’t expect everything to work.)
E[foo='bar'], E[foo$='bar'], E[foo^=bar], and E[foo*='bar']
Supported by: Firefox 3+, IE7+, Opera 9.5+, Safari 3.1+
Problem: Let’s say you have a page with thousands of links, and you want to change their style based on whether they match certain criteria (to make certain types of links stand out to visitors, or yourself). So, for example, we’ll make links starting with http:// blue and links starting with ftp:// red. Then, if the end of the link is .html, we’ll make it bold; if it’s .php we’ll make it italicized. If the link contains the phrase “.com” in it, we’ll make it large; anything else will stay at the default size. If a link’s href is set to “#”, then the link will be bright pink for being such a show off, yet doing nothing. Finally, if a link doesn’t match any of these selectors, the default settings will be a size of 12px, black, and no boldness or italicization.
Solution: Here’s one way you could do this: Apply several classes to every single link (you can use more than one, you know) so that, for example, anchor tags with an href attribute set to an FTP address at a dot com site would have its class attribute set to “dotcom ftp” – and then we would set individual classes in the CSS file. However, this is very impractical, especially if you’re typing everything out by hand. There’s a much quicker way to do it: the E[foo='bar'] CSS3 selector and its variants. Here’s what each one does. In each of the items below, “E” is a standard CSS or CSS2 selector (“.theClassName”, “#theID”, “a”, “p”, “div”, etc.). “foo” is the name of an attribute that each item matching E might have. “bar” is the value that we want it to match in one of several ways (depending on if the part connecting the foo and bar is =, ^=, $=, or *=).
- E[foo='bar'] – This selector will match any item E in which attribute foo is exactly equal to bar. So, if we want to apply some styles to any <p> tag that has an align attribute set to left, we could do:
p[align='left'] {
…
}
- E[foo$='bar'] – This selector will match any item E in which the value of attribute foo ends with bar. Continuing with the example above, we could get all <p> tags with align set to “right” or “left” by doing:
p[align$='t'] {
…
}
- E[foo^='bar'] – This selector will match any item E in which the value of attribute foo begins with bar. Yet again using our ubiquitous <p> tags example, suppose we have the following document:
<p id=”poo_face”>Some poo</p>
<p id=”winnie_the_pooh”>An adorable little bear</p>
<p id=”poo_pie”>Poo in baked form</p>
We want to make the first and last <p> tags have a brown background and light brown text (a sign of a cute bear’s varied diet), and we want the other to have a goldish background with red text (that cute little bear). Here’s how we can do this with two CSS selectors, instead of using classes:
p[id^='poo_'] { color: #846D6D; background-color: #583E43; }
p[id^='winnie'] { color: #C00; background-color: #FFCB00; }
This is interesting. Piece of advice: I’m just doing this for an example. I do not recommend it for doing something so simple as this example – it’s just overkill that might unnecessarily break your site’s appearance for users of older browsers.
- E[foo*='bar'] – This selector will match any item E in which the value of attribute foo contains bar anywhere in itself. So let’s say that Winnie rolled around in all the poo around him. A quick fix to our predicament is to simply delete the second selector above and change the first one slightly:
p[id*='poo'] { color: #846D6D; background-color: #583E43; }
This will make all of our text light brown on a dark brown background.
So, going back to our example of the links, all we’ll need to accomplish our goal with the thousands of hand-typed links on our page is this:
a { font-size: 12px; color: #000; font-weight: normal; font-style: normal; }
a[href^='http'] { color: #00F; }
a[href^='ftp'] { color: #F00; }
a[href$='.html'] { font-weight: bold; }
a[href$='.php'] {font-style: italic; }
a[href*='.com'] { font-size: 5em; }
a[href='#'] { color: #F0F; }
It really comes down to whatever floats your boat, but since this works in the latest versions of the major browsers (I don’t really care about IE6 users, tehe) 7 lines of code sure beats adding several different class to many thousands of links. Of course, you’re probably not going to encounter a situation like this. But in any case, you may find this very useful someday, even though this could very easily be reproduced using the default class or ID selectors – it would just be slightly more work.
Sample Script
Here’s the HTML and CSS that shows everything I was talking about. Copy it into your own HTML file and try it out in one of the supported browsers (see above)!
<html>
<head>
<title>A Test Page</title>
<style type=”text/css”>
a { font-size: 12px; color: #000; font-weight: normal; font-style: normal; }
a[href^='http'] { color: #0F0; }
a[href^='ftp'] { color: #F00; }
a[href$='.html'] { font-weight: bold; }
a[href$='.php'] {font-style: italic; }
a[href*='.com'] { font-size: 5em; }
a[href='#'] { color: #F0F; }
</style>
</head>
<body>
<a href=”http://www.largepoo.com”>Large Poo</a><br />
<a href=”ftp://www.anorganizationalwebsite.org”>An Organizational Website</a><br />
<a href=”www.mynameisbob.info/whoisbob.html”>Who is Bob?</a><br />
<a href=”www.hereswhyyoushouldcare.info/why_should_i_care.php”>Why should I care about Bob?</a><br />
<a href=”#”>An empty, no good, showoff link.</a><br />
</body>
</html>