|
|
||||||
|
|
![]() |
|
![]() |
|
||
|
|
||||||
Cascading Style Sheets: To Hell with Standards
Obviously, Sucky had seen better times. There he was, curly matted hair, limping on one hind leg, and barking at me. I decided that Sucky, my neighbor's, well, dog had a bad interface. Hmmm, I thought, maybe a makeover might be in order. So I trotted over to my neighbor's house, Sucky in tow, to share my thoughts on redesigning Sucky's look and feel. I was surprised to find that my neighbor didn't share my enthusiasm. Rich felt that while the dog didn't necessarily meet the standards of the neighborhood, Sucky's appearance and demeanor were sufficient to scare off any prowler -- in other words, he served his intended purpose.
I've talked little about the presentation of HTML and XML up to this point, so I thought I'd spend the next couple of columns covering this important topic. The story begins with Cascading Style Sheets (CSS) because few production Web sites actually use style sheets. The problem is that browser support is inconsistent, to say the least. Just like Sucky, Web developers would rather limp along with one bad interface than try to please the entire browser neighborhood.
This month, I'll reintroduce you to Cascading Style Sheets, Level 1 (CSS1), which is now part of the HTML 4 standard. We'll also look briefly at the latest features in CSS2. I'll also examine the similarities and differences in how each browser supports these standards, which is essential if you want to keep up with the big dogs.
CSS1 in a Nutshell
The tag line of my BeyondHTML.com Web site is "Separating Presentation from Semantics." And this is precisely the goal of CSS: to separate the formatting or presentation of a document from its content. That's a good thing, because CSS lets you easily change the way your document is presented while simplifying the actual markup. Beyond those noble goals, CSS is now part of HTML 4, and the old ways of embedding formatting information into the document are going away.
The original CSS1 specification defines a rule-based language that lets you describe how objects (especially text) can be rendered on the screen. For example, a rule could say that all paragraph text should be rendered using a 12-point Helvetica font with a font color of black, while all level-1 heads should be rendered in red with an underline. Rules for describing the
<H1>and<P>elements in this manner are shown in Example 1. These two rules can be placed directly in your HTML document using the<Style>element, or you can (as I prefer) place them in a separate file and include the rules using a<Link>tag. Now, all<P>and<H1>blocks will be displayed with the properties described by these rules.In looking over Example 1, you'll note the rule for the
<P>element describes a family of fonts and gives alternatives in case the first font style isn't available. While a discussion of typography is beyond the scope of this column, you'll find a basic understanding of fonts and typography useful when creating your own styles. Though its CSS coverage is a bit out of date, I still recommend the chapter on fonts in Cascading Style Sheets by HŒkon Lie and Bert Bos (Addison Wesley, 1997). Also, Craig Kanarick provided an excellent presentation on typography in this magazine (see "Dynamic Digital Design," May 1996).To see the effect that styles have on your HTML, compare the document in Listing One to that in Listing Two. Listing One is a typical HTML document with formatting handled inline, while Listing Two is the same document with styles applied. With the exception of the drop-cap we've created for the first letter in the document, the markup in Listing Two is much simpler. (I'll say more about the drop-cap in a moment.) More importantly, you can create different styles for the same document and present it in different ways without changing the original document.
The CSS specification also describes a "box" model in which a document can be viewed as a box that contains other boxes (or objects). These boxes, which represent elements in the document tree, can also contain other, smaller boxes. For example, the
<BODY>of your document can contain a paragraph element (<P>), which can contain a bulleted list, which can in turn contain italicized text (<I>), and so on. Different box types are generated for block-level elements like<P>and inline elements such as<I>. Figure 1 shows how boxes for the elements in Listing Two would be created according to this visual formatting model.Each box has its own set of properties, including borders, margins, and padding; see Figure 2. You set these properties in your style rules and you can control the creation of new boxes by setting the
displayproperty to eitherblock,inline, orlist-item(CSS2 adds two more types). The browser uses this information to lay out your document in terms of these boxes. But despite the standard, Internet Explorer and Navigator handle the layout of boxes differently, and you'll have to be careful if you want your styles to look and behave the same in both browsers (see "Browser Support for CSS," next page).Returning to Listing Two, you'll notice the statement
<DIVCLASS="DropCap">. Another important feature of CSS is the ability to define classes for block-level (<DIV>) and inline (<SPAN>) elements. In effect, this lets you create your own formatting tags. For instance, Example 2 shows the rule for the drop-cap. Note that the rule's name, called its "selector," is prefixed with a period. In this case, the properties set the font size and style, create a red background for the drop-cap, and draw a border around it. Thefloatproperty lets you flow text immediately to the right of the drop-cap, giving the desired affect.CSS Positioning
One problem with the box model in CSS1 was that boxes could only be positioned based on the borders, margins, and padding of their containing boxes. And while boxes could either be nested or placed below each other, they could not be placed side by side or stacked on top of each other. So the W3C quickly followed CSS1 with an extension, CSS Positioning, that lets you place boxes based on either an absolute position in the document, or a position relative to a containing box.
To demonstrate the usefulness of positioning, let's create a style sheet to render magazine articles. Let's assume you have a navigation bar you want to place on the left-hand side of the screen, and further assume that you want to create a left-hand margin so the article doesn't crowd the navigation bar. Currently, everyone on the planet uses tables to achieve both effects. However, we can use absolute positioning to achieve the same result. Example 3 defines new class elements for a headline, subtitle (dek), and copy, which can be used to format the article, and introduces a new
NavBarclass to format and position the navigation bar. Listing Three shows how you combine these into a Web page to get the desired effect.Positioning also introduces a layering model that lets you layer or stack boxes on top of each other. Each box is rendered according to a stacking order and boxes with greater stack levels are formatted in front of boxes with lower stack levels. Through the magic of JavaScript, you can hide and/or reveal the different layers to achieve various effects, including animation. Although a layering model was originally introduced in Navigator, this model varies significantly from that described in the current positioning standard. For additional information on the early positioning model see "Positioning with Cascading Style Sheets" by Chuck White (Web Techniques, December 1997).
New to CSS2
Cascading Style Sheets, Level 2 was released as a W3C Recommendation in March 1998. We're not seeing many examples of CSS2 simply because, until recently, it was virtually unsupported. Nevertheless, CSS2 adds a ton of interesting features including enhancements to CSS positioning. I'll provide a quick rundown on the new features and describe some changes from CSS1. For more information on CSS2, see Eric Meyer's article, "What's New in CSS2," in the January 1999 issue of Web Techniques.
First, CSS2 extends absolute positioning with a new property called
fixed. Fixed positioning was added to support the new media types that have also been introduced. These new types let you target scrolling media (the browser window), paged media such as printed documents, transparencies and pages displayed on screen, and other specialized devices such as speech synthesizers, refreshable Braille displays, hand-held devices, projection screens, and even television. This leads to the introduction of another significant addition: aural style sheets.CSS2 also introduces styles and properties for rendering tables and adds support for list-numbering styles, bidirectional text, and language-sensitive quotation marks. In addition, an enhanced font-selection mechanism now supports downloadable fonts, adjustable font sizes, system fonts, and more. New box types have been added as has a new
inheritvalue for all properties. Selectors have been extended to supportchild,adjacent, andattributeselectors. And the visual formatting model has been enhanced in many ways. For example, you can now control content overflow, clipping, and visibility, specify minimum and maximum heights and widths, and add text shadows. Finally, new pseudoclasses similar to those found in Internet Explorer 4.x (for example,hover) have been added.In addition to the new offerings, CSS2 makes minor changes to CSS1. If your style sheets break under the new model, one of the items in Table 1 may be the culprit.
Browser Support for CSS
This all sounds great, but what's in it for us? The answer depends on which browsers your Web site supports. The recently released Navigator 4.5 makes little "documented" progress over its older 4.0 precursor. For example, Navigator still employs an incompatible
<Layer>model, which, as I mentioned, was introduced prior to CSS positioning. Whenever you define a position asabsoluteunder Navigator, you automatically create a layer. The problem is that layers in Navigator are independent boxes. Worse, layers in Navigator do not inherit from their parents. So, both layout and behavior are affected.For example, Listing Three nests
<H1>and<P>elements along with theDek,Byline, andDropCapclasses all within theCopyclass, which are all defined in Example 3. According to the box model, the browser should create theCopybox and place boxes for the other elements within this box. In terms of layout, the elements should be positioned based onCopy. This works in Internet Explorer. Navigator, however, creates each box as an independent layer. So in lieu of any absolute positioning information, everything is positioned from the top-left corner of the document.Another complaint I have is that Navigator is far less tolerant of incorrect syntax: Any mistakes will result in the entire style sheet rule being ignored. For example, including height and width properties causes the copy rule to be ignored, so the text will not be properly positioned. Another problem is that Navigator does not appear to properly support
<DIVclass>for block-level elements. However, Navigator does support<DIVID>. The difference between the two is that ID must be unique within the document. Thus, you can work around the<DIVclass>problem in limited cases. In all fairness, the Mozilla project, Netscape's experiment with the Open Source development community, promises to include a completely reworked "style engine." However, this was not ready for general consumption at the time of this writing.My latest experience with Internet Explorer has been with the Internet Explorer 5 beta (unofficially referred to as beta 2, to differentiate it from the Developer Preview). If the Internet Explorer 5 beta would stop thrashing my dial-up connection and crashing occasionally, I'd be much happier with its CSS2 support! But that's the beta. Presumably, the new browser will be generally available by the time this reaches print. The beta indicates compliance with the major CSS2 features. And Internet Explorer seems to properly handle the way attributes are inherited. However, not everything seems to be implemented. For example, CSS2 includes new support for collapsible lists. That is, when a list element is hidden, its box is no longer considered in the layout. Therefore, the box for the next list element takes its place in the layout, giving the appearance that the list has collapsed. Oddly, Internet Explorer seems able to support the
collapseproperty, at least for lists. You can hide a list item by setting itsvisibleproperty to none. However, the box for that item will still be included in the layout, leaving a blank line where the item was.Strangely Quiet
I've heard darned little in the press about CSS2. The reason may be that browser support is inconsistent, to say the least. Consider that while CSS2 was issued as a W3C Recommendation nearly a year ago, limited support is just now showing up in the beta version of Internet Explorer 5, and is virtually nonexistent in the recently released Navigator 4.5. As mentioned above, my tests show that Navigator 4.5 still lags in its support for CSS1 and maintains features that are incompatible with the specification. In other areas, features are supported, but behave differently under the two browsers.
To use CSS features, Web developers need to know that they will behave predictably in both browsers. With standards in hand, we need consistent browser support to reliably use these features. To that end, I'm compiling a list of compatibility issues between the major browsers and the CSS specification (both Level 1 and Level 2), which I'll post at BeyondHTML.com. If you run into a compatibility problem, I'd love to hear from you. Until then, to hell with standards!
(Get the source code for this article here.)
Michael is the publisher of BeyondHTML.com and serves as Web Techniques' editor at large. He can be reached at www.BeyondHTML.com.
|
|