Blog

Tuesday, 2 April 2013

CSS3 – How to make it work in Internet Explorer?

CSS3 is a great tool which really simplifies web page development. Sadly, it’s not supported by older browsers. Chrome 2+, Firefox 3.5+, Safari 3+ and Opera 9.5+ will work with it just fine but when it comes to Internet Explorer it gets worse. Does it mean that we have to stop using CSS3 if we want to support IE? Not necessarily. In this post I aggregated hacks which will make IE ‘understand’ some of CSS3 features.


Selectors

CSS3 comes with a bunch of selectors which allow us to target specific elements on the page: 
  • [attr], [attr=], [attr~=], [attr|=], [attr^=], [attr^=""], [attr$=], [attr$=""], [attr*=], [attr*=""]
  • :nth-child, :nth-last-child, :first-child, :last-child, :only-child    
  • :nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type
  • :empty           
  • :enabled, :disabled      
  • :checked      
  • :hover
  • :focus
  • :target
  • :not    
  • :root   
  • ::first-line
  • ::first-letter
This is a huge change comparing to CSS2, as we no longer have to use additional class names in tags just to distinguish those elements from the others of the kind. Of course Internet Explorer 8.0 and older will just ignore these entirely but adding this little script to our page is all we need to use CSS3 structural selectors even in older versions of IE:

<!--[if (gte IE 6)&(lte IE 8)]>
  <script type="text/javascript" src="selectivizr.js"></script>
<![endif]-->

You can download the library from here: http://selectivizr.com. Please note that support for CSS3 selectors varies depending on JS library you are using.

Rounded corners

I love ‘border-radius’ property. Thanks to it you can round corners in your design elements without the need for corner images. To make the property work in IE, we need to use JS fallback solution: https://code.google.com/p/curvycorners/downloads/list. There are many different libraries that round the corners but Curvy Corners is outstanding because it doesn’t need any extra configuration code to work – it reads ‘border-radius’ property directly! We can add it to the page in usual way:

<!--[if (gte IE 6)&(lte IE 8)]>   
    <script src="curvycorners.js" charset="utf-8" type='text/javascript'></script>
<![endif]-->

Gradients

CSS3 ‘linear-gradient’ property is a pretty cool one, as it allows us to generate gradient without using any images. Web developers have waited for it many, many years. Sadly, the property is interpreted differently by different browsers. It’s hard to manually write CSS code which will generate the same looking gradient for every browser. So if you need a gradient on your web page, I suggest using this generator: http://www.colorzilla.com/gradient-editor. Here is the sample of code generated this way:

body {
     /*START: Gradient generated using http://www.colorzilla.com/gradient-editor/*/
    background: #59b6c4; /* Old browsers */
    /* IE9 SVG, needs conditional override of 'filter' to 'none' */
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzU5YjZjNCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYyJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
    background: -moz-linear-gradient(top, #59b6c4 0%, #ffffff 62%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #59b6c4), color-stop(62%, #ffffff)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top, #59b6c4 0%, #ffffff 62%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top, #59b6c4 0%, #ffffff 62%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top, #59b6c4 0%, #ffffff 62%); /* IE10+ */
    background: linear-gradient(to bottom, #59b6c4 0%, #ffffff 62%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#59b6c4', endColorstr = '#ffffff', GradientType = 0); /* IE6-8 */
    /*END: Generated gradient*/
    background-attachment: fixed;
}

This code generates blue-to-white vertical gradient. Personally, I don’t like when page background moves while scrolling the page, so I added ‘background-attachment: fixed;’ property. If you want to make your gradient display properly in IE9 don’t forget to add the following code to your page:

<!--[if gte IE 9]>
    <style type="text/css">
        .gradient {
            filter: none;
        }
    </style>
<![endif]-->

You need to add ‘gradient’ class to all html tags having gradient. So in our case ‘body’ tag will look like that: ‘<body class="gradient">’.


Shadows

In order to make a shadow around some element you can use 'box-shadow' CSS3 property e.g. 'box-shadow: 3px 3px 4px #000;'. To make the same shadow in IE you need to use a proper filter:

/* For IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000')";
/* For IE 5.5 - 7 */
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000');

Combined styles for various web browsers look somewhat like that:

.shadow {
  -moz-box-shadow: 3px 3px 4px #000;
  -webkit-box-shadow: 3px 3px 4px #000;
  box-shadow: 3px 3px 4px #000;
  /* For IE 8 */
  -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000')";
  /* For IE 5.5 - 7 */
  filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000');
}


Multicolumn layouts

Another interesting feature of CSS3 is the ability to create multicolumn text layouts. We can do it using the following CSS3 properties: column-count, column-gap and column-rule. To make such layouts work in all browsers we will use Columnizer plugin (http://welcome.totheinter.net/columnizer-jquery-plugin/):

<script charset="utf-8" src="autocolumn.js" type='text/javascript'></script>
<script type="text/javascript">
function hasColumnSupport(){
var element = document.documentElement;
var style = element.style;
if (style){
return typeof style.columnCount == "string" ||
typeof style.MozColumnCount == "string" ||
typeof style.WebkitColumnCount == "string" ||
typeof style.KhtmlColumnCount == "string";
}
return null;
}
$(function(){
if(!hasColumnSupport()){
$(".3columns").columnize({ columns: 3 });
}
});
</script>

hasColumnSupport() function checks if browsers support multi column layouts. If not, then columnizer plugin is used. Line: ‘$("#text").columnize({ columns: 3 });’ will distribute text into 3 columns in all html elements having class=”3columns”.