CssUserAgent was started back in 2006 as a less chaotic solution to fixing browser-specific quirks when polishing up web app UIs. 20 | Originally, it was part of a larger Ajax framework that has since been modularized into smaller independent libraries.
21 |The intention is to build valid standards-based cross-plaform CSS and sparingly use CssUserAgent to finish the job. 22 | Test your code in many browsers as early and frequently as you can. 23 | Don't just design for your favorite browser and once finished look at it in everything else. 24 | This tends to create more workarounds then are necessary.
25 | 26 |Chill, buddy. It's just a tool. If you don't need it, don't use it. The fact is there are tons of people out there writing cryptic CSS hacks and this gives them a better option.
28 |UserAgent-sniffing, in all its various forms, gets lots of flak in the web UI community. Typically this is because it is abused by those new to the trade. L337 haxors tend to love to bash any pragmatic shortcuts which trade code purity for time.
29 |The reality is, as in all of life, there are trade-offs to be made. Beware "always" and "never" statements; choose wisely and use shortcuts sparingly. Deep breaths. It's going to be okay.
30 | 31 |CssUserAgent actually predates Modernizr by a couple years; however, this is a valid point as Modernizr is a great tool. The existence of both is further evidence that browser differentiating layout is indeed a problem in need of a solution.
33 |These two tools serve slightly different but complimentary purposes. Modernizr uses feature detection to allow differentiating layout. This works well for feature-oriented differences but some layout differences aren't necessarily the result of missing features or cannot be detected through feature testing. 34 | See the "Undetectables" topic in Modernizr's docs for specific examples. 35 | Sometimes you just need a slightly different padding or font size for one browser.
36 |Modernizr may or may not be the right tool for the job. Keep in mind, Modernizr is also about 4x larger and requires more complex DOM testing logic on each page load. Again choose your tools based upon your needs.
37 | 38 |As mentioned earlier, CSS hacks have been the traditional solution. 40 | These techniques rely upon bugs within various browser implementations to be able to target specific browsers. 41 | CSS hacks have many downsides, not the least of which is they typically employ invalid CSS syntax which could be misinterpreted by CSS compaction utilities. 42 | Another common issue is their behavior is largely unknown for future browsers.
43 |Since Internet Explorer typically is the greatest deviant in web design, another common solution uses different stylesheets for IE by using IE-only conditional comments to include or exclude certain <link/> or <style/> tags. 44 | This only applies to IE, and tends to become difficult to maintainable in larger applications. 45 | Even worse is that seemingly valid uses of conditional comments can drastically slow down page load in IE-8.
46 |Another solution which only targets Internet Explorer 47 | uses IE-only conditional comments to apply classes to the HTML tag. 48 | This clever solution has the advantage of not requiring CSS Hacks or JavaScript, but only works with IE and makes your markup ugly as sin.
49 | 50 |The most important caveat to know is that CssUserAgent requires JavaScript. 52 | This typically isn't an issue for most users. But be warned not to rely upon browser-specific CSS classes for the accessibility of your content. 53 | As mentioned earlier, this is intended for layout fixes and polish not core business logic.
54 | 55 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mckamey/cssuseragent/04be9bfdebff14876c3cf024bc60370fe163763a/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Avoid CSS hacks! Use cssua.js
to apply special CSS classes to your pages allowing you to use valid CSS to work around browser-specific quirks. Read more…
Expected: | ' + expected + ' |
---|---|
Result: | ' + actual + ' |
Diff: | ' + QUnit.diff(expected, actual) +' |
Source: | ' + source +' |
This page demonstrates the power of CssUserAgent. This feature applies User-Agent specific CSS classes to the <html>
tag to allow browser-specific CSS variation without resorting to CSS hacks. Since these are performed once at startup, CSS may be statically defined without the need to mix browser-specific logic into the presentation.
Multiple classes are created for each user-agent, allowing the web developer to target browser classes on differing levels of granularity. The general pattern is browser name followed by version number of varying precision:
65 |ua-browsername
ua-browsername-major
ua-browsername-major-minor
ua-browsername-major-minor-build
ua-browsername-major-minor-build-revision
Notice how the sidebar color scheme and browser icon change depending upon which browser you are using.
76 |This is all done with CSS since cssua.js has prepped the HTML tag with special CSS classes which allow you to target browsers with varying degrees of precision.
77 | 78 |
79 | <!-- the CSS classes currently applied to this page tag are: -->
80 | <html class="">
83 |
84 | <head>…</head>
85 | <body>…</body>
86 |
87 | </html>
88 |
89 |
90 | UserAgent-sniffing is regarded as something to be used sparingly, but pragmatic developers know it is sometimes the simplest approach to fixing a particular browser's quirk. When it is, cssua.js
produces a helper object as a side-effect which makes user-agent-siffing easier and more consistent.
An object map is also built which allows you to test the user agent from your script in a simplified manner that doesn't require string parsing. For example, this object is effectively produced:
93 | 94 |cssua.userAgent = cssua.ua = {
95 |
113 | };
114 |
115 |
116 | Change the input userAgent value and watch how the key-value pairs and the CSS class names respond to the change. This gives you an idea of what to expect from browsers other than this one.
118 |Testing for older Internet Explorer has never been easier than this:
172 | 173 |
174 | if (cssua.ua.ie < 8.0) { /* proof of Pareto principle here */ }
175 |
176 |
177 | Or get a hint if this user might need a mobile experience:
178 | 179 |
180 | if (cssua.ua.mobile) { /* consider your audience */ }
181 |
182 |
183 | Remember to convert the version String
to a Number
with parseFloat
if the value isn't a simple number, e.g., it has multiple decimal points or trailing letters. Otherwise JavaScript may interpret the value as NaN
(not a number):
186 | if (parseFloat(cssua.ua.chrome) > 101) { /* enter the Matrix */ }
187 |
188 |
189 | CssUserAgent helps detect the increasingly ambiguous category of mobile browsers. cssua.js
adds specific classes when it detects mobile browsers:
192 | <html class="… ua-mobile ua-mobile-iphone …">…<html>
193 |
194 |
195 | This allows you to target the browser rendering engine (e.g. "webkit
"), or a specific browser (e.g. "safari
"). The version can be targeted at the major version number (e.g. "ie-5
" includes 5.0, 5.5) or minor (e.g. "ie-5-0
" includes only 5.0) all the way down (e.g. "ua-chrome-8-0-552-224
") for a very specific case.
199 | /* CssUserAgent lets you target specific browsers without CSS hacks */
200 | .logo-area
201 | {
202 |
203 | background-image: url(logo.png);
204 | background-repeat: no-repeat;
205 | background-position: left top;
206 |
207 | }
208 |
209 | /* target IE 5.0, 5.5, 6.0 */
210 | .ua-ie-5 .logo-area,
211 | .ua-ie-6 .logo-area
212 | {
213 |
214 | /* IE versions < 7.0 don't fully support transparent 24-bit PNGs */
215 | background-image: url(logo.gif);
216 |
217 | }
218 |
219 |
220 |
221 | Some browsers have multiple listings if the rendering engine is significant. For instance, Gecko-based browsers (such as Firefox, Mozilla, Netscape, Camino, SeaMonkey) also define Gecko CSS classes, to target all browsers of a specific Gecko version at once.
222 |Below is an example of a number of browser labels which display differently under the presence of different CssUserAgent classes.
223 | 224 |