Python CSS Browser Selector

by koesbong on January 28, 2011

So you’ve got a site that looks great on your Firefox for Mac but not on your Firefox for Windows. Or you’ve got a site that looks mighty fine on Firefox 3.6 but not so mighty on Firefox 3.5. How do you deal with that? There is one particular trick that I know of to do a targeted IE specific CSS fixes, but that trick won’t work for the scenarios above.

IE Specific Conditional CSS

<!--[if IE]>
  <link rel="stylesheet" type="text/css" href="all-ie-only.css" />
<![endif]-->

Searching around on Google led me to Rafael Lima’s JavaScript CSS Browser Selector. Basically you load a Javascript file and after the page finished loading, the javascript detects what browser and machine you’re on and add those as class names to your <html > tag. Well, the problem with this approach is that it waits for the page to finish loading, then load the Javascript file. If for some reason your JS file takes a little bit longer to load after the page finished loading, you may see a flash of unstyled content.

Since I work with PHP a lot, I found out last year that there is a PHP version of that script written by Bastian Allgeier. He mentioned that his php script is a port from Rafael’s Javascript version. The advantage of the PHP version is that “there’s no additional request needed to include the javascript file and the selectors are available immediately“.

Fast forward to today, I have been working with Python and Django for the past few weeks and would like to use that script, but was not able to find the Python version. So I ported it and it is now on Github.

How to use

We will utilize Django’s TEMPLATE_CONTEXT_PROCESSORS so that it’ll be accessible to all templates. So, in your settings.py, add ‘app_folder.context_processors.get_ua’, where app_folder is the folder name your app lives in, and context_processors is the file in which we will call the get_ua() function.

settings.py

...

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "app_folder.context_processors.get_ua",
)

...

context_processors.py

import css_selector

def get_ua(request):
    ua = request.META.get('HTTP_USER_AGENT', 'unknown')
    return css_selector.get_ua(ua)

And then in your base or index HTML file:

<!DOCTYPE HTML>
<html class="{{ css }}">
    ...
</html>

The output:

<!DOCTYPE HTML>
<html class="gecko mac ff36">
    ...
</html>

In your CSS file, you can then target the browsers and OS more specifically:

.mac.ff36 #header {}
.win.ff36 #header {}

Available Browser Codes

  • ie – Internet Explorer (All versions)
  • ie8 – Internet Explorer 8.x
  • ie7 – Internet Explorer 7.x
  • ie6 – Internet Explorer 6.x
  • ie5 – Internet Explorer 5.x
  • gecko – Mozilla, Firefox (all versions), Camino
  • ff2 – Firefox 2
  • ff3 – Firefox 3
  • ff35 – Firefox 3.5
  • ff35 – Firefox 3.6
  • ff35 – Firefox 4
  • opera – Opera (All versions)
  • opera8 – Opera 8.x
  • opera9 – Opera 9.x
  • opera10 – Opera 10.x
  • konqueror – Konqueror
  • webkit or safari – Safari (all versions), NetNewsWire, OmniWeb, Shiira, Google Chrome
  • chrome – Google Chrome
  • iron – SRWare Iron

Available OS Codes

  • win – Microsoft Windows
  • linux – Linux (x11 and linux)
  • mac – Mac OS
  • freebsd – FreeBSD
  • ipod – iPod Touch
  • iphone – iPhone
  • ipad – iPad
  • blackberry- BlackBerry
  • android – Android
  • webtv – WebTV
  • j2me – J2ME Devices (ex: Opera mini)
  • mobile – Other mobile devices

Inspiration

As I mentioned earlier, this is a port of the PHP script by Bastian Allgeier, which is a port of the Javascript by Rafael Lima, who was inspired by 37Signals. Big thanks to Adam Kuert for pointing out the usage of Django’s context processors to make things much easier and Nathan Ostgard for the porting guidance.

License

Following Bastian and Rafael’s step, this code is released under the following license: http://creativecommons.org/licenses/by/2.5/

Any feedback is greatly appreciated.

2 comments

[...] This post was mentioned on Twitter by chrisforrette, koesbong. koesbong said: wanna use @bastianallgeier's php css browser selector for your django project? now you can – http://t.co/5OZJqfU #python #django #css [...]

by Tweets that mention Python CSS Browser Selector « Koes Bong -- Topsy.com on January 28, 2011 at 8:40 pm. Reply #

[...] Started With MongoDB (Python) | Building Browsergames Python CSS Browser Selector « Koes Bong python – Django Module, App and Import Question – object has no attribute [...]

by More bookmark « I-Girl, I Define! on May 27, 2012 at 10:09 am. Reply #

Leave your comment

Required.

Required. Not published.

If you have one.