搜尋
首頁web前端html教學safe CSS hacks_html/css_WEB-ITnose

In defense of CSS hacks ? introducing “safe CSS hacks”

Published 19th May 2011 · tagged with CSS, HTML

How do you target Internet Explorer in your CSS? Do you use CSS hacks, conditional stylesheets or something else?

It’s the perfect trollbait. There have been plenty of discussions about this, and I don’t mean to start a new one. Everyone’s entitled to their own opinion, but the thing is that it’s not purely a philosophical matter. I am writing this article because I noticed there’s a lot of misunderstanding on the subject of CSS hacks.

People have been advocating three different approaches: conditional stylesheets, CSS hacks, or conditional classnames. All these techniques have their pros and cons. Let’s take a look.

Conditional stylesheets

Conditional comments make it very easy to specify stylesheets that should only be loaded in Internet Explorer, or even in specific versions of that browser. Non-IE browsers treat conditional comments as any other HTML comment. Here’s an example:

<!--[if lte IE 8]><link rel="stylesheet" href="lte-ie-8.css"><![endif]--><br /><!--[if lte IE 7]><link rel="stylesheet" href="lte-ie-7.css"><![endif]--><br /><!--[if lte IE 6]><link rel="stylesheet" href="lte-ie-6.css"><![endif]-->

This snippet will cause lte-ie-8.css to be loaded in IE8, IE7, IE6 and even in IE5. (Older IE versions don’t support conditional comments.) In IE7 and older versions, lte-ie-7.css will be loaded as well. In IE6 all three additional stylesheets will be loaded.

If you want to use this technique to style an element differently in specific versions of Internet Explorer, it’d look something like this:

/* Main stylesheet */<br />.foo { color: black; }<br /><br />/* lte-ie-8.css, for IE8 and older */<br />.foo { color: green; }<br /><br />/* lte-ie-7.css, for IE7 and older */<br />.foo { color: blue; }<br /><br />/* lte-ie-6.css, for IE6 and older */<br />.foo { color: red; }

Pros

The conditional comments snippet is valid HTML.

Since there’s no need to use CSS hacks, you can even write valid CSS if you want to.

Cons

Performance decreases due to the multiple additional HTTP requests, depending on the browser.

Conditional comments block downloads in IE unless another (possibly empty) conditional comment is included earlier in the source.

The total file size increases, since the conditional comments have to be repeated for every HTML single document, and you’ll have to repeat the selector in every CSS file. More typing work!

Maintainability is negatively affected. You now have to maintain four separate stylesheets instead of just one. Whenever you make changes to your main CSS file, you need to remember to change the IE-specific CSS files if necessary.

Conditional classnames

Those not willing to use CSS hacks can always apply conditional classnames to the  or 

element. This approach allows you to write clean and hack-free CSS at the cost of adding hacksconditional comments to your HTML.
<!--[if lt IE 7]><html class="ie6"><![endif]--><br /><!--[if IE 7]>   <html class="ie7"><![endif]--><br /><!--[if IE 8]>   <html class="ie8"><![endif]--><br /><!--[if gt IE 8]><!--><html><!--<![endif]-->

This allows you to keep your browser-specific CSS in the same file:

.foo { color: black; }<br />.ie8 .foo { color: green; } /* IE8 */<br />.ie7 .foo { color: blue; } /* IE7 */<br />.ie6 .foo { color: red; } /* IE6 and IE5 (but who cares, right?) */

Pros

The conditional classes snippet is valid HTML. (Prior to HTML5, you would have to add the classes to the 

 element instead.)

Since there’s no need to use CSS hacks, you can even write valid CSS if you want to.

No additional HTTP requests are being issued to get the IE-specific styles.

In this particular case, the conditional comments don’t block downloads.

Cons

This technique increases the file size of every HTML document you use it for.

The use of the IE-specific classnames automatically increases the specificity of your selectors, which may not be what you want.

Since you’ll need the classnames in the selectors, you’ll have to use separate CSS rules for IE-specific styles.

The character encoding declaration (e.g. ) should be placed within the first 1024 bytes of the HTML document. Using this technique, you may cross this limit, especially if you’re adding lots of other attributes to the  element (since you’ll have to repeat them inside every conditional comment).

Using conditional comments around the opening  tag throws IE into compatibility view unless you set the X-UA-Compatible header in a server-side config.

Simon Pieters reports that using conditional comments before  causes IE to ignore the . So again, you’ll need to set the X-UA-Compatibleheader in a server-side config.

CSS hacks

Paul Irish maintains a comprehensive list of CSS hacks for various browsers. In reality, you’ll rarely need to specifically target anything but IE. Here’s an overview of the three most popular CSS hacks and which browsers they’re supposed to target:

.foo {<br />  color: black;<br />  color: green\9; /* IE8 and older, but there’s more… */<br />  *color: blue; /* IE7 and older */<br />  _color: red; /* IE6 and older */<br />}

Note the use of the \9 CSS hack. Web developers noticed it could be used to easily target IE8 and older versions, so that’s what they did. But then there was IE9, and as it turned out, the final IE9 release was still affected by this hack (despite my bug report on the matter). All those CSS declarations that were meant to be for IE8 and earlier versions only, now got interpreted by IE9 as well. Needless to say, stuff broke, since IE9 doesn’t need most of the IE8-specific CSS fixes.

This is the perfect example of an unsafe CSS hack.

Safe CSS hacks

So what constitutes a “safe” CSS hack? What makes me even think there is such a thing?

Let’s face it ? CSS hacks are still hacks. There’s no way to accurately predict how future browser versions will parse these rules. But we can make an educated guess ? some hacks are less hacky than others. A safe CSS hack is a CSS hack that:

works in specific versions of a given web browser;

is unlikely to be parsed by all other browsers, including future versions.

Take the _property: value hack, for example. The CSS 2.1 spec says the following:

Keywords and property names beginning with - or _ are reserved for vendor-specific extensions.

A property name is an identifier.

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit.

So who’s to say there will never be a property name starting with an underscore character? To quote the CSS3 spec:

Although [the underscore] is a valid start character, the CSS Working Group believes it will never define any identifiers that start with that character.

Both the _property: value and *property: value hacks (as seen in the above code block) are examples of safe CSS hacks. They were discovered, identified as bugs, and patched in a browser update. Since then, it’s very likely that Microsoft and other browser vendors added checks for these CSS hacks to their layout tests, to make sure no new browser version is shipped with a regression this significant.

If you discover a CSS hack in the latest version of a certain browser, it won’t be a safe hack until an updated version of that browser is released where the parser bug is fixed. For example, some people (myself included) have been looking for an IE9-specific CSS hack. Recently, one was found, but we’ll have to wait at least until the final IE10 release to use it, because IE10 may or may not be shipped with the same CSS parser bug. We can’t risk repeating the history of the \9 hack.

Pros

You don’t have to add conditional comments to every single HTML page.

No additional HTTP requests are being issued to get the IE-specific styles.

The specificity of your CSS selectors is preserved.

There’s no need to repeat CSS rules ? you can just add extra declarations (with the hacks) to the declaration block.

Cons

They’re called CSS hacks for a reason ? only use safe CSS hacks.

There’s no safe CSS hack for IE8 (yet?).

Contrary to conditional comments, most CSS hacks don’t validate. But then again, CSS3 properties and vendor-prefixed properties don’t validate either.

Combining conditional classnames with safe CSS hacks

Safe CSS hacks are preferable to conditional stylesheets or classnames, but what if you have to write IE9-specific styles? By definition, there won’t be a safe CSS hack for IE9 at least until IE10 is released. Also, what about IE8? There is no safe CSS hack (that I know of) that targets IE8 but not IE9. What to do?

In the HTML, we can use a minimal version of the conditional classnames technique, like so:

<!--[if lt IE 9]><html class="lte-ie8"><![endif]--><br /><!--[if gt IE 8]><!--><html><!--<![endif]-->

We can then use .lte-ie8 as a styling hook in CSS selectors to target IE8 and older versions. Combined with safe CSS hacks, we can finally target IE8 and older versions without also affecting IE9:

.foo {<br />  color: black;<br />}<br /><br />.lte-ie8 .foo {<br />  color: green; /* IE8 and older */<br />  *color: blue; /* IE7 and older */<br />  _color: red; /* IE6 and older */<br />}

This technique combines all the advantages of safe CSS hacks and conditional classnames, while minimizing the drawbacks.

About me

Hi there! I’m Mathias, a web standards enthusiast from Belgium. HTML, CSS, JavaScript, Unicode, performance, and security get me excited. If you managed to read this far without falling asleep, you should follow me on Twitter and GitHub.

Comments

Nicolas Gallagher wrote on 19th May 2011 at 11:23:

Great summary! The last option is quite interesting.

There are a couple of other ways that people might use conditional stylesheets (not significantly different to the example you included, but with slightly different pros/cons).

One is wrapping conditional comments around stylesheets aimed at specific versions of IE to reduce the amount of overriding needed. IE6/7 are pretty similar so they can often get the same stylesheet. Not important (but still possible) to have valid CSS in a stylesheet that only two, stable and well documented browsers will ever see.

<!--[if IE 8]><link rel="stylesheet" href="ie-8.css"><![endif]--><br /><!--[if lt IE 8]><link rel="stylesheet" href="ie-6-7.css"><![endif]-->

The other approach (brought to my attention by @bricecarpentier) requires a build script. It wraps every stylesheet in a conditional comment and serves IEs a CSS file that combines the default CSS with the IE-specific CSS. This means you don’t incur an extra HTTP request in old IE.

<!--[if gt IE 7]><!--><link rel="stylesheet" href="style.css"><!--<![endif]--><br /><!--[if IE 7]><link rel="stylesheet" href="style.ie-7.css"><![endif]--><br /><!--[if IE 6]><link rel="stylesheet" href="style.ie-6.css"><![endif]-->

But both these approaches have the same issues around making maintenance harder.

Thomas Deceuninck wrote on 19th May 2011 at 11:52:

Interesting article Mathias! But what to do when you want to set a property specific for one browser? For example:

.foo {<br />  color: red;<br />}<br /><br />.ie7 .foo {<br />  color: green;<br />}

If you use the * prefix for it instead, IE6 will also be affected, right?

Nicolas Gallagher wrote on 19th May 2011 at 11:53:

Oh, and one more problem with using conditional comments around the  tag is that it throws IE into compatibility view unless you set the X-UA-Compatible header in a server-side config:https://github.com/h5bp/html5-boilerplate/issues/378

Luc De Brouwer wrote on 19th May 2011 at 12:04:

I kind of disagree on the cons with the conditional stylesheets solutions.

The performance of the browser due to additional HTTP requests is something you can limit by targeting the specific browser instead of using the 'lte' method. I find that maintainability increases with the different stylesheets because you can keep all CSS 'hacks' clearly separated. Of course you shouldn't need to go apeshit with the amount of needed 'hacks', if that's the case you did a rubbish job setting up the CSS framework etc. Also the solution Stoyan Stefanov suggested ( the empty conditional statement ) works like a charm.

However, this is an excellent write up!


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
HTML與CSS vs. JavaScript:比較概述HTML與CSS vs. JavaScript:比較概述Apr 16, 2025 am 12:04 AM

HTML、CSS和JavaScript在網頁開發中的角色分別是:HTML負責內容結構,CSS負責樣式,JavaScript負責動態行為。 1.HTML通過標籤定義網頁結構和內容,確保語義化。 2.CSS通過選擇器和屬性控製網頁樣式,使其美觀易讀。 3.JavaScript通過腳本控製網頁行為,實現動態和交互功能。

HTML:是編程語言還是其他?HTML:是編程語言還是其他?Apr 15, 2025 am 12:13 AM

HTMLISNOTAPROGRAMMENGUAGE; ITISAMARKUMARKUPLAGUAGE.1)htmlStructures andFormatSwebContentusingtags.2)itworkswithcsssforstylingandjavascript for Interactivity,增強WebevebDevelopment。

HTML:建立網頁的結構HTML:建立網頁的結構Apr 14, 2025 am 12:14 AM

HTML是構建網頁結構的基石。 1.HTML定義內容結構和語義,使用、、等標籤。 2.提供語義化標記,如、、等,提升SEO效果。 3.通過標籤實現用戶交互,需注意表單驗證。 4.使用、等高級元素結合JavaScript實現動態效果。 5.常見錯誤包括標籤未閉合和屬性值未加引號,需使用驗證工具。 6.優化策略包括減少HTTP請求、壓縮HTML、使用語義化標籤等。

從文本到網站:HTML的力量從文本到網站:HTML的力量Apr 13, 2025 am 12:07 AM

HTML是一種用於構建網頁的語言,通過標籤和屬性定義網頁結構和內容。 1)HTML通過標籤組織文檔結構,如、。 2)瀏覽器解析HTML構建DOM並渲染網頁。 3)HTML5的新特性如、、增強了多媒體功能。 4)常見錯誤包括標籤未閉合和屬性值未加引號。 5)優化建議包括使用語義化標籤和減少文件大小。

了解HTML,CSS和JavaScript:初學者指南了解HTML,CSS和JavaScript:初學者指南Apr 12, 2025 am 12:02 AM

WebDevelovermentReliesonHtml,CSS和JavaScript:1)HTMLStructuresContent,2)CSSStyleSIT和3)JavaScriptAddSstractivity,形成thebasisofmodernWebemodernWebExexperiences。

HTML的角色:構建Web內容HTML的角色:構建Web內容Apr 11, 2025 am 12:12 AM

HTML的作用是通過標籤和屬性定義網頁的結構和內容。 1.HTML通過到、等標籤組織內容,使其易於閱讀和理解。 2.使用語義化標籤如、等增強可訪問性和SEO。 3.優化HTML代碼可以提高網頁加載速度和用戶體驗。

HTML和代碼:仔細觀察術語HTML和代碼:仔細觀察術語Apr 10, 2025 am 09:28 AM

htmlisaspecifictypefodyfocusedonstructuringwebcontent,而“代碼” badlyLyCludEslanguagesLikeLikejavascriptandPytyPythonForFunctionality.1)htmldefineswebpagertuctureduseTags.2)“代碼”代碼“ code” code code code codeSpassSesseseseseseseseAwiderRangeLangeLangeforLageforLogageforLogicIctInterract

HTML,CSS和JavaScript:Web開發人員的基本工具HTML,CSS和JavaScript:Web開發人員的基本工具Apr 09, 2025 am 12:12 AM

HTML、CSS和JavaScript是Web開發的三大支柱。 1.HTML定義網頁結構,使用標籤如、等。 2.CSS控製網頁樣式,使用選擇器和屬性如color、font-size等。 3.JavaScript實現動態效果和交互,通過事件監聽和DOM操作。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)