Skip to Content


Articles / No More CSS Hacks

No More CSS Hacks

Associated links:

Introduction

If you are a web designer or front-end developer, you are probably familiar with how different browsers or user agents displays your code in their own way. Picture this: You are pushing pixels and refining your designs so it fits perfect in your Firefox browser, but when presenting your design to the client in Internet Explorer, your pages might brake completely. Bye bye contract. Designing with CSS is no exception. On the contrary – table based layout seems to be more cross-browser consistent than CSS positioning. This probably one of the reasons why several big names still uses tables in their web design layouts.

CSS Hacks

To compensate these browser glitches, many CSS designers have been working on setting up CSS hacks. A CSS hack is a way to force some user agents to ignore a certain CSS property by putting faux code into the CSS file. One of the most infamous issues when designing with CSS is the Box model. IE5/Windows and IE5.5/Windows misinterpret the CSS1 box model by placing border and padding inside the specified width instead of outside. Here is an example of one of the most common CSS hacks used to solve this:

.content
    {
    width: 700px;
    padding: 0 100px;
    voice-family: "\"}"";
    voice-family: inherit;
    width: 500px;
    }

So what does this mean? The first rule width: 700px; will apply to all user agents. But there is a second style rule, which takes advantage of a CSS parsing bug in IE5/Windows and IE5.5/Windows, to apply a width which is then overriden. So IE5/Windows and IE5.5/Windows will read width: 700px and all other browsers will read width: 500px. So far so good. Except that everyone will see your hack.

Why Hacks are Ugly

There is something fundamentally wrong with how hacks work. They are based on producing errors in the CSS code to exploit browser flaws that prevents them from parsing certain CSS properties and values. Most CSS hacks works fine enough, but looks really bad and a hack like the one above does not validate using the W3C validator. If you are interested in semantics and standards you would never put a similar hack in an XHTML file, so why would you do it in the CSS file?

The Other Way

What if we could detect browsers and serve different CSS rules to different user agents, without using hacks or conditional comments? What if the end user or validator never saw the CSS rules specified for other browsers than the one they are using? We can. Many server side languages can detect browsers just as good as any CSS hack, and in this example we will use some simple PHP magic to make things happen.

Let's Get Going

To be able to use PHP in a CSS file, we need to link up the php file in the XHTML header as CSS and then send the correct header in the php file. As we don't need the @import hack anymore, put this line in the header of your XHTML file:

<link rel="stylesheet" href="styles.php" type="text/css" />

Create a new file called "styles.php" and save it into the same directory as your XHTML file. The first line in this file will be a header command to define a text/CSS header to the document. Once this is done, we can start producing variables in PHP and use them to print different rules in the CSS file depending on user agent. Let's create a small application that detects browser types and versions and platform, and then put these values in variables for later use:

<?php
header
("Content-type: text/css");
$d = detect();
$b = $d['browser'];
$v = $d['version'];
$o = $d['os'];
function
detect()
    {
    
$browser = array ("IE","OPERA","MOZILLA","NETSCAPE","FIREFOX","SAFARI");
    
$os = array ("WIN","MAC");
    
$info['browser'] = "OTHER";
    
$info['os'] = "OTHER";
    foreach (
$browser as $parent)
        {
        
$s = strpos(strtoupper($_SERVER['HTTP_USER_AGENT']), $parent);
        
$f = $s + strlen($parent);
        
$version = substr($_SERVER['HTTP_USER_AGENT'], $f, 5);
        
$version = preg_replace('/[^0-9,.]/','',$version);
        if (
$s)
            {
            
$info['browser'] = $parent;
            
$info['version'] = $version;
            }
        }
    foreach (
$os as $val)
        {
        if (
eregi($val,strtoupper($_SERVER['HTTP_USER_AGENT']))) $info['os'] = $val;
        }
    return
$info;
    }

Let's use these variables to print out user agent specific values, taking the box-model hack as an example. We will use simple if/else statements to check our variables, but you could also use ternary operators. What we are doing here is basically: if platform is windows and browser is IE and version is less than 6, width is 700px, else width is 500px.

.content
    {
    padding: 0 100px;
    width: <?php
    
if ($o == "WIN" && $b == "IE" && $v < 6) echo "700px;"
    
else echo "500px;";
    ?>
    }

There are no limits to how useful a script like this can be for the advanced CSS designer. In the rule above, IE5/win and IE5.5/win will see width: 700px; and all other browsers will see width: 500px;. Without hacks and invalid CSS markup You can even skip the popular @import hack to prevent browser versions below 5 to display the CSS. Another useful example would be to serve .gif instead of .png to IE5/win & IE5.5/win if you are using alpha transparency as background:

body
    {
    background: url(<?php
    
if ($o == "WIN" && $b == "IE" && $v < 6) echo "background.gif";
    else echo
"background.png";
    
?>);
    }

Here is another scenario: You want to apply max-width, but just found out that IE doesn't support it. So you found out about a max-width hack, but don't like to put ugly javascript expressions in your CSS. Here's how to serve the javascript to IE only:

body
    {
    <?php
    
if ($b == "IE") echo "width:expression(document.body.clientWidth > 800? \"800px\": \"auto\" );";
    else echo
"max-width: 800px;";
    
?>
    }

Final Example

The sample PHP/CSS file in this example will hide certain selectors and only show the selector that contains the correct browser information. At the same time we will get rid of the @import hack and serve no CSS to user agents that doesn't support it properly. You can watch what the html file looks like at our Demo page. Don't forget that you can download all associated files to this article here.

<?php
header
("Content-type: text/css");
$d = detect();
$b = $d['browser'];
$v = $d['version'];
$o = $d['os'];
function
detect()
    {
    
$browser = array ("IE","OPERA","MOZILLA","NETSCAPE","FIREFOX","SAFARI");
    
$os = array ("WIN","MAC","LINUX");
    
$info['browser'] = "OTHER";
    
$info['os'] = "OTHER";
    foreach (
$browser as $parent)
        {
        
$s = strpos(strtoupper($_SERVER['HTTP_USER_AGENT']), $parent);
        
$f = $s + strlen($parent);
        
$version = substr($_SERVER['HTTP_USER_AGENT'], $f, 5);
        
$version = preg_replace('/[^0-9,.]/','',$version);
        if (
$s)
            {
            
$info['browser'] = $parent;
            
$info['version'] = $version;
            }
        }
    foreach (
$os as $val)
        {
        if (
eregi($val,strtoupper($_SERVER['HTTP_USER_AGENT']))) $info['os'] = $val;
        }
    return
$info;
    }
?>

<?php if ($b != "OTHER" && $o != "OTHER" && $v >= 5) { ?>

/* BEGIN CSS RENDERING */

body
    {
    background: #fff;
    font: small/140% verdana, sans-serif;
    padding: 4em;
    margin: 0;
    }

<?php
echo ($b =="OPERA") ? null : ".opera { display: none; }\n";
echo (
$b =="IE") ? null : ".ie { display: none; }\n";
echo (
$b =="FIREFOX") ? null : ".firefox { display: none; }\n";
echo (
$b =="MOZILLA") ? null : ".mozilla { display: none; }\n";
echo (
$b =="NETSCAPE") ? null : ".netscape { display: none; }\n";
echo (
$b =="SAFARI") ? null : ".safari { display: none; }\n";
?>

/* END CSS RENDERING */

<?php } ?>

This article was written by David Hellsing

David Hellsing is a designer and web developer living in Gothenburg, Sweden. He is the founder and gentle dictator of Stylegala and the swedish design firm monc.

Are you a web publisher?

We are always looking for people who can write good articles about web design, css and standards. Are you one of them? Talk to us.

There are 34 guest comments so far.

commentat 02:44 on 06 October 2008, partner wrote:

tnx admin.

commentat 16:27 on 12 October 2008, mcloft wrote:

Thanks for the info.

commentat 23:28 on 14 October 2008, netguru wrote:

Hi Admin,

This is the best of the best BEST BEST best CSS solution for PHP. I've been searching this for about two hours and you saved me. Thank you.

commentat 10:19 on 21 October 2008, tomas wrote:

Everything seems to be nice, but opera 9.60 doesn't work with your script :(

commentat 10:21 on 21 October 2008, tomas wrote:

Everything seems to be nice, but opera 9.60 doesn't work with your script :(

commentat 11:58 on 21 October 2008, tomas wrote:

Everything seems to be nice, but opera 9.60 doesn't work with your script :(

commentat 22:27 on 22 October 2008, dress up games wrote:

all things cool N' Crazy..

commentat 13:01 on 23 October 2008, Teknoloji Platformu wrote:

Thanks , it's cool article.

commentat 18:53 on 27 October 2008, Drew wrote:

Even though tomas has "billboarded" your awareness on the subject (got to love the Internet sometimes for timeouts! Just bugging you tomas ;) it is apparently true that Opera 9.60 does not work properly with your script at this time. This is what is rendered in the browser window:

You are using Opera

You are using Internet Explorer

You are using Firefox

You are using Mozilla

You are using Netscape

You are using Safari

However this script is the best one I have ever seen and am thankful for you sharing your knowledge with the masses - ok, just me ;)

Thanks again!

commentat 20:15 on 28 October 2008, cet wrote:

thanks all admin

commentat 20:16 on 28 October 2008, çet wrote:

thank you

commentat 20:17 on 28 October 2008, çet wrote:

thanks

commentat 20:18 on 28 October 2008, sohpet wrote:

thanks

commentat 01:14 on 29 October 2008, islami sohbet wrote:

thanks

commentat 01:16 on 29 October 2008, çet wrote:

thank you

commentat 08:20 on 01 November 2008, ford wrote:

Hello!

I am a hacker. I can get you a yahoo, aol, hotmail,myspace faceobook..etc password. Once I have the password, I will show you proof I have it. I will take snapshots of the account or even message you from the account. I do charge a fee per password though.

Are you interested? Email me at Fordf202006@yahoo.com

commentat 03:55 on 02 November 2008, efoc wrote:

Thanks a lots.

commentat 21:46 on 13 November 2008, Metallica wrote:

Cascading Style Sheets (CSS) web design lessons

Css link Properties Attributes - examles

http://css-lessons.ucoz.com/link-css-examples-1.htm

http://css-lessons.ucoz.com/link-css-examples-2.htm

commentat 08:21 on 15 November 2008, srendn wrote:

Great alternative to those 'if' statements...

However due to the lack of a .css file extension, DMX 8 does not render the styles in edit mode, therefore making its wysiwyg capabilities unusable.

Any suggestions on how to force the styles from 'styles.php' appear in DMX editor?

commentat 16:48 on 18 November 2008, sex toy shop wrote:

Css link Properties Attributes - examles

http://css-lessons.ucoz.com/link-css-examples-1.htm

commentat 16:50 on 18 November 2008, lingerie wrote:

IE5/Windows and IE5.5/Windows misinterpret the CSS1 box model by placing border and padding inside the specified width instead of outside.

commentat 12:43 on 22 November 2008, film porno wrote:

Thanks a lot

commentat 14:13 on 30 November 2008, Play Boy wrote:

HELLO EVERYONE,

THE ONLY GENUINE, EASY AND QUICK WAY TO CRACK PASSWORD FOR YAHOO-HOTMAIL-MYSPACE-FACEBOOK-AOL-GMAIL IS EITHER USING FISHING WEBSITES OR MAKING VICTIM COMPUTER A ZOMBIE.

IT REALLY WORKS GOOD.

YOU CAN DO IT ON YOUR OWN INSTEAD OF PAYING LOT OF MONEY TO OTHERS OVER INTERNET.

WARNING: DO NoT PAY ANYONE IN ADVANCE UNLESS YOU SEE A PROOF.

IF ANYONE NEEDS MY HELP, EMAIL ME AT:

pass.crackerz@yahoo.com OR chessplayer69@gmail.com

CHECK MY BLOG: http://crackthatprofile.blogspot.com/

commentat 18:58 on 15 December 2008, dex online wrote:

oh yeah, this is what i want! thank you!

commentat 11:23 on 16 December 2008, rencontres wrote:

thanks a lot

commentat 20:59 on 16 December 2008, clearance london wrote:

Thanks for this article, it's great. So great that we've made it 'sticky' on The Webmaster Forums. Now we don't have to repeat ourselves, just send people to this article!

commentat 15:36 on 23 December 2008, powl wrote:

sounds interesting! if it dosn't work with opera, for me it's a no-go ;), but i'll give it a try on my next project

commentat 15:44 on 23 December 2008, powl wrote:

sounds interesting! if it dosn't work with opera, for me it's a no-go ;), but i'll give it a try on my next project

commentat 22:59 on 18 January 2009, Call Surf Comfort wrote:

Thanks for this nice tutorial!

commentat 12:54 on 19 January 2009, oyna wrote:

If you are a web designer or front-end developer, you are probably familiar with how different browsers or user agents displays your code in their own way

commentat 01:27 on 20 January 2009, last wrote:

good jop my

friend

commentat 02:37 on 21 January 2009, sinema izle wrote:

thank you.

commentat 02:54 on 21 January 2009, youtube wrote:

Thank you very much.

commentat 02:34 on 22 January 2009, sinema izle wrote:

thank you

Add a comment:

(required, non-public)

  |  Chars left: 1000

Keep the comment relevant and constructive.
A valid email address or URL to your site must be provided, or the comment might get deleted. Content seemed inappropriate or offensive may be edited and/or deleted. Avoid explicit language. Email addresses are never displayed. Line breaks and paragraphs are automatically converted - no need to use <p> or <br/>. Quotes & apostrophes are automatically converted to smart punctuation. Be careful when copying and pasting portions of entries or other comments. The following inline HTML elements may be used: <strong><em><pre><q><blockquote><code>. All other code will get removed before posting. Don't forget to close your tags.


All articles

Search

Features

Stylegala BookStore
The Stylegala BookStore has a massive archive of great books for you as a professional..
Bullet madness
Bullet madness is a list of 200 bullets, arrows and icons uploaded by our users.
CSS Reference
An alphabetical list over the most common CSS1 and CSS2 syntax and properties.

Sponsors

Logo design for $149

Advertise here