|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV SYS-CON.TV WEBCASTS |
MXDJ TOP LINKS YOU MUST CLICK ON ! Dreamweaver Avoiding CSS Pitfalls
Avoiding CSS Pitfalls
By: Zoe Gillenwater
Jun. 17, 2004 12:00 AM
CSS has been around for years, but many Web designers still do not think it is ready to be used extensively because of the host of browser rendering inconsistencies that exist. However, by knowing a few CSS hacks and tricks, you can learn how to write code that is cross-browser compatible and allows you to fully separate your content from its presentation. This article assumes you know what CSS is and have some idea how to use it to style Web pages, but is aimed at Web designers who have not yet taken the leap of using it as their primary layout method due to frustrations with browser inconsistencies. It also assumes you know the benefits of CSS-based layout and are eager to make use of it. Many of the hacks I'll go over depend on your document using a doctype that will put it into browsers' "standards rendering mode," so be sure you are using a proper doctype as well. (Dreamweaver MX 2004 uses such doctypes on its HTML and XHTML templates, so you should be good to go. If in doubt, read my article in the last issue of MXDJ or check out the CSS Wiki - http://css-discuss.incutio.com/?page=DoctypeSwitch - for information about doctype switching.) Squashing Bugs A word of caution: keep in mind that not everyone supports the use of hacks. Some developers argue that the browser failings we are forced to work around will never be fixed because our hacks create the appearance that everything is working correctly. Hacks can also be dangerous because they rely on browser bugs that may be corrected in future browser releases, rendering your hacks useless or perhaps introducing new problems of their own. However, by keeping our hacks in the CSS instead of the (X)HTML markup, we should be able to change or remove broken hacks in one central file and update an entire site if it becomes necessary in the future. If we're going to create the best experience for our users, hacks are a necessary tool in commercial Web site design - as long as they are used sparingly and thoughtfully with periodic testing to make sure they are still functioning correctly. Box Model In many cases, the box model problem can be worked around without any hacks. For instance, instead of applying padding to a box to get its content to move away from the edges, you can apply the padding to the content inside the box:
div {
width: 200px;
}
div p {
padding: 20px;
}
But we also wanted 2px borders on our box. You could choose to ignore the four pixel difference they would introduce in WinIE5.x - some layouts don't rely on such precision. Or, you could nest another div inside the first one and apply the borders to the nested div, but this mucks up your markup. What you really want is a way to give WinIE5.x a bigger value than other browsers use, a value that is equal to the total box width, including padding and borders, so that it can happily subtract them without making the box too small. Tantek Çelik developed a box model hack to do just that, and since then several simplified versions have followed. My favorite is the Modified Simplified Box Model Hack (MSBMH) developed by Edwardson Tan:
div {
width: 200px;
padding: 20px;
border: 2px solid red;
}
* html div {
width: 224px;
w\idth: 200px;
}
The first rule gives the correct width, padding, and border values to browsers that correctly implement the box model. The second rule is seen only by IE through the use of the Star HTML Hack. "* html div" tells the browser, "apply this rule to any div element that is a descendant of an HTML element that is a descendant of any element" (the asterisk is the universal selector and means "any element"). This rule is nonsense: HTML is not a descendant of any element - it is the root element - so this rule should not apply to anything and compliant browsers should (and do) skip over it. However, IE seems to ignore the universal selector when it precedes "html," so this rule gets applied by IE and IE only. The first width value in the second rule is read by all IE versions, giving WinIE5.x the total on-screen box width that it uses in its box model. Unfortunately, IE6 for Windows and IE5 for the Mac also see this 244px value, but they don't have a box model problem and need the correct 200px value. The second value with the backslash character sets things back correctly for these browsers. Since WinIE5.x cannot understand a rule with a backslash in it, it keeps the larger 244px value, and all other browsers including IE6 and MacIE5 get the correct 200px value, making things look the same cross-browser. Keep in mind that IE6 needs to be in standards-rendering mode for this to work correctly. Otherwise it will use WinIE5.x's incorrect box model, and since the hack only targets WinIE5.x, IE6 will not get fixed. The Star HTML component of the MSBMH comes in handy quite often: IE has a host of bugs, and the Star HTML Hack allows you to feed it different values when it's misbehaving. Three Pixel Gaps To get rid of the Three Pixel Float Gap, you need to assign the float a negative margin to pull the following box back against it. Let's say we're using the following code to create two columns that sit flush against each other:
#sidebar {
float: left;
width: 300px;
}
#content {
width: 400px;
margin-left: 300px;
}
We've assigned #content a margin-left exactly the same size as #sidebar's width so that they will sit flush against each other, but in IE the Float Gap shows up, preventing them from touching. Add the following hack below your regular rules to get rid of the gap:
/* hide from MacIE \*/
* html #sidebar {
margin-right: -3px;
}
* html #content {
margin-left: 0;
}
/* end hide */
We've used the Star HTML Hack above to give values to just IE, then enclosed it in a Mac Backslash Hack that hides the values from MacIE due to the backslash in the comment preceding the rule (a MacIE bug). Thus, only WinIE (the problem browser group) sees the hacked values. What if you do want some space between your boxes, you just want to kill the extra three pixels WinIE adds? Just give WinIE a margin-right that is three pixels smaller than it should be. Code I is an example that leaves 10 pixels between the two boxes. The examples in Code I have a width assigned to #content, but when you leave off this width, the Three Pixel Text Jog shows up. How can you get rid of the Text Jog if you have a fluid layout and can't assign #content a width? Holly Bergevin discovered that a height works just as well, and since IE will (incorrectly) expand a box's height to accommodate its content, you can assign a very small height and still keep your fluidity! Code II shows the Holly Hack to kill both the Float Gap and Text Jog. The Holly Hack can be used in a variety of situations when IE is misbehaving. If IE is doing something strange, check to see if the offending box has a dimension assigned. If not, try giving it a height of 1%, and often this will fix things. Peek-a-Boo Bug Doubled Float-Margin Bug The CSS:
#float {
float: left;
width: 100px;
margin: 10px;
}
The (X)HTML: <div id="container"> <div id="float">float</div> </div> Your reaction to this is probably, "I know! Use the Star HTML Hack to feed IE a halved value!". This would work, but luckily can be fixed even more easily and cleanly. Steve Clason discovered that if you apply "display: inline" to the float it gets rid of the doubled margin. Since "display: inline" on floats is ignored by other browsers (floats are block elements by definition) you don't even have to hide this rule from them via the Star HTML Hack! Easy. Flash of Unstyled Content <head> <title>My Page</title> <style type="text/css">@import "screenstyle.css";</style> <link rel="stylesheet" type="text/css" media="print" href="printstyle.css"> </head> If you decide to add a script to fix the problem instead, keep in mind that the script doesn't have to be in the head to prevent the FOUC. Placing it inside the body but before all visual content works just as well. Text Inheritance
table {
font-size: 1em;
}
This makes sure the font size of the table displays at the same size as the surrounding text, which it ought to do by default, so the rule doesn't need to be hidden from other browsers. Netscape Navigator (NN) 4.x also has major - and less predictable - text inheritance problems. Although you may want to present NN4.x with an unstyled version of your pages (using @import instead of <link> to call your style sheet), there may be times when you want to give it at least some basic text formatting. Since NN4.x often loses text properties at seemingly random spots in your page, it's best to explicitly set the text parameters on everything that could possible need them in NN's style sheet:
body, div, p, blockquote, ol, ul, dl, li, dt, dd, td {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
Opera has its own text problem when you set font-size to 100%: it computes it to be one pixel smaller than it should be. Using 100.01% instead of 100% fixes this. Horizontal Centering
body {
min-width: 700px;
text-align: center;
}
#wrapper {
width: 700px;
margin: 0 auto;
text-align: left;
}
Setting the left and right margins to auto centers #wrapper in the window because the margins are set to equal values. Since WinIE5.x does not recognize this technique, add "text-align: center" to the main div's container, in this case "body," to achieve the centering in that browser (this property won't work in other browsers because it's only supposed to center inline content, not blocks, but WinIE5.x ignores that little detail). Set a min-width on the body equal to the width of the centered box to avoid problems in Gecko-based browsers. If you don't set this min-width, when you size your window below the size of the centered box, its left side will get cut off without the ability to scroll over to the left to see the cut-off content (see Image IV). This is because when the window is too small, the auto margins must get set to negative values, thus extending the box equally off both sides of its containing block (in this case, the body). Containing Floats But don't worry - there is a way to overcome this behavior when your layout calls for it! All you need is a block-level element, set to clear the float, placed within the container but after the floated element. This forces the container to expand down around the element beneath the float, enclosing the float in the process. The CSS:
br.clear {
clear:both;
height:0;
margin:0;
font-size: 1px;
line-height: 0;
}
The HTML: <div id="container"> <div id="float">float</div> <br class="clear"> </div> Another easy way to contain a float is to float its parent: a floated parent automatically expands to hold children floats. While we're on the subject of floats, one caution: make sure you assign your floats an explicit width, as required by the CSS 2.0 spec. Although most browsers are lax about this (so much so that the requirement's been dropped from the upcoming 2.1 spec), MacIE takes floats that don't have a width and expands them to fill up their entire container. This is a problem if you are using floated <li>s to create a horizontal nav bar, for instance. In this particular case, you can float the <a>s inside the <li>s to get them to sit beside each other in MacIE, but most of the time you have to bite the bullet and give all floats a width to keep MacIE from expanding floats to 100%. Conclusion LATEST FLEX STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||