June 26, 2009 | David Raffauf
One of the most powerful but overlooked features of CSS is the ability to use CSS selectors to pinpoint content and style it. Here are the advanced CSS selector tips I use everyday.
By keeping all my styles specifically applied to the "poll" table I can guarantee they aren't accidentally applied to other tables in the future.
table#poll {}
table#poll tr {}
table#poll tr th {}
table#poll tr.odd td {}
table#poll tr.even td {}
If you decide in the future you like this style for all your tables, just remove the ID in the CSS. There's no harm in having the ID set in the HTML of the poll table.
table {}
table tr {}
table tr th {}
table tr.odd td {}
table tr.even td {}
Or, if this is one of a few styles, just change the ID to a class:
table.poll {}
table.poll tr {}
table.poll tr th {}
table.poll tr.odd td {}
table.poll tr.even td {}
It's not uncommon to have deeply nested HTML. Let's assume you have a div#wrapper that contains some layout divs. To keep this simple let's say you want to set their border to gray.
div#wrapper div { border: 1px solid #ccc; }
Everything looks good. But maybe you want to add some divs inside your layout divs. Since we've used the descendant selector, these new divs will also receive a gray border. Before I knew better I attempted to fix the issue doing this:
div#wrapper div div { border: none; }
The problem is that you'd have to define an infinite list of nested div selectors to cover all the cases. The right way to handle this is to use a child selector from the start:
div#wrapper > div { border: 1px solid #ccc; }
Now, no matter how many nested divs are within your layout divs they won't receive the border.
If you're daring enough to use CSS to wrangle a form's appearance you've probably run into CSS like this:
input[type=text] {}
But did you know this is a generic pattern you can apply to any element? You could warn yourself about images with no alt tags with this style:
img[alt=""] { color: red; }
There are other patterns that let you look for substrings, first characters, and last characters of attributes. If you wanted to add an icon after all your .pdf files you could do this:
img[src~=".pdf"]:after {
content: '
';
}
I still have to remind myself that there's usually a better solution attainable via advanced selectors than adding more HTML that's really style related.
Let's say you've got a photo gallery. You tag all your photo img elements with the class "photo":
But you also need to highlight recent additions.
So how do you say you want to select recent photos in CSS?
img.photo.recent { border: 2px solid blue; }
This is a practical tip that I use almost everyday. When I didn't know this I ended up with bloated HTML with lots of additional span tags.
If you want to get even fancier there are additional examples you can find in the O'Reilly CSS Pocket Reference. You can select siblings for example by doing this:
h2 + p {}
But I personally haven't run into many interesting uses for this kind of specificity. It's nice to know it's there for when I inevitably learn what it's super useful.
Thanks for reading this quick review of underused CSS tricks. It's by no means comprehensive but hopefully it will whet your appetite for finding simpler solutions.
thanks a lot for those important tips