Jump to content

CSS hack: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Updated browser prefixes section
 
(44 intermediate revisions by 33 users not shown)
Line 1: Line 1:
{{Short description|Coding technique}}
{{Multiple issues|
{{hatnote|This article is about a CSS technique. Not to be confused with the proprietary Microsoft-specific CSS property.}}
{{update|date=September 2014}}
{{Howto|date=September 2011}}
{{Use dmy dates|date=December 2021}}
A '''CSS hack''' is a [[Computer programming|coding]] technique used to hide or show [[Cascading Style Sheets|CSS]] [[Markup language|markup]] depending on the [[Web browser|browser]], version number, or capabilities. Browsers have different interpretations of CSS behavior and different levels of support for the [[W3C]] [[World Wide Web Consortium#Standards|standards]]. CSS hacks are sometimes used to achieve consistent layout appearance in multiple browsers that do not have compatible rendering. Most of these hacks do not work in modern versions of the browsers, and other techniques, such as feature support detection, have become more prevalent.
}}


== Types of hacks ==
A '''CSS hack''' is a [[Computer programming|coding]] technique used to hide or show [[Cascading Style Sheets|CSS]] [[Markup language|markup]] depending on the [[Web browser|browser]], version number, or capabilities. Browsers have different interpretations of CSS behavior and different levels of support for the [[W3C]] [[World Wide Web Consortium#Standards|standards]]. CSS hacks are sometimes used to achieve consistent layout appearance in multiple browsers that do not have compatible rendering.


=== Invalid or non-compliant CSS ===
==Browser Prefixes==
Due to quirks in the interpretation of CSS by various browsers, most CSS hacks involve writing invalid CSS rules that are interpreted only by specific browsers, or relying on bugs in specific browsers. An example of this is prefixing rules with an underscore (as in <code>_width</code>) to target Internet Explorer 6—other browsers will ignore the line, allowing it to be used to write code specific to one [[Web browser|browser]].
Each of the most popular browser rendering engines has its own vendor-specific prefix for experimental properties. However, due to the proliferation of these properties in live code, the browser vendors have begun to move away from this in favor of user-controlled feature flags.<ref>{{Cite web|url=https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix|title=Vendor Prefix|website=Mozilla Developer Network|access-date=2016-10-12}}</ref> The following is a list of prefixes from various layout engines:

Similar CSS hacks involve inducing syntax errors like asterisks, missing whitespace, and CSS comments around property names. Additionally, in [[Internet Explorer]] 6 and 7, the <code>!important</code> declaration is recognized as such with any string after the exclamation mark, e.g. <code>!ie</code>.<ref>{{cite web |title=Browser CSS hacks |author=Paul Irish |url=https://www.paulirish.com/2009/browser-specific-css-hacks/ |website=www.paulirish.com |access-date=8 June 2022 |date=2009-04-15}}</ref>

=== Unsupported CSS ===
Although newer CSS rules are correct by current standards, they are ignored by older browsers as "invalid". By writing old rules followed by newer rules that cancel out or modify the old ones, it is possible to only activate certain rules on older browsers.

=== Conditional comments ===
{{Main|Conditional comment}}
Prior to version 10, [[Internet Explorer]] supported a special comment syntax that would allow blocks of HTML to be read only by specific versions of the browser. These comments are mostly used to provide specific CSS and JavaScript workarounds to older versions of the browser. No other browsers interpreted these comments or offered similar functionality.

The following are examples of the different syntax for these comments.
<syntaxhighlight lang="html">
<head>
<title>Test</title>
<link href="all_browsers.css" rel="stylesheet" type="text/css">
<!--[if IE]> <link href="ie_only.css" rel="stylesheet" type="text/css"> <![endif]-->
<!--[if lt IE 7]> <link href="ie_6_and_below.css" rel="stylesheet" type="text/css"> <![endif]-->
<!--[if !lt IE 7]> <![IGNORE[--><![IGNORE[]]> <link href="recent.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
<link href="not_ie.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
</head>
</syntaxhighlight>

=== Critics ===
Hiding code using hacks often leads to pages being incorrectly displayed when browsers are updated. These hacks can lead to unexpected behavior in newer browsers that may interpret them differently than their predecessors. Since Internet Explorer 6 and 7 have fallen out of use, CSS hacks have declined as well. Modern methods of feature targeting are less fragile and error-prone.

== Alternatives ==

===Browser prefixes===
Each of the most popular browser [[Rendering (computer graphics)|rendering]] engines has its own [[vendor prefix]] for experimental properties. However, due to the proliferation of these properties in live code, the browser [[vendors]] have begun moving away from this practice in favor of feature flags.<ref>{{Cite web|url=https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix|title=Vendor Prefix|website=Mozilla Developer Network|access-date=2016-10-12}}</ref>

==== List of prefixes ====
The following are a list of prefixes from various layout engines:
{| class="wikitable"
{| class="wikitable"
|-
|-
! Vendor Prefix !! In Use !! Layout Engine !! Created by !! Used by
! Vendor Prefix !! In Use !! Layout Engine !! Created by !! Used by
|-
|-
| <code>-ah-</code> || yes || Formatter || Antenna House || Antenna House Formatter
| <code>-ah-</code> || Yes || Formatter || Antenna House || Antenna House Formatter
|-
|-
| <code>-apple-</code> || yes || [[WebKit]] || [[Apple Inc.]] || [[Safari (web browser)|Apple Safari 2.0]], Opera Widgets, [[Acid3#Presto and WebKit based browsers|WebKit-Based Browsers (as legacy prefix)]]
| <code>-apple-</code> || Yes || [[WebKit]] || [[Apple Inc.]] || [[Safari (web browser)|Apple Safari 2.0]], Opera Widgets, [[Acid3#Chrome, Presto and WebKit based browsers|WebKit-Based Browsers (as legacy prefix)]]
|-
|-
| <code>-atsc-</code> || || || [[Advanced Television Systems Committee standards]] ||
| <code>-atsc-</code> || || || [[Advanced Television Systems Committee standards]] ||
|-
|-
| <code>-epub-</code> || yes || WebKit || [[EPUB|EPUB Working Group]] || [[Chromium]] / [[Google Chrome]], WebKit-Based Browsers
| <code>-epub-</code> || Yes || WebKit || [[EPUB|EPUB Working Group]] || [[Chromium (web browser)|Chromium]] / [[Google Chrome]], WebKit-Based Browsers
|-
|-
| <code>-hp-</code> || || || [[Hewlett-Packard]] ||
| <code>-fx-</code> || Yes || || [[Sun Microsystems]] (now acquired by [[Oracle Corporation]]) || [[JavaFX]] applications
|-
|-
| <code>-khtml-</code> || yes / yes || [[KHTML]] / WebKit || [[KDE]] || KDE [[Konqueror]] / Apple Safari 1.1 through Safari 2.0, WebKit-Based Browsers (as a legacy prefix)
| <code>-hp-</code> || || || [[Hewlett-Packard]] (now [[HP Inc.]] and [[Hewlett Packard Enterprise]]) ||
|-
|-
| <code>-moz-</code> || yes || [[Gecko (software)|Gecko]] || [[Mozilla Foundation]] || Gecko-Based Browsers[?], Mozilla Firefox
| <code>-khtml-</code> || Yes / yes || [[KHTML]] / WebKit || [[KDE]] || KDE [[Konqueror]] / Apple Safari 1.1 through Safari 2.0, WebKit-Based Browsers (as a legacy prefix)
|-
|-
| <code>-ms-</code> || yes || [[Trident (layout engine)|Trident]] / MSHTML || [[Microsoft Corporation]] || [[Internet Explorer|Microsoft Internet Explorer]]
| <code>-moz-</code> || Yes || [[Gecko (software)|Gecko]] || [[Mozilla Foundation]] || Gecko-Based Browsers[?], Mozilla Firefox
|-
| <code>-ms-</code> || Yes || [[Trident (layout engine)|Trident]] / MSHTML || [[Microsoft Corporation]] || [[Internet Explorer|Microsoft Internet Explorer]]
|-
|-
| <code>mso-</code> || || Office || Microsoft Corporation || Microsoft Office[?]
| <code>mso-</code> || || Office || Microsoft Corporation || Microsoft Office[?]
|-
|-
| <code>-o-</code> || yes || [[Presto (layout engine)|Presto]] || [[Opera Software]] || [[Opera (web browser)|Opera desktop Browser up to version 12.16]], [[Opera Mini]], and [[Opera Mobile|Opera Mobile up to version 12.1]], [[Nintendo DS]] & [[Nintendo DSi]] Browser, Nintendo Wii Internet Channel
| <code>-o-</code> || Yes || [[Presto (layout engine)|Presto]] || [[Opera Software]] || [[Opera (web browser)|Opera desktop Browser up to version 12.16]], [[Opera Mini]], and [[Opera Mobile|Opera Mobile up to version 12.1]], [[Nintendo DS]] & [[Nintendo DSi]] Browser, Nintendo Wii Internet Channel
|-
|-
| <code>prince-</code> || yes || Prince || [[YesLogic]] || YesLogic Prince
| <code>prince-</code> || Yes || [[Prince (software)|Prince]] || [[YesLogic]] || YesLogic Prince
|-
|-
| <code>-rim-</code> || || WebKit || [[BlackBerry Limited]] || RIM Blackberry Browser
| <code>-rim-</code> || || WebKit || [[BlackBerry Limited]] || RIM Blackberry Browser
|-
|-
| <code>-ro-</code> || yes || MARTHA || Real Objects || Real Objects PDFreactor
| <code>-ro-</code> || Yes || MARTHA || RealObjects || RealObjects PDFreactor
|-
|-
| <code>-tc-</code> || || || TallComponents || TallComponents
| <code>-tc-</code> || || || TallComponents || TallComponents
|-
|-
| <code>-wap-</code> || yes || Presto || [[Open Mobile Alliance|The WAP Forum]] || Opera Desktop Browser and Opera Mobile, The WAP Forum
| <code>-wap-</code> || Yes || Presto || [[Open Mobile Alliance|The WAP Forum]] || Opera Desktop Browser and Opera Mobile, The WAP Forum
|-
|-
| <code class=nowrap>-webkit-</code> || yes || WebKit/Blink || Apple Inc. (WebKit)/Google Inc. (Blink) || Apple Safari & Safari for iOS (WebKit), Chromium / Google Chrome desktop and mobile (Blink), Opera desktop and mobile from version 14 (Blink), Android browser (Blink), [[Nokia]] MeeGo Browser 8.5, Nokia [[Symbian]] Browser 7.0 and later (WebKit), Blackberry Browser 6.0 and later (WebKit).
| <code class=nowrap>-webkit-</code> || yes || WebKit/Blink || [[Apple Inc.]] ([[WebKit]])/[[Google|Google Inc.]] ([[Blink (browser engine)|Blink]]) || Apple Safari & Safari for iOS (WebKit), Chromium / Google Chrome desktop and mobile (Blink), Opera desktop and mobile from version 14 (Blink), Android browser (Blink), [[Nokia]] MeeGo Browser 8.5, Nokia [[Symbian]] Browser 7.0 and later (WebKit), Blackberry Browser 6.0 and later (WebKit).
|-
|-
| <code>-xv-</code> || no || Presto || Opera Software || Opera Desktop Browser for Windows 2000/XP
| <code>-xv-</code> || No || Presto || Opera Software || Opera Desktop Browser for Windows 2000/XP
|}
|}


==== Example ====
Most browsers have CSS properties that apply in that browser only, or at least in the underlying render engine.<ref name="WebKit CSS Styles">[http://qooxdoo.org/documentation/general/webkit_css_styles - WebKit CSS Styles]</ref> The prefix on these properties is specific to each rendering engine.<ref name="Render Engine Prefixes">[[Comparison of layout engines (Cascading Style Sheets)#General notes|Render Engine Prefixes]]</ref> Here is an example.
<source lang="css">
<syntaxhighlight lang="css">


/* Cross-browser css3 linear-gradient */
/* Cross-browser css3 linear-gradient */
Line 70: Line 104:


}
}
</syntaxhighlight>
</source>


==== Limitation ====
'''Trident'''
Vendor prefixes were designed for features that were under development, meaning that the syntax may not even be final. Also, adding a rule for each browser's implementation of a function does not scale well when you want to support many browsers. Consequently, the major browser vendors are moving away from vendor prefixes in favor of other methods such as <syntaxhighlight lang="CSS" inline>@supports</syntaxhighlight> feature queries.
<code id="trident_-ms-">-ms-</code>&nbsp;— All experimental properties are prefixed with "-ms-", e.g. <code>-ms-interpolation-mode</code> instead of <code>interpolation-mode</code>.


=== Feature deletion ===
'''Gecko'''
<code id="gecko_-moz-">-moz-</code>&nbsp;— All experimental selectors, properties and values are prefixed with "-moz-", e.g. <code>::-moz-selection</code> instead of <code>::selection</code>.


==== JavaScript feature detection ====
'''WebKit'''
Multiple [[JavaScript]] libraries exist to detect what features are available in a particular browser so that CSS rules can be written to target them. Libraries such as Modernizr add classes to the <code>html</code> element, allowing for CSS rules such as <syntaxhighlight lang="CSS" inline>.cssgradients .header</syntaxhighlight>.
<code id="webcore_-webkit-">-webkit-</code>&nbsp;— All experimental selectors, properties and values are prefixed with "-webkit-", e.g. <code>-webkit-box-shadow</code> instead of <code>box-shadow</code>.


==== Feature queries ====
'''KHTML'''
<code id="khtml_-khtml-">-khtml-</code>&nbsp;— All experimental selectors, properties and values are prefixed with "-khtml-", e.g. <code>-khtml-opacity</code> instead of <code>opacity</code>.


A new feature known as feature queries was introduced in [[CSS|CSS3]], allowing the detection of specific functionality within the CSS (without requiring the use of a JavaScript library for [[feature detection (web development)|feature detection]]). This new directive can be used to check for the support or lack of support for a specific feature, and checks can be combined with <code>and</code>, <code>or</code>, and <code>not</code>. Obviously, <syntaxhighlight lang="CSS" inline>@supports</syntaxhighlight> rules will only work on browsers that support <syntaxhighlight lang="CSS" inline>@supports</syntaxhighlight>. <syntaxhighlight lang="css">
'''Presto'''
header {
# <code id="presto_-xv-">-xv-</code>&nbsp;— All new selectors, properties and values introduced by CSS3 Speech Module are prefixed with "-xv-" (but not found in CSS2 aural style sheets), e.g. <code>-xv-voice-rate</code> instead of <code>voice-rate</code>.
display: block;
# <code id="presto_-o-">-o-</code>&nbsp;— All experimental properties are prefixed with "-o-", e.g. <code>-o-transition-property</code> instead of <code>transition-property</code>.

The DOM properties corresponding to vendor-specific experimental CSS properties are prefixed with the vendor-prefix, without any hyphens.

==Commented backslash==
This hack exploits a [[Software bug|bug]] in [[Internet Explorer for Mac]] related to [[Comment (computer programming)|comment]] [[parsing]]. A comment ending in <code>\*/</code> is not properly closed in IE Mac, so rules that need to be ignored in IE Mac can be placed after such a comment. Another comment is needed after the rule to close the comment for IE Mac.<ref name="QuirksModeCSSHacks">[http://www.quirksmode.org/css/csshacks.html QuirksMode - CSS Hacks]</ref>
<source lang="css">
/* Ignore the next rule in IE mac \*/
selector { ...styles... }
/* Stop ignoring in IE mac */
</source>

==Box model hack==
Called the "box model hack" because the bug it is most often used to work around is the [[Internet Explorer box model bug]], this hack provides a different set of properties to [[Internet Explorer]] and other browsers. As of version [[Internet Explorer 6|6]], IE has corrected the box model bug in documents which include certain [[Document Type Declaration]]s (required by the [[HTML]] specifications) in certain ways.

<source lang="css">
#elem {
width: [IE width];
voice-family: "\"}\"";
voice-family: inherit;
width: [Other browser width];
}
}
html>body #elem {
width: [Other browser width];
}
</source>


@supports (display: flex) {
The first <code>voice-family</code> statement is set to the string <code>"}"</code>, but an IE parser bug will interpret it as a string with a single [[backslash]] followed by a closing [[Bracket#Curly brackets or braces .7B .7D|brace]] for the end of the rule. <code>voice-family</code> is chosen because it will not affect rendering on a screen [[Style sheet (web development)|style sheet]]. The second rule uses the <code>html>body</code> hack for browsers such as [[Opera (web browser)|Opera]] 5 that have the parsing bug but do not have the box model bug (and, additionally, which support the child selector).<ref>{{Cite web|url=http://tantek.com/CSS/Examples/boxmodelhack.html|title=Box Model Hack}}</ref>
header {

display: flex;
==Underscore hack==
}
Versions 6 and below of Internet Explorer recognized properties with this prefix (after discarding the prefix). All other browsers ignore such properties as invalid. Therefore, a property that is preceded by an [[underscore]] or a [[hyphen]] was applied exclusively in Internet Explorer 6 and below.

<source lang="css">
#elem {
width: [W3C Model Width];
_width: [BorderBox Model];
}
}
</syntaxhighlight>
</source>

This hack uses invalid CSS<ref name="webdevoutcsshacks" /> and there are valid CSS directives to accomplish a similar result. Thus some people do not recommend using it.<ref>http://www.javascriptkit.com/dhtmltutors/csshacks3.shtml#unrecommended-vendor_prefix</ref><ref>https://stackoverflow.com/questions/15641506/css-underscore-hack-for-ie-still-relevant</ref> On the other hand, this hack does not change the specificity of a selector making maintenance and extension of a CSS file easier.

==Star hack==
Versions 7 and below of Internet Explorer recognized properties which were preceded by non-alphanumeric characters except an [[underscore]] or a [[hyphen]] (after discarding the prefix). All other browsers ignore such properties as invalid. Therefore, a property that was preceded by an non-alphanumeric character other than an [[underscore]] or a [[hyphen]], such as an [[asterisk]], was applied exclusively in Internet Explorer 7 and below.

<source lang="css">
#elem {
width: [W3C Model Width];
*width: [BorderBox Model];
}
</source>

This hack used invalid CSS<ref name="webdevoutcsshacks" /> and there were valid CSS directives to accomplish a similar result. On the other hand, this hack didn't change the specificity of a selector making maintenance and extension of a CSS file easier.

==Star HTML hack==
The <code>html</code> element is the root element of the W3C standard [[Document Object Model|DOM]], but Internet Explorer versions 4 through 6 included a mysterious parent element.<ref name="ieblogparserforie7">{{Cite web|url=https://blogs.msdn.com/ie/archive/2005/09/02/460115.aspx|work=Improving the CSS 2.1 strict parser for IE 7|publisher=Microsoft|title=IEBlog}}</ref> Fully compliant browsers will ignore the <code>* html</code> selector, while IE4-6 used to process it normally. This enabled rules to be specified for these versions of Internet Explorer which are ignored by all other browsers. For example, this rule specified text size in Internet Explorer 4-6, but not in any other browsers.
<source lang="css">* html p {font-size: 5em; }</source>
This hack uses fully valid CSS.<ref name="webdevoutcsshacks">{{Cite web|url=http://www.webdevout.net/css-hacks|title=WebDevout - CSS Hacks|publisher=WebDevout}}</ref>

==Star plus hack==
Although Internet Explorer 7 no longer recognized the classic star HTML hack,<ref name="ieBlog">[http://blogs.msdn.com/ie/archive/2005/10/12/480242.aspx The IEBlog]</ref> it introduced a similar hack using selectors new to IE7:
<source lang="css">*:first-child+html p { font-size: 5em; }</source>
Or...
<source lang="css">*+html p { font-size: 5em; }</source>
This code would be applied in Internet Explorer 7, but not in any other browser. Note that this hack only worked in IE7 standards mode; it did not work in quirks mode. This hack was also supported by Internet Explorer 8's compatibility view (IE7 standards mode), but not in IE8 standards mode. Like the star HTML hack, this used valid CSS.<ref name="webdevoutcsshacks" />

==Child selector hack==
Internet Explorer 6 and earlier did not support the "child selector" (<code>></code>), allowing rules to be specified for all other browsers. For example, this rule would turn paragraph text blue in Firefox, but not in IE before version 7.<ref name="webdevoutcsshacks" />
<source lang="css">html > body p { color: blue; }</source>
Although IE7 added support for the child selector, a variation of the hack has been discovered which allows Internet Explorer 7 to be excluded as well. When an empty comment occurs immediately after the child selector, IE7 will drop the rule that follows, as will earlier versions of IE.
<source lang="css">html >/**/ body p { color: blue; }</source>

==Negation pseudo-class hack==
Internet Explorer 8 and below did not support the [[CSS3]] <code>:not()</code> [http://www.w3.org/TR/css3-selectors/#negation negation pseudo-class].<ref>{{Cite web
|url=http://reference.sitepoint.com/css/pseudoclass-not
|title=Sitepoint CSS Reference
|publisher=[[SitePoint]]
|accessdate=2009-01-07}}</ref>
Internet Explorer 9 added support for CSS3 pseudo-classes including the negation pseudo-class.<ref>{{cite web|last=MSDN|title=CSS Compatibility and Internet Explorer|url=http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx#pseudoclasses|accessdate=19 March 2011}}</ref>

<source lang="css">
.yourSelector {
color: black; /* value for IE 8 and below */
}

html:not([ie8andbelow]) .yourSelector {
color: red; /* value for Chrome, Safari, Opera, Firefox, and IE9+ */
}
</source>

The negation pseudo-class accepts any simple selector: A type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class. (excluding pseudo-elements and the negation pseudo-class itself).
<ref>{{Cite web
|url=http://www.w3.org/TR/css3-selectors/#simple-selectors-dfn
|title=Simple selectors
|publisher=[[World Wide Web Consortium]]
|accessdate=2011-07-04}}</ref>
It then applies the following properties to all elements which do not match this argument. Note that the <code>ie8andbelow</code> selector has no meaning, it is simply a string that will never match an actual selector. The string <code>dummy</code> would work equally as well.

A variation of this hack uses the <code>:root</code> pseudo-class, which is also unrecognized by Internet Explorer 8 and below.

==body:empty hack==
The :empty pseudo-class, introduced in CSS3, is supposed to select only elements which do not contain any content. However, Gecko 1.8.1 and below (used in Firefox 2.0.x and below) incorrectly selects body:empty even when the body element contains content (which it usually should). This can be taken advantage of to feed exclusive CSS rules to Firefox 2.0.x and below, along with other browsers using the same rendering engine.<ref name="webdevoutcsshacks" />
<source lang="css">
/* Make p elements disappear in Firefox 2.0.x and below */
body:empty p {
display: none;
}
</source>
This hack uses valid CSS.

==!important quirks==
Internet Explorer 7 and below had a few quirks related to the !important declaration, which was supposed to give a value higher importance than normal.<ref name="webdevoutcsshacks" /> IE7 and earlier accepted virtually any string in place of important and process the value normally, while other browsers ignore it. This could be used to specify values exclusively for these browsers.
<source lang="css">
/* Make text blue in IE7 and below, black in all other browsers */
body {
color: black;
color: blue !ie;
}
</source>
Similarly, IE7 and earlier accepted non-alphanumeric characters after an !important declaration, while other browsers ignore it.
<source lang="css">
body {
color: black;
color: blue !important!;
}
</source>
Both of these hacks used invalid CSS. Internet Explorer 6 and below also had a problem with !important declarations when the same property of the same element has another value specified within the same code block, without another !important declaration. This should result in the second value being overridden by the first, but IE6 and lower do not honor this.
<source lang="css">
/* Make text blue in IE6 and lower */
body {
color: black !important;
color: blue;
}
</source>
This hack uses valid CSS.

{{anchor|cssexpressions}}

==Dynamic properties==
Between versions 5 and 7, Internet Explorer supported a proprietary syntax for applying CSS properties which change dynamically, sometimes referred to as CSS expressions.<ref>[http://msdn.microsoft.com/en-us/library/ms537634.aspx About Dynamic Properties]</ref> Dynamic properties are typically combined with other hacks to compensate for unsupported properties in older versions of Internet Explorer.

<source lang="css">
div {
min-height: 300px;

/* simulates min-height in IE6 */
_height: expression(document.body.clientHeight < 300 ? "300px" : "auto");
}
</source>

==Conditional comment==
{{Main article|Conditional comment}}
Conditional comments are conditional statements interpreted by Microsoft Internet Explorer in HTML source code.
<source lang="html4strict">
<head>
<title>Test</title>
<link href="all_browsers.css" rel="stylesheet" type="text/css">
<!--[if IE]> <link href="ie_only.css" rel="stylesheet" type="text/css"> <![endif]-->
<!--[if lt IE 7]> <link href="ie_6_and_below.css" rel="stylesheet" type="text/css"> <![endif]-->
<!--[if !lt IE 7]> <![IGNORE[--><![IGNORE[]]> <link href="recent.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
<!--[if !IE]--> <link href="not_ie.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
</head>
</source>

==Criticism==
Hiding code using hacks often leads to pages being incorrectly displayed when browsers are [[Patch (computing)|updated]]. Many hacks that used to hide CSS from Internet Explorer 6 and lower no longer work in version 7 due to its improved support for CSS standards. The [[Microsoft]] Internet Explorer development team have asked that people use [[conditional comment]]s instead of hacks.<ref>[http://blogs.msdn.com/ie/archive/2005/10/12/480242.aspx IEBlog – Call to action: The demise of CSS hacks and broken pages]</ref> Unfortunately, Microsoft removed support for Conditional Comments after Internet Explorer 9.<ref>[https://msdn.microsoft.com/en-us/library/ie/hh801214%28v=vs.85%29.aspx Conditional comments are no longer supported]</ref>


=== Script polyfills ===
==See also==
While JavaScript feature detection and <syntaxhighlight lang="CSS" inline>@supports</syntaxhighlight> rules can help to target browsers that require fallback functionality, they will not address bugs in specific browsers or enable that advanced functionality. [[Polyfill (programming)|Polyfills]], scripts that make behavior consistent across all browsers, can be used to add support for new CSS rules (for example, [[media queries]] in IE 8) as well as fix bugs in specific browsers. Since polyfills add or fix functionality in browsers that do not have it, they serve a different purpose than feature queries, but can be used in combination with them.
* [[Comparison of layout engines (Cascading Style Sheets)]]
* [[Conditional comment]]s
* [[Conditional comment]]s


==Notes==
==References==
<references/>
<references/>


==External links==
==External links==
* [http://browserstrangeness.bitbucket.org/css_hacks.html Browser Strangeness] - Jeff Clayton's Live CSS hacks and tests to filter for mainstream browsers, including the only known CSS Hacks for Safari 7 and 8
* [https://web.archive.org/web/20150311021026/http://browserstrangeness.bitbucket.org/css_hacks.html Browser Strangeness] Jeff Clayton's Live CSS hacks and tests to filter for mainstream browsers, including the only known CSS Hacks for Safari 7 and 8
* [http://browserhacks.com browserhacks.com] - Multiple browser filter methods and tests (Hugo Giraudel, Joshua Hibbert, Tim Pietrusky, Fabrice Weinberg, Jeff Clayton)
* [http://browserhacks.com/ browserhacks.com] Multiple browser filter methods and tests (Hugo Giraudel, Joshua Hibbert, Tim Pietrusky, Fabrice Weinberg, Jeff Clayton)
* [http://qooxdoo.org/documentation/general/webkit_css_styles Safari/Webkit (webkit) prefix filters] refix filters]
* [https://web.archive.org/web/20120212190720/http://qooxdoo.org/documentation/general/webkit_css_styles Safari/Webkit (webkit) prefix filters] refix filters]
* [https://developer.mozilla.org/Special:Tags?tag=CSS:Mozilla+Extensions Mozilla (moz) prefix filters]
* [https://developer.mozilla.org/Special:Tags?tag=CSS:Mozilla+Extensions Mozilla (moz) prefix filters]
* [http://www.opera.com/docs/specs/opera9/css/index.dml Opera (wap) prefix filters] - This page has all of Opera's CSS selectors.
* [https://web.archive.org/web/20161221232725/http://www.opera.com/docs/specs/opera9/css/index.dml Opera (wap) prefix filters] This page has all of Opera's CSS selectors.
* [https://web.archive.org/web/20060804012032/http://centricle.com/ref/css/filters/ CSS Filters] – A fairly complete table of CSS hacks which show and hide rules from specific browsers.
* [https://web.archive.org/web/20060804012032/http://centricle.com/ref/css/filters/ CSS Filters] – A fairly complete table of CSS hacks which show and hide rules from specific browsers.
* [https://web.archive.org/web/20070715175654/http://www.lipfert-malik.de/webdesign/tutorial/bsp/css-weiche-filter.html Filters and Cross-Over] – CSS filters. Parsing errors marked red.
* [ CSS Filters – CSS-only Filters Summary] – More CSS filters.
* [http://rafael.adm.br/css_browser_selector – CSS Browser Selector] – Allows to combine browser specific CSS in single stylesheet (using JavaScript).
* [http://www.lipfert-malik.de/webdesign/tutorial/bsp/css-weiche-filter.html Filters and Cross-Over] – CSS filters. Parsing errors marked red.
* [https://web.archive.org/web/20110720143842/http://www.positioniseverything.net/articles/cc-plus.html – #IEroot] – Targeting IE with a single stylesheet containing all CSS (without using JavaScript, but using conditional comments to assign browser-specific tag to arbitrary content root {{Tag|div|o}})
* [http://rafael.adm.br/css_browser_selector - CSS Browser Selector] - Allows to combine browser specific CSS in single stylesheet (using JavaScript).
* [https://stackoverflow.com/questions/28417056/how-to-target-only-ie-any-version-within-a-stylesheet How to target only IE (any version) within a stylesheet?] – discussion on [[StackOverflow]]
* [http://www.positioniseverything.net/articles/cc-plus.html - #IEroot] - Targeting IE with a single stylesheet containing all CSS (without using JavaScript, but using conditional comments to assign browser-specific tag to arbitrary content root [div])
* [https://stackoverflow.com/questions/11173106/apply-style-only-on-ie Apply style ONLY on IE] – discussion on [[StackOverflow]]
{{Use dmy dates|date=September 2011}}
* [https://www.rareprogrammer.com/css-comments CSS Comments] - How to add comments in CSS


{{DEFAULTSORT:Css Filter}}
{{DEFAULTSORT:Css Filter}}

Latest revision as of 14:27, 27 February 2024

A CSS hack is a coding technique used to hide or show CSS markup depending on the browser, version number, or capabilities. Browsers have different interpretations of CSS behavior and different levels of support for the W3C standards. CSS hacks are sometimes used to achieve consistent layout appearance in multiple browsers that do not have compatible rendering. Most of these hacks do not work in modern versions of the browsers, and other techniques, such as feature support detection, have become more prevalent.

Types of hacks

[edit]

Invalid or non-compliant CSS

[edit]

Due to quirks in the interpretation of CSS by various browsers, most CSS hacks involve writing invalid CSS rules that are interpreted only by specific browsers, or relying on bugs in specific browsers. An example of this is prefixing rules with an underscore (as in _width) to target Internet Explorer 6—other browsers will ignore the line, allowing it to be used to write code specific to one browser.

Similar CSS hacks involve inducing syntax errors like asterisks, missing whitespace, and CSS comments around property names. Additionally, in Internet Explorer 6 and 7, the !important declaration is recognized as such with any string after the exclamation mark, e.g. !ie.[1]

Unsupported CSS

[edit]

Although newer CSS rules are correct by current standards, they are ignored by older browsers as "invalid". By writing old rules followed by newer rules that cancel out or modify the old ones, it is possible to only activate certain rules on older browsers.

Conditional comments

[edit]

Prior to version 10, Internet Explorer supported a special comment syntax that would allow blocks of HTML to be read only by specific versions of the browser. These comments are mostly used to provide specific CSS and JavaScript workarounds to older versions of the browser. No other browsers interpreted these comments or offered similar functionality.

The following are examples of the different syntax for these comments.

<head>
  <title>Test</title>
  <link href="all_browsers.css" rel="stylesheet" type="text/css">
  <!--[if IE]> <link href="ie_only.css" rel="stylesheet" type="text/css"> <![endif]-->
  <!--[if lt IE 7]> <link href="ie_6_and_below.css" rel="stylesheet" type="text/css"> <![endif]-->
  <!--[if !lt IE 7]> <![IGNORE[--><![IGNORE[]]> <link href="recent.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
   <link href="not_ie.css" rel="stylesheet" type="text/css"> <!--<![endif]-->
</head>

Critics

[edit]

Hiding code using hacks often leads to pages being incorrectly displayed when browsers are updated. These hacks can lead to unexpected behavior in newer browsers that may interpret them differently than their predecessors. Since Internet Explorer 6 and 7 have fallen out of use, CSS hacks have declined as well. Modern methods of feature targeting are less fragile and error-prone.

Alternatives

[edit]

Browser prefixes

[edit]

Each of the most popular browser rendering engines has its own vendor prefix for experimental properties. However, due to the proliferation of these properties in live code, the browser vendors have begun moving away from this practice in favor of feature flags.[2]

List of prefixes

[edit]

The following are a list of prefixes from various layout engines:

Vendor Prefix In Use Layout Engine Created by Used by
-ah- Yes Formatter Antenna House Antenna House Formatter
-apple- Yes WebKit Apple Inc. Apple Safari 2.0, Opera Widgets, WebKit-Based Browsers (as legacy prefix)
-atsc- Advanced Television Systems Committee standards
-epub- Yes WebKit EPUB Working Group Chromium / Google Chrome, WebKit-Based Browsers
-fx- Yes Sun Microsystems (now acquired by Oracle Corporation) JavaFX applications
-hp- Hewlett-Packard (now HP Inc. and Hewlett Packard Enterprise)
-khtml- Yes / yes KHTML / WebKit KDE KDE Konqueror / Apple Safari 1.1 through Safari 2.0, WebKit-Based Browsers (as a legacy prefix)
-moz- Yes Gecko Mozilla Foundation Gecko-Based Browsers[?], Mozilla Firefox
-ms- Yes Trident / MSHTML Microsoft Corporation Microsoft Internet Explorer
mso- Office Microsoft Corporation Microsoft Office[?]
-o- Yes Presto Opera Software Opera desktop Browser up to version 12.16, Opera Mini, and Opera Mobile up to version 12.1, Nintendo DS & Nintendo DSi Browser, Nintendo Wii Internet Channel
prince- Yes Prince YesLogic YesLogic Prince
-rim- WebKit BlackBerry Limited RIM Blackberry Browser
-ro- Yes MARTHA RealObjects RealObjects PDFreactor
-tc- TallComponents TallComponents
-wap- Yes Presto The WAP Forum Opera Desktop Browser and Opera Mobile, The WAP Forum
-webkit- yes WebKit/Blink Apple Inc. (WebKit)/Google Inc. (Blink) Apple Safari & Safari for iOS (WebKit), Chromium / Google Chrome desktop and mobile (Blink), Opera desktop and mobile from version 14 (Blink), Android browser (Blink), Nokia MeeGo Browser 8.5, Nokia Symbian Browser 7.0 and later (WebKit), Blackberry Browser 6.0 and later (WebKit).
-xv- No Presto Opera Software Opera Desktop Browser for Windows 2000/XP

Example

[edit]
/* Cross-browser css3 linear-gradient */
.linear-gradient {

  /* Gecko browser (Firefox) */
  background-image: -moz-linear-gradient(top, #D7D 0%, #068 100%);

  /* Opera */
  background-image: -o-linear-gradient(top, #D7D 0%, #068 100%);

  /* older Webkit syntax */
  background-image: -webkit-gradient(linear, left top, left bottom,
    color-stop(0, #D7D), color-stop(1, #068));

  /* Webkit (Safari, Chrome, iOS, Android) */
  background-image: -webkit-linear-gradient(top, #D7D 0%, #068 100%);

  /* W3C */
  background-image: linear-gradient(to bottom, #D7D 0%, #068 100%);

}

Limitation

[edit]

Vendor prefixes were designed for features that were under development, meaning that the syntax may not even be final. Also, adding a rule for each browser's implementation of a function does not scale well when you want to support many browsers. Consequently, the major browser vendors are moving away from vendor prefixes in favor of other methods such as @supports feature queries.

Feature deletion

[edit]

JavaScript feature detection

[edit]

Multiple JavaScript libraries exist to detect what features are available in a particular browser so that CSS rules can be written to target them. Libraries such as Modernizr add classes to the html element, allowing for CSS rules such as .cssgradients .header.

Feature queries

[edit]

A new feature known as feature queries was introduced in CSS3, allowing the detection of specific functionality within the CSS (without requiring the use of a JavaScript library for feature detection). This new directive can be used to check for the support or lack of support for a specific feature, and checks can be combined with and, or, and not. Obviously, @supports rules will only work on browsers that support @supports.

header {
    display: block;
}

@supports (display: flex) {
    header {
        display: flex;
    }
}

Script polyfills

[edit]

While JavaScript feature detection and @supports rules can help to target browsers that require fallback functionality, they will not address bugs in specific browsers or enable that advanced functionality. Polyfills, scripts that make behavior consistent across all browsers, can be used to add support for new CSS rules (for example, media queries in IE 8) as well as fix bugs in specific browsers. Since polyfills add or fix functionality in browsers that do not have it, they serve a different purpose than feature queries, but can be used in combination with them.

References

[edit]
  1. ^ Paul Irish (15 April 2009). "Browser CSS hacks". www.paulirish.com. Retrieved 8 June 2022.
  2. ^ "Vendor Prefix". Mozilla Developer Network. Retrieved 12 October 2016.
[edit]