Detect browser support for CSS properties

Tuesday, September 22, 2009

Adding shadows or rounded corners to any element is way more trouble than it should be, especially if you're tried out some of the newer CSS3 properties. A simple two lines of CSS can get you these amazingly gorgeous effects, but as expected they aren't supported in every browser (I'm looking at you Internet Explorer!)

Some older versions of browsers that do support these features don't use the official W3C method and you have you use a vendor specific CSS property,like so:

#coolElement{
    box-shadow:#000 3px 3px 8px;
    -moz-box-shadow:#000 3px 3px 8px;
    -webkit-box-shadow:#000 3px 3px 8px;
    border-radius:5px;
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
}

So, that of course won't work in IE, and if you want to have rounded corners or shadows on IE you have to make some custom PNG images and align everything properly. It's a lot of work, but it must be done if you want it to look consistent across all browsers. I realized today that ideally I want to do both, meaning that I want to use the pure CSS method when it's available in the browser, and the old clunky way otherwise.

Sure I could just see what works in each browser and only allow certain versions of browsers, but I'd always have to come back and update that list as future browsers add support for these things. Instead, why not test and see if the browser supports these features first, and then decide what to do.

function supportsBoxShadow(){
  var s=document.body.style;
  return s.WebkitBoxShadow!== undefined||s.MozBoxShadow!==undefined||s.BoxShadow!==undefined;
}
function supportsBoderRadius(){
  var s=document.body.style;
  return s.WebkitBorderRadius!== undefined||s.MozBorderRadius!==undefined||s.BorderRadius!==undefined;
}

Those functions will return true if the CSS property is supported in the browser, and not just the W3C property, but the vendor specific property as well. If there's some other property you want to test, follow the same pattern and just use CamelCase and remove the hyphens.

So putting this into practice is pretty simple, assuming we use the CSS property defined above.

if(supportsBoxShadow()){
    //Woo! We don't have to do anything! CSS does all the work!
}else{
    //Write your complex code here to position your PNG shadows.... :(
}
Posted by Chris Barr on 09/22 at 09:43 AM
Filed under Web, Code, Javascript, CSS1 Comments

Finding Unused CSS Rules

Wednesday, March 04, 2009

The other day I ran across a very useful article about the $$ selector in Firebug for Javascript and how to use it to loop through your stylesheets to find unused CSS styles. Very cool. The original code snippet would output everything to the firebug console, which I found to be useless on larger sites because I would hit Firebug's limit too often.

I modified it a bit to output the CSS to the actual site instead inside a styled element. So to use this on your own site, just copy and paste the code below into Firebug's console and hit run.

//Create a styled place to output styles to
var output = document.createElement('pre');
output.setAttribute("id","unusedCSSstyles");
output.setAttribute("style","height:95%; overflow:auto; text-align:left; background:#000000; border:2px outset #00CC33; color:#00CC33; opacity:0.9; padding:3px; position:fixed !important; left:5px; top:20px; width:95%; z-index:9998; font-size:12px;");

//create a styled close button
var closeBtn = document.createElement('a');
closeBtn.setAttribute("id","cssCloseBtn");
closeBtn.setAttribute("href","#");
closeBtn.setAttribute("onclick","document.body.removeChild(document.getElementById('unusedCSSstyles')); document.body.removeChild(document.getElementById('cssCloseBtn')); return false;");
closeBtn.setAttribute("style","position:fixed !important; left:2; top:0; z-index:9999; color:red; font-size:16px; padding:3px 20px; background-color:#000000; border:1px solid #FFF;");
closeBtn.innerHTML="close";

//add button and output element to body
document.body.appendChild(closeBtn);
document.body.appendChild(output);

//Find each stylesheet
for(var i = 0; i < document.styleSheets.length; i++) {
//write the filename to output element
output.innerHTML+="<br /><h3>"+document.styleSheets[i].href+"</h3>";
//find CSS rules
  for (var j = 0; j < document.styleSheets[i].cssRules.length; j++) {
    s = document.styleSheets[i].cssRules[j].selectorText;
    //write unused CSS rules to output element
    if ($$(s).length === 0) output.innerHTML+="<strong>["+j+"]</strong> "+s+"<br />";
  }
}

Do note that this has a few limitations:

  • It cannot find stylesheets from another domain or subdomains
  • It cannot find inline styles or the <style> tags anywhere
  • It will not work on sites that use Mootools since it also uses the $$ selector. (this site does, so don't try it here!)

If you're really serious about finding what CSS styles you haven't used on your site, you might want to check out a Firefox plugin called Dust Me Selectors

Posted by Chris Barr on 03/04 at 11:20 AM
Filed under Web, Code, Javascript, CSS, Productivity0 Comments