Give the Browsers CSS They Can Digest

Get Help With All Aspects of Web Design & Design Software

Moderators: Moderator, Global Moderator

Post Reply
Tami
Administrator
Administrator
Posts: 10892
Joined: Sun Apr 25, 2004 1:05 pm

Give the Browsers CSS They Can Digest

Post by Tami »

Give the Browsers CSS They Can Digest
By Chris Heilmann

Some but not all browsers support CSS2. You can deliberately code your website so that users of either kind of browser will see pages that are appropriate for what their browser can handle. Older browsers won\'t gag, but you will still be able to take advantage of what you can do with CSS2 in the newer browsers. Read on to find out how.

When surfing the Web, one might encounter websites that look completely different in Microsoft Internet Explorer and Firefox/Opera. We don’t mean websites with bugs, or ones that were developed for MSIE only. We’re talking about websites deliberately showing a different style in the two of them. One example would be this CSSZengarden submission: (http://www.csszengarden.com/?cssfile=http://icant.co.uk/zen/sample.css).

The reason for these websites is to show how much more a browser that properly supports CSS2 can offer. This technique is called progressive enhancement (http://css-discuss.incutio.com/?page=ProgressiveEnhancement), or graceful degredation (http://www.anybrowser.org/campaign/
abdesign.html#degradability) - depending on which way you look at it – from newer to older or older to newer browser.

It is nothing new - clever Web developers have done to same to send a basic style sheet to older browsers like Netscape 4, and a different one to more advanced browsers:

[code]<link rel="StyleSheet" href="basic.css" type="text/css">

<style type=”text/css”>@import “advanced.css”;</style>[/code]

Netscape 4 does not grasp the @import directive and applies basic.css exclusively. More modern browsers also read advanced.css and overwrite or re-use what has been defined in basic.css. The same can be done today for yet a newer breed of browser. This can be achieved in several ways.

One widely used mistake is to bind the style sheet to the browser, rather than its capabilities. Developers use javascript to determine the browser and write out bespoke style sheets via java script:

[code]document.open();

if(navigator.appName == "Netscape"){

          document.write(\'<link rel="StyleSheet" href="netscape.css" type="text/css">\');

}

if (navigator.appName == "Microsoft Internet Explorer") {

          document.write(\'<link rel="StyleSheet" href="ie.css" type="text/css">\')

}

if (navigator.userAgent.indexOf("Opera") != -1){

          document.write(\'<link rel="StyleSheet" href="ie.css" type="text/css">\')

}                    

document.close();[/code]

This not only means that users without javascript will not get any styles whatsoever – something that happens in Netscape 4 anyway – but it also means that the styles need to be maintained in all those files. Furthermore, browsers that allow the user to mimic others, like Opera, might get a style sheet they cannot display at all. Browser sniffing (http://www.quirksmode.org/js/detect.html) is not future proof, and in most cases it\'s a waste of time. This also applies to solutions that chose the lesser evil – object detection(http://www.quirksmode.org/js/support.html).

[code]    document.open();

   if(document.layers){

              document.write(\'<link rel="StyleSheet" href="netscape.css" type="text/css">\')

   } else if (document.all && !document.getElementsById){

              document.write(\'<link rel="StyleSheet" href="ieold.css" type="text/css">\')

   } else if (document.all && document.getElementsById){

              document.write(\'<link rel="StyleSheet" href="ienew.css" type="text/css">\')

   } else if (document.getElementsById){

              document.write(\'<link rel="StyleSheet" href="ienew.css" type="text/css">\')

   }

   document.close();[/code]

A lot of developers have spent a lot of time to find out about the differences and fallacies of the different browser engines, and come up with a lot of hacks for how to send a special style to this or that browser (http://centricle.com/ref/css/filters/) or how to hide some rules from that or the other.

Amazing as this feat might be – and on certain occasions it is a life saver – it still binds us to the browser, rather than concentrating on following standards and making sure our code will work in the future, too.

The topic of browser hacks is very vast indeed (http://css-discuss.incutio.com/?page=CssHack), and there are some good articles published about it, along with some very good resources. Still, browser hacks should be used as a last resort. If some browser rigorously claims to be able to show a certain style, but fails terribly to comply, it is time to apply a browser hack to teach it some manners.

What most browser hacks do, though, is make our CSS invalid and hard to maintain. If we work in a distributed developer environment, browser hacks should be properly commented to avoid confusion further down the line.

Let’s try to do the right thing, and cast aside the idea of Web development catering the whims and problems of browsers and concentrate on implementing standards instead.

Styles can be applied in different ways to an HTML document:



1. Via the LINKtag
2. Inline, via a STYLEtag
3. Inline but external via the @import directive
4. Inline via the style attribute

Option four should also go in the “only in direst emergencies” folder. There is no sense to applying styles on a tag level, as it mixes presentation with structure and turns maintenance into a nightmare. The same applies to the second option; inline styles only get applied to one document, whereas the real power of CSS is that you maintain them in one spot and apply them to all documents in a site

This leaves us with option1, the LINKtag and stylesheet applied via the @import directive.

Almost, as now we delve into the depth of CSSand find that there are several selectors to choose from:

1. The plain vanilla Type Selector (http://www.w3.org/TR/REC-CSS2/selector.html#type-selectors)
2. The Child Selector (http://www.w3.org/TR/REC-CSS2/selector.html#child-selectors)
3. The Adjacent SiblingSelector (http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors)

The CSSspecifications offer us much more fun to be had (http://www.w3.org/TR/REC-CSS2/selector.html), including simple, exact and partial attribute selectors, language selectors and various flavours of pseudo selectors. Let’s discard these for the moment, and keep them in mind for a good night’s read when we can use them to reach more than a small percentage of our visitors.

Type selectors like body{background:#000;} are understood by nearly all browsers around today (including official non-CSS browsers like Netscape 4.x). Child selectors like DIV>P or Adjacent Sibling Selectors like DIV+Pare are only supported by newer browsers, excluding Internet Explorer on Windows. This is something we can use to our advantage. Incidentally, the child selector is mentioned as a CSS hack in some of the resources. However, it is not a hack, it is valid CSS2 and there is nothing hacky about it.

It is pretty hard finding useful examples for the child selector, but basically it can save some hassle, for example in the following HTML:

[code]    <div>

   <p>Content 1</p>

   <ul>

       <li><p>Content 2</p></li>

       <li><p>Content 3</p></li>

   </ul>

   <p>Content 2</p>

   </div>[/code]

We want all the P elements outside the list to have a background, but the ones inside the list to have none.

What we could use is:

[code]div p{background:#036;}

div li p{background:transparent;}[/code]

which can be replaced on real CSS2 browsers with:

[code]div>p{background:#036;}[/code]

Adjacent sibling selectors

These selectors allow us to match exactly the next element in the node tree. For example, they allow us to only apply a margin to a paragraph when it is not following another paragraph. If it does follow another paragraph, we won’t apply a margin, but indent the text – much like you do in books:

[code]p {margin:.5em 0 0 0;}

p+p {margin:0;text-indent:1em;}[/code]

Now, as MSIE on PC does not support the child selector, we can ensure that only browsers that can deal with certain styles get them. Normally this is done by preceding them with a html>body construct. This matches every BODY element inside the HTML element, a rather pointless definition in HTML documents, as those only allow for one body, but it makes sure that these styles are applied document-wide.

Example: An article style sheet

Let’s create a style sheet that makes it easy to read articles. We start with a properly marked up, valid HTML document (http://icant.co.uk/forreview/generating_nocss.html) that forces the browser to render in standards mode. This is all we will give old browsers like Netscape 4.x.

For newer browsers, we apply the stylesheet \"articles.css\" (http://icant.co.uk/forreview/articles.css) for screen display and \"print.css\" (http://icant.co.uk/forreview/print.css) for printouts:

[code]<style type="text/css" media="screen">

        @import "articles.css";

   </style>

   <link rel="StyleSheet" href="print.css" media="print" type="text/css" />[/code]

The document has a table of contents linking to different headlines in the document via their ID. For non–CSS browsers this one gets displayed before the content. For the others, we want to display the table of contents next to the main text. We achieve that by positioning the TOC absolutely and giving the content a margin. Giving the content a vertically repeater background separates it from the TOC even further. We can apply a background to the content, as we know that it will always be longer than the TOC, otherwise, we’d have to use a background on the parent element of the two.

[code]#toc{

   position:absolute;

   top:0;

   z-index:10;

   right:1em;

   width:17em;

}

#content{

   margin:0 16em 0 0;

   padding:0 2em 0 0;

   background:url(tocback.gif) repeat-y right 0 #f8f8f8;

}[/code]

The rest of the styling is more or less eye-candy. We define how links look in the content and the TOC, the same for lists and headlines. As technical articles often feature code examples that may break the layout, we set the overflow attribute of those to scroll, forcing the browser to display a scrollbar instead of expanding the whole page horizontally.

[code]#content pre{

   margin:1em 3em;

   width:35em;

   overflow:scroll;

   padding:.5em;

   border:1px solid #999;

   background:#eee;

}[/code]

That is as far as we go for CSS2 challenged browsers like MSIE. For the Gecko, Opera or KHTML browsers out there, we go further by fixing the TOC to stay next to the content at any time.

[code]html>body #toc{

          position:fixed;

}[/code]

This, however, renders the “back to table of contents” links useless, as the TOC never leaves the screen. Therefore we hide them:

[code]html>body #content p.backlink{

          position:absolute;

          left:-999em

}[/code]

The multi column layout of the screen does not make much sense on a printout, since all but the first page would have a useless gap on the right. That’s why we keep the TOC inline, and only define the colors, sizes and typefaces. Furthermore, we get rid of all backgrounds and knickknack to make the printout as small as possible.

Once again, the “back to table of contents” links become useless.

[code]p.backlink{

   display:none;

}[/code]

This is as far as it goes for MSIE and other CSS2 challenged browsers. For the rest, however, we can do a lot more.

First of all, we don’t want to have paragraphs with margins in between them, but text indentation for those that follow other paragraphs:

[code]html>body #content p+p{

   margin:0;

   padding:0;

   text-indent:2em;

}[/code]

For our footer, we need to overrule this setting, otherwise it’d be squashed against the text.

[code]html>body #content p+p#footer{

   margin-top:1em;

   padding:2px 1em;

   border-top:1px solid #000;

   background:#ccc;

   text-indent:0;

   text-align:left;

}[/code]

When printing out online texts it is rather annoying that you cannot see the destination to which inline links point. You’d need to go back to the online version of the article to follow these links. Clever webzine content management systems overcome this problem by providing a list of links at the end of the article. With CSS2, we can work around the link problem by re-using the href attribute of inline links and display it after them:

[code]#content a:after, #footer a:after{

   content: " (URL:" attr(href) ")";

   background:#ddd;

}[/code]

This generates a message with the location of the linked document after each link in the content and the footer. For the TOC, we need to overrule this setting, as we don’t want these links to be displayed:

[code]#toc a:after{

          content:\'\';

          color:#000;

}[/code]

That’s all. Our article style sheet applies itself to all the browsers that can show the “special effects” and only send easily digestible CSS to the others.

[url=\"http://www.devarticles.com/c/a/Web-Style-Sheets/Double-Vision-Give-the-Browsers-CSS-They-Can-Digest/\"]source[/url]
Image

[color=\"#41211C\"]It takes years to build up trust and only seconds to destroy it

[/color]
Post Reply

Return to “Web Design Principles”