Opacity CSS Validation Using Javascript

Posted on May 29th, 2009 by Jarrett M. Barnett

I’ve always been annoyed by browser specific CSS properties. Not necessarily because of the purpose browser specific CSS properties serve, but more so the isolation of each property. For instance, applying opacity across multiple browsers requires something like the following:

#selector {
    filter:alpha(opacity=80); /* Internet Explorer */
    -moz-opacity:0.8; /* Mozilla Firefox (legacy) */
    opacity: 0.8; /* CSS3 Standard */
}

Someday when CSS3 goes completely live, we won’t have to worry about opacity not validating; however, what about other browser specific styles that we need in order to support multiple browsers? If you don’t care about passing W3 CSS Validation, then this article is not for you. But for those of you whom require validation, or have a perfectionist nature, can workaround the validation engine using both JavaScript and CSS.

Although it may not be the best method out there, using JavaScript to implement impossible-to-validate CSS works the best for me.

Why does it work? Well its simple. Most bots/spiders don’t render JavaScript, which I imagine is for a number of reasons. Perhaps rendering JavaScript would slow down the bots’ very purpose of data mining (or with bad bots, the purpose of infiltrating). In fact, there usually isn’t anything valuable to a bot that would come from having to render JavaScript. (As a side note, this doesn’t mean that their aren’t bots that seek out sites that have vulnerabilities in their JavaScript markup, but reading JavaScript and rendering JavaScript are completely different).

So first, its a matter of migrating browser specific code to its own spreadsheet (so our JavaScript can include it). 

/* invalidable.css */
#selector {
  /* random properties */
    zoom: 1;
    -moz-border-radius
  /* opacity properties */
    filter:alpha(opacity=80); /* Internet Explorer */
    -moz-opacity:0.8; /* Mozilla Firefox (legacy) */
    opacity: 0.8; /* CSS3 Standard */
}

Once you have your browser specific properties on its own stylesheet, its just a matter of creating a JavaScript file that will “dynamically” insert the <link type=”text/css” rel=”stylesheet” href=”/assets/styles/invalidable.css” media=”screen”/> into your page (thus keeping with XHTML Strict standards).

// invalidable.js  <-- note the extension
//
// Dynamically Inserts CSS Link Tag
var headTag = document.getElementsByTagName("head")[0];
var linkTag = document.createElement('link');
linkTag.type = 'text/css';
linkTag.rel = 'stylesheet';
linkTag.href = '/assets/styles/invalidable.css';
linkTag.media = 'screen';
headTag.appendChild(linkTag);

Now all you have to do is throw in an JavaScript include tag:

<script type="text/javascript" src="/assets/js/invalidable.js"></script>

Your done! Bots will now only get this: 

<script type="text/javascript" src="/assets/js/invalidable.js"></script>

…while visitors will get this:

<script type="text/javascript" src="/assets/js/invalidable.js"></script>
<link type="text/css" rel="stylesheet" href="/assets/styles/invalidable.css" media="screen"/>

NOTE: It’s important to mention that visitors who have JavaScript DISABLED will NOT have the CSS file included, simply because the JavaScript won’t process; however, I will go on to say that its incredibly rare for you to have visitors that have JavaScript disabled. The only cases you’ll probably run into is visitors who visit your site from a cheap mobile phone (iPhone supports JavaScript), or a visitor who knows what their doing and has a Firefox plugin like “NoScript” installed.

On another subject, its important to mention that Google now penalizes for showing “different” content to search engines than to visitors. Would I classify an extra line in the section as different? Probably not. It’s my opinion that Google’s algorithm would check for differences in content, and not necessarily markup. I also haven’t seen very many cases where practices such as using JavaScript to “show/hide” content, be penalized in anyway. 

4 Responses to “Opacity CSS Validation Using Javascript”

  1. Jürgen Jeka Says:

    Hi,

    -moz-opacity is dead since Firefox 0.9/ Gecko 1.7, June 2004
    -khtml-opacity is dead since Safari 1.2, February 2004

    But you need quotes for IE 8:
    filter: "alpha(opacity=80)";

    See https://developer.mozilla.org/En/CSS/Opacity

    j.j.

  2. If you’re going to require that javascript is installed, why bother with all the extra time and effort it takes to include an entire CSS file when you could simply make the element opaque with javascript? :S

  3. I included the ‘-moz-opacity’ and ‘-khtml-opacity ‘ properties specifically for the “legacy obsessed” (hence the legacy CSS comment).

    Also based on current analytic reports (Javascript based), about 2-4% of visitors (of the 40% of visitors that use Firefox) are still falling into that bracket. If you don’t care about the very few users that still use old versions of Firefox, then ditch -moz-opacity. :)

    It’s probably useful to know that -moz-opacity (in all subsequent versions prior to Firefox 3.5) acts as an alias for the proper ‘opacity’. So I suppose its not completely useless; probably similar to how iframes are still being used (despite not being XHTML strict compliant).

    As far as being backwards compatible with older versions of Safari, no one cares (at least I don’t) :) – I personally don’t use -khtml-opacity, but I figured someone may have wanted to include it.

    You should also know that its not proper to use the “filter” property as it in itself is not compliant. Hence the proper way to apply opacity in Internet Explorer 8 is:
    [sourcecode language="css"]
    /* Note that it begins with a hyphen for proper etiquette */
    -ms-filter: “progid:DXImageTransform.Microsoft.Alpha(Opacity=0)”;
    [/sourcecode]

    You are also correct that quotes need to be added (also for proper etiquette). I’ve made the change in the post ;)

  4. I find it easier to simply have one CSS file control all the rogue CSS properties (such as opacity), than to have too much Javascript. I suppose its because I prefer CSS over Javascript anyway. (I believe too much Javascript is a bad thing, AJAX being the exception of course).

    -and bad Javascript markup has far worse consequences than bad CSS markup. Hence my preference. :)