CSS Browser Hacks

Thursday, September 23, 2010

SELECTOR HACKS

/* IE 6 and below */
* html #uno  { color: red }

/* IE 7 and below */
*:first-child+html #dos { color: red }

/* IE 7 and modern browsers */
html>body #tres { color: red }

/* Modern browsers (not IE 7) */
html>/**/body #cuatro { color: red }

/* Opera 9.27 and below */
html:first-child #cinco { color: red }

/* Safari */
html[xmlns*=""] body:last-child #seis { color: red }

/*safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:nth-of-type(1) #siete { color: red }

/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:first-of-type #ocho {  color: red }

/* saf3, chrome1+ */
@media screen and (-webkit-min-device-pixel-ratio:0) {
 #diez  { background: #FFDECE; border: 2px solid #ff0000  }
}

ATTRIBUTE HACKS

/* ie6 and below */
#once { _color:blue }

/* ie7 and below */
#doce { *color: blue } /* or #color:blue */


/*IE8 Standards-Mode Only:*/

.test { color /*\**/: blue\9 }
 
All IE versions, including IE8 Standards Mode:
.test { color: blue\9 }
/* 'Modern Browsers' includes IE8, whether you agree or not.. :) */

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 on the Mac

Quite simply, IE on the Mac does strange things with CSS. The browser's become somewhat obsolete as Microsoft aren't going to be bringing out an updated version. As such, many web developers code their CSS-driven sites so that the site works in IE/Mac, although it may not offer the same level of advanced functionality or design. Provided IE/Mac users can access all areas of the site this is seen as a suitable way of doing things.
To hide a command using the IE/Mac CSS hack1 is simple, and involves wrapping a set of dashes and stars around as many CSS rules as you like:
/* 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.
). The second CSS rule, which IE/Mac can't see, displays this section.

@import "non-ie.css" all

Internet Explorer 7 and below don't support media selectors on @import rules, instead ignoring the entire rule when they are present. Therefore, you can create an entire stylesheet for non-IE browsers and import it into your main stylesheet by adding @import "non-ie.css" all;.

Future versions of Internet Explorer may support the @import rule correctly.

@import "stylesheet.css" all; imports the stylesheet in all major browsers except IE 7 and below. It may or may not work in future versions of IE.


Unrecommended hacks

_property: value and -property: value

Due to a parsing error, Internet Explorer 6 and below wouldn't fail on properties that were prefixed with non-alphanumeric characters. Prefixing a regular property name with _ or - will cause the property to be applied to Internet Explorer 6 and below but generally not in other browsers. Internet Explorer 7 had this bug fixed.

The CSS specification allows browsers to use an underscore (_) or hyphen (-) as a prefix for a vendor-specific property name with the guarantee that such properties will never be used in a future CSS standard. Because of this guarantee, these two prefix characters are ideal options for this hack.
Although the CSS specification defines this vendor-specific property syntax, the properties are inherently not part of any W3C-endorsed CSS profile and are therefore invalid when validated against one. For this reason, and because there is an often acceptable alternative, this hack is unrecommended.

_property: value and -property: value apply the property value in IE 6 and below. Warning: this uses invalid CSS.

*property: value

Although Internet Explorer 7 corrected its behavior when a property name is prefixed with an underscore or a hyphen, other non-alphanumeric character prefixes are treated as they were in IE6. Therefore, if you add a non-alphanumeric character such as an asterisk (*) immediately before a property name, the property will be applied in IE and not in other browsers. Unlike with the hyphen and underscore method, the CSS specification makes no reservations for the asterisk as a prefix, so use of this hack could result in unexpected behavior as the CSS specifications evolve.

*property: value applies the property value in IE 7 and below. It may or may not work in future versions. Warning: this uses invalid CSS.

body:empty

The :empty pseudo-classes is proposed for CSS 3 and should select an element that has no elements or text inside it. However, when used on the body element, Firefox 1.5 and 2.0 (and corresponding versions of other Gecko-based browsers) always select it even when the body has content (which it should always have).
Although this hack is expected to be valid in CSS 3, it has not yet reached W3C Recommendation status and is invalid CSS 2.x, so it currently isn't recommended to use this hack. However, it is probably the best way to single out recent versions of Firefox.
body:empty {} selects the body element in Firefox 1.5 and 2.0 only. It may or may not work in future versions. Warning: this uses invalid CSS 2.x but valid CSS 3 according to recent drafts.


html*

Internet Explorer 7 fixed the quirk that allowed the universal selector (*) to select some nonexistent parent of the html element, but there's another issue that they didn't fix: When a universal selector is directly adjacent to another simple selector without a space between, Internet Explorer 7 assumes a space there. That means that html* is treated by IE7 like html *, while other browsers ignore it because it's a parsing error. Similarly, IE7 treats ** like * *.
html* {} selects all descendants of the html element in IE 7 and below. It may or may not work in future versions. Warning: this uses invalid CSS!

!ie

Internet Explorer 7 fixed one of the issues with the !important identifier, but it still has problems when the identifier has an error in it. If an illegal identifier name is used in place of important, Internet Explorer 7 and below will handle the property normally instead of failing. Therefore, in any style declaration block, you can include properties intended to only apply to Internet Explorer and add an !ie identifier. Almost any word can be used in place of ie.
The !ie identifier allows the property to be applied in IE 7 and below. It may or may not work in future versions. Warning: this uses invalid CSS!

!important!

Another problem with the !important identifier that wasn't fixed in IE 7 is the treatment of non-alphanumeric characters after the identifier. Normally, this should cause the property to fail, but Internet Explorer 7 and below ignore the additional punctuate and apply the property as if it just had the !important identifier.
The !important! identifier allows the property to be applied with importance in IE 7 and below and the property is not applied in other browsers. It may or may not work in future versions. Warning: this uses invalid CSS!

 




 


1 comments:

Unknown said...

Very much informative and useful sakthi :) :) :)

Post a Comment

 
This is Sakthi, CSS Developer @ Chennai,India © 2010 | Designed by My Blogger Themes | Blogger Template by Blog Zone