CSS hacks & browser detection
More and more web developers are ditching tables and coming round to the idea of using CSS to control the layout of their site. With the many benefits of using CSS, such as quicker download time, improved accessibility and easier site management, why not?
The problem with CSS
Historically the main problem with using CSS has been lack of browser support. This is no longer the case as version 5 browsers, which all have good support for CSS, now account for over 99% of browsers in use.
Instead, the problem is that browsers can sometimes interpret CSS commands in different ways, causing developers to throw their arms up in the air and switch back to pixel-perfect table layouts. Fear not though, as you learn more about CSS you'll gradually start to understand the different browser interpretations and realise that there aren't really that many.
How browser detection using CSS hacks works
The way browser detection using CSS hacks works is to send one CSS rule to the browser(s) you're trying to trick, and then send a second CSS rule to the other browsers, overriding this first command. If you have two CSS rules with identical selectors then the second CSS rule will always take precedence.
Say for example you wanted the space between your header area and the content to have a gap of 25px in Internet Explorer, or IE as it's affectionately known. This gap looks good in IE but in Firefox, Opera and Safari the gap is huge and a 10px gap looks far better. To achieve this perfect look in all these browsers you would need the following two CSS rules:
#header {margin-bottom: 25px;}
#header {margin-bottom: 10px;}
The first command is intended for IE, the second for all other browsers. How does this work? Well, it won't at the moment because all browsers can understand both CSS rules so will use the second CSS rule because it comes after the first one.
By inserting a CSS hack we can perform our browser detection by hiding the second CSS rule from IE. This means that IE won't even know it exists and will therefore use the first CSS rule. How do we do this? Read on and find out!
Browser detection for Internet Explorer
To send different CSS
rules to IE, we can
use the child selector command which
IE can't understand.
The child selector command involves two elements, one of which is
the child of the other. So, html>body refers to the
child, body, contained within the parent, html.
Using the example of the header margin, our CSS command would be:
#header {margin-bottom: 3em;}
html>body #header {margin-bottom: 1em;}
IE can't understand
the second CSS
rule due to the html>body
CSS command so
will ignore it and use the first rule. All other browsers will use
the second rule.
Browser detection for Internet Explorer 5
It may seem strange at first to send different CSS rules to different versions of a browser, but in the case of IE5 it's very necessary. This is due to IE5's misinterpretation of the box model. When specifying the width of an element in CSS, padding and borders aren't included in this value. IE5 however, incoporates these values into the width value causing element widths to become smaller in this browser.
The following CSS rule would result in a width of 10em for all browsers, except IE5 which would give it a width of just 5em (IE5 would incorporate two sets of padding and border, on both the left and right, when calculating the width):
#header {padding: 2em; border: 0.5em; width: 10em;}
The solution to this problem? Perform browser detection and send a different CSS rule to IE5:
#header {padding: 2em; border: 0.5em; width: 15em;
width/**/:/**/ 10em;}
IE5 will use the first width value of 15em, 5em of which will be taken up by the two sets of padding and border (one each for the left and for the right). This would ultimately give the element a width of 10em in IE5.
The 15em value will then be overridden by the second width value of 10em by all browsers except IE5, which for some reason can't understand CSS commands with empty comment tags either side of the colons. It doesn't look pretty but it does work!
Commented Backslash MacIE5 CSS Hack
The are 2 divs below. One says "This is not MacIE5", and should be visible for all css-supporting browsers except MacIE5.
The other says "This is MacIE5" and should only be visible in Mac IE5
The CSS that does it:
#isnotMacIE5 { display: none; }
#isMacIE5 { display: block; background-color: #060; color: #fff; }
/* commented backslash hack v2 \*/
#isnotMacIE5 { display: block; background-color: #060; color: #fff; }
#isMacIE5 { display: none; }
/* end hack */
Notes:
v2 of the commented backslash hack was suggested by James Craig.
Originally I'd discovered that if you inserted a comment containing a backslash
between rules in your stylesheet, MacIE5 would ignore the next (single) rule ..
(provided the selector contained a . or #). James pointed out that if you move the
\ and effectively escape the end-comment marker (removing all characters
and space btw the \ and the */), you can comment out a whole block of rules for
MacIE5 - which is mighty handy.
Here's an example of the single-rule commented backslash hack in action:
This paragraph should be highlighted green in IE5/Mac, red otherwise
/* Hide from IE-Mac \*/
#header {margin-bottom: 3em;}
#footer {margin-top: 1.5em;}
/* End hide */
IE/Mac will simply ignore all these commands. This CSS hack can actually be quite useful if there's a certain area of the site not working properly in IE/Mac. If that section isn't fundamental to being able to use the site, you can simply hide it from IE/Mac like so:
#noiemac {display: none}
/* Hide from IE-Mac \*/
#noiemac {display: block;}
/* End hide */
The first CSS
rule hides the entire section assigned the noiemac id (i.e.
<div id="noiemac">). The second
CSS rule, which
IE/Mac can't see, displays
this section.
Browser detection for IE 4 and Netscape 4
Version 4 browsers have limited and somewhat erratic support for CSS. Making a CSS layout in these browsers, whose market share has now slipped well below 1%, can be extremely challenging. It's become common practice nowadays to completely hide the CSS file from version 4 and earlier browsers. This can be achieved using the @import directive to call up the CSS document:
<style type="text/css">@import "styles.css";</style>
Version 4 (and earlier) browsers will display a non-styled version of the site as they can't understand this @import directive.
- CSS Menus
- CSS Introduction
- CSS Reference
- 1 About the CSS2 Specification
- 2 Introduction to CSS2
- 3 Conformance: Requirements and Recommendations
- 4 CSS2 syntax and basic data types
- 5 Selectors
- 6 Assigning property values, Cascading, and Inheritance
- 7 Media types
- 8 Box model
- 9 Visual formatting model
- 9.1 Introduction to the visual formatting model
- 9.2 Controlling box generation
- 9.3 Positioning schemes
- 9.4 Normal flow
- 9.5 Floats
- 9.6 Absolute positioning
- 9.7 Relationships between 'display', 'position', and 'float'
- 9.8 Comparison of normal flow, floats, and absolute positioning
- 9.9 Layered presentation
- 9.10 Text direction: the 'direction' and 'unicode-bidi' properties
- 10 Visual formatting model details
- 10.1 Definition of "containing block"
- 10.2 Content width: the 'width' property
- 10.3 Computing widths and margins
- 10.4 Minimum and maximum widths: 'min-width' and 'max-width'
- 10.5 Content height: the 'height' property
- 10.6 Computing heights and margins
- 10.7 Minimum and maximum heights: 'min-height' and 'max-height'
- 10.8 Line height calculations: the 'line-height' and 'vertical-align' properties
- 11 Visual effects
- 12 Generated content, automatic numbering, and lists
- 13 Paged media
- 14 Colors and Backgrounds
- 15 Fonts
- 16 Text
- 17 Tables
- 18 User interface
- 19 Aural style sheets
- 19.1 Introduction to aural style sheets
- 19.2 Volume properties: 'volume'
- 19.3 Speaking properties: 'speak'
- 19.4 Pause properties: 'pause-before', 'pause-after', and 'pause'
- 19.5 Cue properties: 'cue-before', 'cue-after', and 'cue'
- 19.6 Mixing properties: 'play-during'
- 19.7 Spatial properties: 'azimuth' and 'elevation'
- 19.8 Voice characteristic properties: 'speech-rate', 'voice-family', 'pitch', 'pitch-range', 'stress', and 'richness'
- 19.9 Speech properties: 'speak-punctuation' and 'speak-numeral'
- Appendix A. A sample style sheet for HTML 4.0
- Appendix B. Changes from CSS1
- Appendix C. Implementation and performance notes for fonts
- Appendix D. The grammar of CSS2
- Appendix E. References
- Appendix F. Property index
- Appendix G. Descriptor index
- Appendix H. Index
