Untold Mysteries of CSS
- Universal Selector
- !Important or Not?
- Multiple Classes
- Mysteries Revealed
Three CSS features you might not know about include the universal selector, !important keywords, and multi-classes. Sure, if you're knee-deep in CSS and standards-based design, you've probably seen at least one of these techniques, but the broader developer audience is sure to find these under-described aspects of CSS extremely useful, too.
Universal Selector
The universal selector is represented by the asterisk: *. It can function as a wildcard, just as you'd expect. Here, I've applied the universal selector to a style declaration:
* {border: 1px solid orange;}
Every element in the (X)HTML document is now styled with a one-pixel solid orange border (see Figure 1).
Figure 1 Notice that all the elements are styled, including the html element (the border surrounding the viewport) and the body element.
The universal selector can be combined with other selectors. Doing so causes a jump across a generation and passes styles only to descendent elements beyond any child elements. Surely many parents have occasionally wanted to select only grandchildren and beyond, but write the children out of the equation!
Consider this rule:
#content * p {border: 1px solid orange;}
No child paragraph elements of the #content div will be selected, but any descendents further on down the line will be selected.
NOTE
Most all compliant browsers expect a space between the universal selector and any other selector.
Check out the following HTML:
<div id="content"> <h1>The Black Cat</h1> <h2>By Edgar Allen Poe</h2> <p>I married early, and was happy to find in my wife a disposition not uncongenial with my own. Observing my partiality for domestic pets, she lost no opportunity of procuring those of the <a href="http://vig.prenhall.com/">most</a> agreeable kind. We had birds, gold fish, a fine dog, rabbits, a small monkey, and a cat.</p> <div id="nested1"> <p>Here's a grandchild paragraph, which is in fact selected.</p> <div id="nested2"> <p>Here's a great-grandchild paragraph, which is in fact selected.</p> </div> </div> <p>This latter was a <a href="http://vig.prenhall.com/">remarkably</a> large and beautiful animal, entirely black, and sagacious to an astonishing degree. In speaking of his intelligence, my wife, who at heart was not a little tinctured with superstition, made frequent allusion to the ancient popular notion, which regarded all black cats as witches in disguise. Not that she was ever serious upon this point - and I mention the matter at all for no better reason than that it happens, just now, to be remembered.</p> <div id="nested3"> <p>Here's a grandchild paragraph, which is in fact selected.</p> </div> <p>Pluto - this was the cat's name - was my <a href="http://vig.prenhall.com/">favorite</a> pet and playmate. I alone fed him, and he attended me wherever I went about the house. It was even with difficulty that I could prevent him from following me through the streets.</p> </div>
Figure 2 shows the results.
Figure 2 Only descendants beyond child elements are styled.
The universal selector is rarely used as intended, in part because it's unknown to many folksespecially those accustomed to working with visual editors rather than hand-coding. Its appropriate use is also limited to universal and descendant styles, or in diagnostic testing by developers.
What's more, Internet Explorer has a bug where the universal selector is concerned, and it's not just IE 6.0 for Windows, either. Macintosh 5.0, 5.15, and 5.21; and Windows 5.0, 5.5, and 6.0 all have the bug present. That's in both quirks and standards mode.
The bug, referred to as the Star HTML Selector Bug, causes IE to misinterpret the universal selector (see Table 1).
Table 1 Browser Interpretations as Applied to html and body Elements
Selector |
In IE, Interpreted as |
Correct Interpretation |
* html |
html |
Matches to no element, because html is root and can never be a grandchild element |
* * body |
* body |
Matches to no element because body, although a child of html, can never be a grandchild element |
* html body | html body | Matches no element |
So here we have a case in which these selectors, although valid syntactically, are connected to no elements whatsoever in browsers that correctly interpret them. In IE, the selectors are improperly interpreted, and IE will apply a style!
Of course, any time syntax is misinterpreted by a browser puts that syntax in perfect line to be exploited for CSS hacking because using them will filter styles to those versions of IE but not to any other contemporary browsers.