The Universal Selector effectively assigns a rule to every element. This declaration is equivalent to a grouped selector that lists every single element contained within the document and enables you to assign a style to every element in the document in a concise rule.
General Syntax for the Universal Selector
* { declarations... }
This page is an example of the universal selector in action. The following rule makes (nearly) all the elements on this page blue:
* { color: #06C; }
Why isn't all of the text on this page blue? Well, that's another topic that we'll be discussing in a few pages, the cascade. In terms of the rules of specificity when considering weight and precedence of rules in the cascade, the universal selector is not considered, so the properties declared by the universal selector are readily superceded. Quite simply, any rule that comes along can override conflicting declarations in the universal selector. It will all become clear when I explain specificity and the cascade later in this lecture.
Let's look at a common application of the universal selector. Modern browsers apply default styles to HTML tags, so that unstyled pages are displayed in a predefined, browser-specific way. For example, P tags and other block-level elements will typically have vertical space between each block-level element. Some designers, in order to have complete control over spacing between elements, will include the following rule at the beginning of the style sheet:
* { margin: 0; padding: 0; }
This effectively eliminates default spacing between all block-level elements, leaving the designer free to establish the spacing via style sheets. Of course, the downside of this is that the designer must create a rule to set spacing for every block-level element that needs it.
You might be asking yourself, "How is this different from resetting margin and padding for the BODY tag as follows:"
body { margin: 0; padding: 0; }
Well, we haven't discussed this yet, but it all comes down to inheritance. Margin and padding properties do not trickle down to descendant elements like many other properties do, so resetting margin and padding for the BODY element doesn't have the document-wide effect that you are trying to achieve. We'll talk more about inheritance in a few more pages. Stay tuned ...
You can specify the universal selector as the target in a descendant selector so that you can apply a style to all of the tags that descend from a particular page element, such as a container DIV. This example demonstrates a page that has separate DIVs for the header, content, and footer. In this example, the following universal selector is used to color all the text in the content DIV red.
#content * { color: red; }
Granchild (or later) Selector
The Stylin' book explains a very interesting use of the universal selector. The author describes it as the inverse of the child selector, stating that the selector targets a descendant element—as long as it is not a child.
The general format of the rule is:
ancestorElement * granchildTag { declarations ... }
Here's the author's example:
p * em { color: blue }
Quoting the text "Here, any EM tag that is at least a grandchild of the P tag, but not a child, is selected; it doesn't matter what the EM's parent is." This statement is accurate with respect to the example, only because you can't have a P that's an ancestor of another P. Nevertheless, you should ignore the "not a child" clause, because it is not valid when the ancestor is a generic DIV or SPAN element.
To see why this is the case, let's examine the following document hierarchy:
<body>
<div>
<div id="header">
<div id="title"> <<-- This DIV is a grandparent of H2
<div id="author"> <<-- This matches '*'
<h2>
Note that the H2 tag is a child to the "author" DIV.
To target the H2 tag, we specify the following rule:
div * h2 { color: blue; }
The div * h2 selector can be interpreted as
"Target a H2 element that is a grandchild or later descendant of any DIV element."
In other words, the DIV must be an ancestor of any element that is an ancestor of the H2 element.
In this example, the H2 element is a child of the "author" DIV, and yet the selector correctly targets the H2 tag. As long as a DIV element is the grandparent of the H2 tag—the parent of the H2 can be any element, even another DIV.
The key points are that the H2 tag must be a granchild or later descendant of any DIV tag. Restated, the DIV tag must be an ancestor of any element that is an ancestor of the H2 tag. However, with DIVs, you can have a DIV be an ancestor of another DIV, so the parenthetical clause "but not a child" is not valid in the case of DIV (or SPAN) ancestors. The specified ancestor must be at least a grandparent, and it doesn't matter what any of the intermediate ancestors are.