Workarounds
CSS provides a set of layout and formatting instructions to be interpreted by Browsers as they display html on the screen (or other media).
Unfortunately, there and some things in CSS that different browsers display differently, so to give viewers the desired appearance, one needs to 'trick' certain browsers to overcome their 'errors'. These tricks are called "Workarounds".
Here are some of the more useful workarounds gathered from a variety of sources:
Styling the HR line.
Ref: http://archivist.incutio.com/viewlist/css-discuss/6178
HR {color: red; background: red; border: 0; height: 5px; width: 80%; }Styling the HR element
Ref: http://www.maxdesign.com.au/articles/hr/
Date: 23 November 2002: Author: Russ Weakley
The < hr> element is self-closing, which means that there is no end tag. It causes a horizontal rule to be displayed by browsers. The amount of vertical space inserted between a rule and the content that surrounds it depends on the browser.
So, what if you want to get rid of the shading that is displayed as a default for the< hr> element in some browsers? Is it possible to style an < hr> element so it works across all modern browsers?
The answer is at css-discuss: “Internet Explorer uses the “color” property, which is incorrect.
The “color” property correctly applies to the foreground text color, not the background color. However, Mozilla (Netscape) and Opera use the background-color property.
In browsers like Opera and Mozilla, you would still have the border of your HR showing, which you may not want. To get rid of that border, set the border to zero”.
Adding space around the < hr> element
You can also define the space above and below the < hr> using margins. For example, if you wanted a standard character return space before the element and double this space afterwards, you could add the following declaration.
hr{color: red;background: red;border: 0;height: 1px;margin: 1em 0 2em;}Note that there are only three values stated for the margin property. This will apply a 1em margin above the < hr>, no margins on either side, and a 2em margin below.
Ref http://www.3internet.co.uk/resources/Design/theHRtag.aspx
The HR Tag
The HR (Horizontal Ruler) tag is a very helpful html element for dividing up sections of text in a page, without having to resort to one pixel high graphic. The problem is that left unstyled, you're leaving it up to the browser to determine how it looks, which can be indifferent at the best of times.
One way to control this is by using the available HTML attributes:
align: [ left, center and right ]
noshade: (solid line)
size: [ pixel value ] line height of the element
width: [ pixel or percentage value ] width of the element
example:
Sadly not all browsers will interpret these attributes the same way, so the best way to get a consistent look is to use CSS.
What properties can you use?
width: [ pixel or percentage value ] specifies the width of the element
height: [ pixel value ] specifies the line height of the element
border: [ pixel value ] in this case it should be set to zero
color: [ hex value ] this describes the color of text within an element
background-color: [ hex value ] sets the background color for the current element
text-align: [ ]details how the element will be horizontally aligned.
You'll need to include both the color and background-color attributes in the style sheet as not all browsers will understand them. Browsers that understand both, will draw a border around the element so it is important to use the height attribute to control this.
Example:
height: 1px;width: 100%;text-align: left; }
Ref: http://reference.sitepoint.com/css/workaroundsfiltershacks
Workarounds, Filters, and Hacks
Unfortunately, as you deal with CSS you’ll eventually discover differences in the way user agents apply and render CSS rules. These differences can be caused by the user agents’ varying interpretations of, and levels of support for, the CSS standards, as well as rendering problems and bugs. But—luckily for us—they can be addressed using workarounds, filters, and hacks.
If you search the Web for “CSS hacks,” you’ll find numerous sites and articles from as far back as 2001 describing ways to tackle browser-related CSS problems. These problems were discovered once people started attempting to create completely CSS-based web design and layout. Happily, modern browser support for CSS is fairly good, so many of those old-school hacks are no longer needed. Older browsers have fallen into disuse and workarounds for problematic browsers that are still in use are well documented.
All software has bugs. Browsers are no exception to this rule, but some browsers are certainly buggier than others. In the past, some bugs related to browsers’ CSS rendering caused web pages to become unreadable, and in some cases, they even crashed browsers. It’s also true that browsers don’t provide perfect support for CSS—a fact that’s often the cause of much frustration. Of course, the situation was far worse in the past, when levels of support could differ wildly.
Workarounds, Filters, and Hacks Defined
Once CSS-based layout and design became popular, web designers and developers needed a way to supply different CSS rules to different browsers—a capability that’s absent from CSS. A hack has typically been regarded as a temporary, inelegant, or unadvised solution to a problem. But in CSS terms, applying a hack generally means exploiting incorrect or buggy CSS features in order to target or exclude a browser, or group of browsers, so that alternative styling may be applied to them. Other techniques—often called workarounds or filters—include targeting the proprietary features of a specific browser, or employing advanced CSS features to exclude older browsers that don’t support the newer features. If all this jargon’s getting a bit much for you, just remember that workarounds are CSS-oriented solutions to these problems, while filters and hacks are browser-oriented solutions.
The Problem with Workarounds, Filters, and Hacks
While it’s often tempting to leap in and apply a complicated hack to force a particular browser to behave, a more careful approach is needed to address CSS problems efficiently. First, you need to make sure that the problem you’re addressing is a real CSS problem—not just the result of incorrect CSS code or an incomplete understanding of CSS. If your web page looks as you intended in one browser but not another, you may be tempted to think that the browser that’s not displaying your site properly has a CSS bug, but of course the exact opposite is equally likely.
Consider, for instance, the fact that different browsers apply varying default margin and padding values to HTML elements like headings and list items. You’ll often see sites on which CSS hacks are used to apply particular rules to different browsers simply because the designers weren’t aware of the variations in these values. The use of CSS hacks in these kinds of situations is redundant; simply spending a few minutes to gain an understanding of the margin and padding rules would negate the need to apply hacks.
If you’re sure that you have a valid CSS rendering problem, and you’re tempted to use a hack, first see whether a change of design could enable you to avoid the issue altogether. If you can design layouts that don’t depend on problematic CSS features, in most cases you won’t need hacks at all.
The Internet Explorer 5 box model problem is a famous example of the unnecessary use of hacks. Many complicated hacks were developed to solve this problem, but with a simple design change—the addition of padding to the parent of an element with a fixed width, instead of to the element itself—designers could have avoided the problem altogether. This approach wasn’t possible in every case, but the option was there.
Avoiding Implementation Pitfalls
If you find yourself in a position where you have no choice but to use a workaround, filter, or hack, be aware of the dangers involved. Your chosen hack may be unreliable—in the future, it may actually cause more problems than would have resulted had you not used it at all. As newer browser versions are produced, new features are implemented, and bugs are fixed, the hack mechanism you’ve been using may cease to work. Also consider the maintenance issues that can arise when many hacks are spread throughout a style sheet.
In reality, the only completely safe way to use a browser hack is to target dead browsers—those browsers that are no longer in development, like Internet Explorer 6—and target them in such a way that you can be sure the hacks you’re using will continue to work in that browser.
Don’t apply hacks to newer browsers, such as Firefox 2, and Opera 9—they’re updated regularly, and new features and bug fixes are addressed relatively quickly. It’s just not safe to use a hack for these newer browsers, and usually they don’t need it anyway—even if they do need adjustment, a change of design will often accommodate any deficiencies you find. Finally, whenever you use a hack, you face the difficulty of finding one that will work on just the browser you’re targeting without affecting all the others. Let us tell you now: in the end, it’s a fruitless pursuit. That’s why the modern approach is to attempt to shun hacks altogether.
Using conditional comments is now the recommended way to target various versions of Internet Explorer; a number of workaround techniques that don’t rely on ugly hacks are also available. Finally, we’ve included a list of popularCSS hacks here, not because they’re recommended, but in case you come across them and need to understand what they attempt to achieve.
Ref http://reference.sitepoint.com/css/conditionalcomments
Internet Explorer Conditional Comments
Conditional comments comprise a proprietary Microsoft extension to Internet Explorer that provides a mechanism to target each of the versions of IE either specifically, or as a group. This extension was introduced in IE5, so it can only be used in documents rendered in browsers from IE5 up on the Windows platform.
Conditional comments use a special syntax—HTML markup wrapped in a conditional statement—and are placed within an HTML comment. If the statement evaluates to true, the enclosed HTML is revealed within the HTML document. If the statement evaluates to false, the enclosed HTML remains hidden. Because conditional comments are placed with HTML comments, the enclosed HTML also remains hidden from all browsers that don’t support conditional comments.
Conditional comments can be placed at any point in the document at which normal comments can be located. As such, you can’t place them in external CSS files, or in between < style> tags. However, they can be used to link to specific files, or to provide specific HTML (or CSS) content for the IE versions specified within the conditional statement. It may seem odd to discuss HTML markup in a CSS reference, but conditional comments are Microsoft’s recommended mechanism for delivering targeted CSS to its browser.
Conditional Comment Basics
The basic form of conditional comments is as follows:
< !--[if IE ]> < link href="iecss.css" rel="stylesheet" type="text/css">< ![endif]-->
The conditional statement is contained within square brackets, and begins with if followed by an expression. The enclosed HTML content is delimited by the opening
< !--[if …]> and a closing < ![endif]--> statement.
In the example above, the enclosed HTML content—a < link> tag—will be revealed to all IE browsers that support conditional comments. It links to a style sheet that only IE will see. All browsers other than IE versions 5 and later will see the code above as one simple HTML comment. If we remove the brackets and text for the sake of clarity, we’re basically left with a normal comment structure as follows:
Conditional Comment Operators
As we mentioned already, we can use conditional comments to apply CSS rules to specific IE browser versions with the help of comparison operators that allow each version of IE to be targeted precisely. We can write complex expressions using one or more of the operators listed in Table 1.
Operator | Description |
---|---|
IE | represents Internet Explorer; if a number value is also specified, it represents a version vector |
lt | less than operator |
lte | less than or equal to |
gt | greater than |
gte | greater than or equal to |
! | the NOT operator |
() | subexpression operator |
& | the AND operator |
| | the OR operator |
true | evaluates to true |
false | evaluates to false |
So, for example, you’d use the following markup to target IE version 7:
< !--[if IE 7 ]>< p>Only IE 7 will see this< /p>
< ![endif]-- >
Alternatively, if you wanted to target all IE browsers except IE7 and above (that is, versions prior to IE7), you could use this method:
< !--[if lt IE 7 ]>< p>Only less than IE 7 will see this< /p>
< ![endif]-->
If you wanted to include IE7 in that list, you’d use lte operator, which selects all version numbers that are less than or equal to 7.
The gt (greater than) and gte (greater than or equal to) operators work similarly. Have a look at this example:
< p>Only IE 6 and greater will see this< /p>
< ![endif]-->
This conditional comment will select all IE browsers with version numbers greater than or equal to 6, which will obviously include IE7 and even IE8—if it ever makes an appearance!
It should be noted that when you use a single digit to represent the version of IE you want to target (for example, [if IE 7]) that directive will be applied to all versions of that browser including those with version vectors. For example, if you used the conditional comment below, you’d be including all versions of IE5 including IE5.5:
< p>This covers all versions of IE5 including IE5.5< /p>
< ![endif]-->
Tip:Targeting Point Releases
If you want to target a specific point release, you’ll need to specify the correct version vector. You can specify a point release using a number followed by up to four decimal places. Even though this appears as a decimal number, IE doesn’t see it that way: each individual digit is compared separately. For example, the expression[if IE 5] will have a broader match than [if IE 5.0], even though they appear to be equal decimal number values. The expression [if IE 5.0] will not match IE5.5.
What this means is that you may need to check the version vector if you’re aiming to target specific browser versions. For example, Microsoft points out that IE5 on the Windows 2000 platform has a version vector equal to 5.0002. This means that the expression [if IE lte 5.0000] would fail to target the release build of IE5.
You can also use the “not” operator, !, to exclude one of the IE browser versions. To exclude IE6, but not IE7 or IE5 (if ever you wanted to do such a thing), you’d use this expression:
< p>IE7 or IE5 only< /p>
< ![endif]-->
Downlevel-hidden Conditional Comments
More complicated expressions can be created using one or more of the available operators. For example, the following conditional comment targets IE6 and IE7 using subexpressions and the OR operator:
< !--[if (IE 6)|(IE 7)]>< p>IE6 or IE7 only < /p>
< ![endif]-->
Microsoft refers to the this style of conditional comments as downlevel-hidden, since browsers that don’t support conditional comments (including IE4 and earlier) will interpret the conditional comment code as a standard HTML comment, and ignore it completely. And yes—Microsoft describes all browsers except IE5 and later as “downlevel” browsers!
There is, however, another version of conditional comments that will allow these downlevel browsers to be targeted; they’re called downlevel-revealed conditional comments.
Downlevel-revealed Conditional Comments
In downlevel-revealed conditional comments, the HTML content inside the conditional statements is revealed to browsers that don’t support conditional comments, because the conditional statements—and only the conditional statements—are ignored. If the statement evaluates to true (in a supporting browser), the content inside the conditional statements is also revealed.
Unfortunately, the syntax of these downlevel-revealed conditional comments will often cause HTML validation errors. Here’s Microsoft’s suggested syntax:
< p>This is shown in downlevel browsers, but is invalid HTML!< /p>
< ![endif]>
However, a better, valid version of the syntax is available. It’s been discovered that if you change the syntax slightly, the downlevel effect can be maintained and the HTML code will validate:
< !--[if !IE]>-->< p>This is shown in downlevel browsers.< /p>
< !--< ![endif]-->
Here, we simply wrap the conditional statements in HTML comments. It should be noted that this usage doesn’t conform to Microsoft’s specifications for these comments, but it presently works in all versions of IE5 and later (including IE7) and, more to the point, will also validate—unlike Microsoft’s version.
That said, a problem exists with that approach should you wish to target downlevel browsers as well as a supporting Microsoft browser version. Take a look at this example, which attempts to target downlevel browsers and IE7 or later:
< p>This is shown in downlevel browsers and IE7 or later.< /p>
< !--< ![endif]-->
This example uses valid HTML, but IE7 and later browsers will also reveal the--> after the opening conditional statement. The fix suggested by Microsoft is to add an extra < ! just after the opening conditional comment:
< !--[if gte IE 7]>< !-->< p>This is shown in downlevel browsers and IE7 or later.< /p>
< !--< ![endif]-->
Conditional Comments in Practice
If you want to use conditional comments in your approach to delivering targeted CSS, here’s what you can do. First, link to your standard style sheet in the normal way (via a < link> tag, for example). Then, use conditional comments to link to one or more other style sheets that contain the CSS targeted towards IE. The IE-only style sheets should contain only the required CSS fixes. They shouldn’t be a duplication of your standard style sheet—that would be a waste of bandwidth and completely redundant anyway. Here’s an example of this approach:
< link href="main.css" rel="stylesheet" type="text/css">< !--[if IE 7]>
< link href="ie7.css" rel="stylesheet" type="text/css">
< ![endif]-->
< !--[if IE 6]>
< link href="ie6.css" rel="stylesheet" type="text/css">
< ![endif]-->
< !--[if IE 5]>
< link href="ie5.css" rel="stylesheet" type="text/css">
< ![endif]-->
main.css is the standard style sheet, while ie7.css, ie6.css, and ie5.css contain the CSS for specific IE versions. You may not need to be as version-specific as we’ve been in this example. Remember that the cascade will be in effect, and that the rules in the CSS files that are referenced lower down the page source will overrule any previously defined CSS rules.
Whether you like conditional comments or not, they do make it easy and safe to target versions of IE, and they’re as future-proof as any of these tricks can be. The comments also provide a logical structure to your CSS management approach, and separate the targeted CSS from the standard CSS. At some time in the future when the targeted CSS is no longer required, the code, which is already separated, can easily be removed.
You can also minimize the number of stylesheets if you use the conditional comments to create IE-specific containers, like so:
< !--[if IE 6]>-->< div id="IE6">< !--< ![endif]-->
< p>regular html content< /p> < !--[if IE 7]>-->< /div>< !--< ![endif]-->
You could then target the < p> element by:
p { /* code for standard browsers*/}div#IE6 p {/* code for IE6 */}
div#IE7 p {/* code for IE7 */}
You can also nest conditional comments. This provides an alternate (and arguably more intuitive) approach to valid downlevel-revealed CCs that also target IE. Instead of this:
< !--[if gte IE 7]>< !-->< p>This is shown in downlevel browsers and IE7 or later.< /p>
< !--< ![endif]-->
You can do this:
< !--[if IE]>< ![if gte IE 7]>< ![endif]-->< p>This is shown in downlevel browsers and IE7 or later.< /p>
< !--[if IE]>< ![endif]>< ![endif]-->
For more on this approach, see the last few sections of this Position Is Everything article:
http://www.positioniseverything.net/articles/multiIE.html
Ref: http://reference.sitepoint.com/css/hacks
CSS Hacks
CSS hacks have a long and colorful history. For a bit of historical perspective, some of the most popular CSS hacks are explained below.
This is not an exhaustive list, and there’s really no need to remember all the hacks and variations in detail, but you should be aware that they exist.
For example, if you happen to inherit a site and discover some obscure CSS notation in an old style sheet, you’ll be able to identify it and understand its purpose. If you can’t find a particular hack in this list, look them up as required from the many resources around the Web, including Dynamic Site Solutions and Centricle.com.
The Backslash and Underscore Hacks
Numerous characters trigger non-compliant behaviors in different browsers. Both of the hacks we’ll discuss in this section constitute legal CSS, but rely on specific browser bugs in order to work.
The first application we’ll look at is the backslash hack, in which a backslash character is inserted into a property name. The backslash indicates a character escape in CSS escape notation and browsers that comply with the CSS specification should ignore the character in this context. However, Internet Explorer 5.5 and earlier versions will ignore the whole declaration when they meet a character escape in the middle of a property name. Here’s an example:
Modern browsers will apply a height of 400px, but Internet Explorer 5.5 and earlier versions will retain the value of 500px, since they’ll ignore the latter declaration.
Note:Positioning the Backslash
For this hack to work properly, the backslash must be positioned in the middle of the property, not at the beginning. Also, it shouldn’t appear before the letters a to f, or A to F, or numerals 0 to 9—if it does, those characters will be treated as hexadecimal numbers according to CSS escape notation rules.
The second application we’ll review is the underscore property hack, in which an underscore character is inserted at the beginning of a property name. This is valid CSS, and modern browsers will simply ignore the declaration because the property is unknown. However, Internet Explorer 6 and earlier versions ignore the underscore and apply the declaration.
For example, in the following CSS, most modern browsers will ignore the second declaration, but Internet Explorer 6 and earlier versions will apply it:
The Voice-family Hack
The most famous, and perhaps oldest, CSS hack is the voice-family hack, also known as the box model hack because it was specifically designed to work around the disparity in the implementation of the box model in Internet Explorer 5.x and other standards-compliant browsers. It’s also known as the Tantek Hack—named after its inventor, Tantek Çelik. It’s an ugly and complicated hack that’s virtually impossible to remember off the top of your head. Here’s what the complete hack looks like:
.test { width: 500px; padding: 50px;voice-family: "\"}\""; voice-family: inherit; width: 400px; }
html>body .test{ width: 400px; }
The hack worked thanks to a flaw in the CSS parser in Internet Explorer 5.x, and it effectively cut the declaration block short at the curly brace in the middle of this section of code: "\"}\"". This flaw effectively made Internet Explorer 5.x see something like this:
.test { width: 500px; padding: 50px; voice-family: "\"}The browser ignored the width: 400px; declaration, and retained the 500pxwidth value. Most other browsers will apply the 400px width instead.
Unfortunately, Opera 5, which was in use at the time, exhibited the same parsing bug as IE5 and IE5.5, so an extra rule needed to be added using the child selector. Opera 5 supported the child selector and applied the declaration:
As I mentioned, it’s an ugly hack, but it was necessary at the time. Eventually, it was surpassed by the simpler star selector hack.
The Commented Backslash Hack
This hack targets a CSS parsing bug in Internet Explorer 5 Mac. To hide rules from IE5 for Mac, simply place a backslash before the close of a comment:
/* begin hiding from IE5 Mac \*/ .test { color: red; } /* end */IE5 for Mac won’t see the close of the comment, so it’ll ignore everything between the backslash and the end of the next comment.
You can also achieve precisely the opposite effect with the following CSS:
The High Pass Filter
The High Pass Filter was developed by Tantek Çelik in order to hide a style sheet from browsers that supported the @import method but didn’t provide a decent level of support for CSS1. The hack looks like this:
@import "null.css?\"\{";@import "highpass.css";
This actually constitutes valid CSS. The first statement attempts to import a file from the URI null.css?"{, which is an empty file, while the second statement imports the desired style sheet. Internet Explorer 6 and up, Internet Explorer 5 for Mac, Netscape 6 and up, and Opera 5 and up could read these two statements correctly, but older browsers got caught up on the escape characters and failed to load any style sheets.