This is Cereal: The cascade and layering effects


Shaun Inman, Designer

www.csszengarden.com/057

SHAUN INMAN SURE LIKES a balanced breakfast. Armed with a box of Post Fruity Pebbles, a twist of parody, and the urge to break some rules, Inman opted for breakfast-oriented imagery to form the basis for the wholesome and delicious This is Cereal. Fortified with special effects for advanced browsers, his design pushes the boundaries of what the Zen Garden markup allows.

Because a large percentage of the population still uses browsers not on the bleeding edge of CSS support, Inman has ensured that the design degrades gracefully. But the extra-tasty special effects are saved for those that support them.

What might have been a controversial move for most Web sites works perfectly in the Zen Garden, which is all about experimentation and continual progress.

The Cascade

The menus and transparencies in This is Cereal are only possible in a highly CSS2-compliant browser like Firefox. Applying this type of enhancement selectively involves various CSS filters and hacks that tap into the power of the cascade.

Tip

More on specificity and inheritance can be found in the CSS spec, in "Assigning property values, Cascading, and Inheritance" (www.w3.org/TR/REC-CSS2/cascade.html).


What is the "Cascading" part of Cascading Style Sheets, anyway? The W3C says, "The CSS cascade assigns a weight to each style rule. When several rules apply, the one with the greatest weight takes precedence." Two related concepts, specificity and inheritance, can be your best friends and your worst nightmares ... although not necessarily in that order.

CSS allows for the styling of multiple elements at once. Without some way to combine and apply style rules to multiple items, CSS files would likely have to implement some form of one-to-one matching between style rules and elementsan impractical and unwieldy idea.

Inheritance

The ability exists to apply style to generic elements and sets of elements that match certain criteria. A style rule applied to h3 elements is applied to all h3 elements within a page (FIGURE 1):

Figure 1. All H3 elements on the page are colored red.


 h3 {  color: red; } 

So every occurrence of an h3 element on this page would be red. Simple. What if you want to override this for some h3 elements but not others? You need to apply an additional class (FIGURE 2):

Figure 2. h3 elements with the class archives are colored green; all other h3 elements remain red.


 h3 {  color: red; } h3.archives {  color: green; } 

The first style rule generically colors all h3 elements red, while the second rule overrides it only on those with an extra class of archives.

There's nothing overly complicated happening yet, so let's try something a bit trickier. Given the following style, how are H3 elements within #linkList styled (FIGURE 3)?

Figure 3. A combination of style rules produces a green header rendered in Verdana at 0.8em.


 h3 {  font: 1em Verdana, sans-serif;  color: red; } h3.archives {  color: green; } #linkList h3 {  font-size: 0.8em; } 

They are colored red, and render as 0.8em Verdana (or a sans-serif backup if Verdana isn't available). Because the font family isn't overridden with a new value in the last rule, Verdana is inherited from the earlier global h3 style rule; only the size changes. And assuming the H3 element or elements in question have also been given the class archives, they will be colored green.

Specificity

The previous example also shows specificity in actionit gives the last style rule a higher priority than the first. Because an extra class was defined, the entire rule is weighted as more specific than the first and takes precedence.

If this concept of specificity didn't exist, the two rules would have to compete for precedence, since an h3 can't have values of both 0.8em and 1em simultaneously. Specificity is a simple way of setting pecking order, and making sure there's a reliable method for determining ahead of time which one wins out.

It seems simple, but specificity comes with its own set of challenges. It's entirely possible to become overly specific in a style rule and create conditions where the only way to override values is to create an even more specific rule.

Case in point:

 body>html #header ul.navigation li.home a {   color: red; } 

What happens when you want to color the :hover state of the link blue instead? You have to go a step further by duplicating that long list of selectors and adding something even more specific to target the :hover state:

 body>html #header ul.navigation li.home a:hover {  color: blue; } 

Controlling Specificity

A certain amount of forethought can go a long way toward avoiding complex and entangled selectors that are far too specific. The rule of thumb is to be as generic as possible in style rules, and only become more specific when the need is presented.

For example, contrast this selector:

 #linkList ul li h3 {  color: red; } 

with this one:

 #linkList h3 {  color: red; } 

The first example provides many extra selectors that an h3 element must meet before being colored redit must be within an unordered list, and a distant descendant of a very specific identifier. The second example drops the list requirement but continues to require a specific identifier as a parent. When you start with the general and work granularly toward the specific, the ease of adding further specificity later on doesn't become an exercise in overly verbose style rules.

Debugging Specificity

Here's one simple tip for debugging CSS layout problems: Ensure that a specificity conflict isn't causing you to spin your wheels. When applying style that doesn't appear to be taking effect, the first thing to check is that your style rule is specific enough. To do this, it's often valuable to insert some overly obvious temporary formatting to make sure that the selector is actually targeting the element in question. For example:

 #linkList h3 {  border: solid 20px red; } 

If the h3 doesn't get the border, make the selector more specific. If it does, discard the border style and try something else, because specificity is most likely not the problem.

Overriding Specificity

An ability to override specificity for any given style rule is built into CSS. The !important declaration, applied on a per-attribute basis, is a quick way of making sure that regardless of the specificity of any other selector within the style sheet, that particular rule will be applied no matter what. For example:

 h3 {  color: red !important; } #linkList h3 {  color: blue; } 

Even though the second rule is more specific to h3 elements within the #linkList block, they will still be rendered in red text because the !important declaration in the previous rule ignores the greater specificity. Note that Microsoft Internet Explorer for Windows does not support !important, so the behavior cannot be relied upon.

However, Internet Explorer's lack of support can be seen as an advantage when debugging CSS; using the !important declaration to selectively render CSS in browsers other than Internet Explorer allows a certain amount of filtering. In the above example, the h3 elements in question could conceivably be rendered as red in browsers like Firefox, Opera, and Safari, but instead rendered in blue in Internet Explorer.

The cascade was put to strenuous use by This is Cereal in order to compensate for the lack of certain effects in certain browsers. In fact, Inman has filtered style so specifically that a cheeky message (FIGURE 4) greets users with browsers that should perhaps support these effects better than they do.

Figure 4. The message greeting viewers of This is Cereal using Internet Explorer.


Layering

The Internet Explorer message and other elements of the page are positioned absolutely, and a certain amount of care was applied to the layer order in order to prevent overlapping.

The z-index attribute is a valuable CSS control for the stacking order of positioned elements within a page. Because absolutely positioned elements are removed from the regular document flow, the default method of controlling overlapping often isn't good enough. Without a z-index value, positioned elements will stack from the bottom up; elements that appear first in the HTML will be placed on the bottom of the stack, and elements that come after will stack on top of them.

z-index controls stacking order and allows the designer to stack in any order desired. Potential values start at 0 and may be any integer. For example:

 #linkList h3 {  position: absolute;  top: 50px;  left: 50px;  z-index: 10; } #linkList ul {  position: absolute;  top: 50px;  left: 50px;  z-index: 20; } 

Placed in the same spot on the page, the H3 appears behind the ul no matter where it shows up in the HTML source, because its z-index value is lower.

Integration

The layering options CSS offers to the graphic designer should feel familiar; they closely correspond with related concepts in image-manipulation software. The cascade is a more programmatic concept without easy analogy in the world of design, but when mastered, it offers the control necessary to make sure that all elements interact gracefully, as This is Cereal successfully demonstrates.



    The Zen of CSS Design(c) Visual Enlightenment for the Web
    The Zen of CSS Design(c) Visual Enlightenment for the Web
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 117

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net