Disabling Deprecated HTML Using CSS

When handing over a project to the client, you sometimes loose control over the content HTML source. Sometimes the client uses a CMS that allows them to have full control over certain parts of the HTML, and sometimes the client simply uses your templates to insert their own HTML content in the document.

It can be hard enough to inform the client about how to use the templates or CMS you provided, and sometimes there is simply not enough room to educate and lecture about semantic HTML and standards. The client will use their plain old markup they once learned, simply because it still works and looks the way they are used to. That will most likely involve some deprecated HTML tags and attributes, such as bgcolor, align and the dreaded <font> tag. This article is about disabling the deprecated tags using CSS, thus gracefully guiding the client in the right direction.

There are several approaches to this problem. One is to place a warning image using CSS when deprecated HTML is used. Another is to use server side stripping before presenting the HTML, removing tags and attributes that are not allowed. While server-side stripping is probably the most effective way of presenting good HTML, you do not always have full control over the server where the site will be hosted and the client might not use a custom CMS.

The idea is to preserve the natural cascade and inheritance in all browsers, while gracefully disabling the HTML we don’t want the client to use. That way the client will stop using it, simply because it doesn’t “work” anymore. A graceful and gentle way of guiding the client in the right direction.

Deprecated HTML

In this article, we will address some of the most popular deprecated HTML 4 tags and attributes, such as:

  • <font>
  • <basefont>
  • <center>
  • <strike>
  • <s>
  • <u>
  • bgcolor
  • border
  • align
  • vspace
  • hspace
  • valign
  • width
  • height

The Solution and Problem

In a perfect world, we could simply adjust some of the HTML tags with the inherit value for the equivalent CSS property. Standard browsers will ignore any deprecated attributes set inline and instead use the inherited value in the cascade. For example, this CSS:

  1. font { color:inherit; }

…will override the following HTML:

  1. <font color="blue">blue</font>

The <font> tag will be rendered using the inherited color instead of blue. Just as we wanted. But as you probably know, Internet Explorer has a problem with inherited values. Even in version 7. So the task begins.

Expressions and currentStyle to the rescue

The inherit value is fairly simple to understand. Some CSS properties has a default value of inherit, which means that they will inherit their parent’s value for the specified properties. The problem is that it will be ignored if a deprecated inline attribute such as color is applied, unless we specify inherit in the CSS. But since IE ignores the inherit value in most cases, we have a problem.

CSS expressions were introduced in Internet Explorer 5.0 and it allows you to to assign a JavaScript expression to a CSS property. All other browsers will simply ignore the expressions. This is gods gift to CSS designers, since many IE bugs can be solved this way. In this case, let’s try the following:

  1. font {
  2. color:inherit; /* standard browsers */
  3. color:expression(this.parentNode.currentStyle['color']); /* IE */
  4. }

Yes. That works. So using the same technique, we can disable several deprecated tags and attributes in all browsers.

But there are more issues to solve before we reach our goal.

Font-Family and font-size

Using the same technique as described above, we would use this to disable the face attribute in font tags:

  1. font {
  2. font-family:inherit; /* standard browsers */
  3. font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
  4. }

That works fine. Except that Opera 9 can’t inherit font-family. font works however, so let’s change that to:

  1. font {
  2. font:inherit; /* standard browsers */
  3. font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
  4. }

Ok. So let’s move on the to the font-size. This is delicate, since font size values are inherited into a computed value. The same expression will not work anymore because: if the body font size is set to 2em, the font size will start it’s calculations from there. It will check the font tag’s parent font size, which is 2em, and present a computed value of 4em (2em’s of 2em). Not what we wanted here. The solution is to simply use font-size: 100% for all browsers, since we don’t want any additional calculations based on the font attributes.

Let’s add the same properties to the deprecated <basefont> tag to disable that as well. So here is the complete CSS to disable <font>and <basefont> tags:

  1. font,basefont {
  2. color:inherit; /* Standard browsers */
  3. color:expression(this.parentNode.currentStyle['color']); /* IE */
  4. font:inherit; /* Standard browsers. Font instead of font-size for Opera */
  5. font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
  6. font-size:100%; /* All browsers. Sizes are inherited */
  7. }

Let’s apply the same basic technique to disable the <center>, <s>, <strike> and <u> tag:

  1. center {
  2. text-align:inherit; /* Standard browsers */
  3. text-align:expression(this.parentNode.currentStyle['textAlign']); /* IE */
  4. }
  5. s,strike,u {
  6. text-decoration:inherit; /* Standard browsers */
  7. text-decoration:expression(this.parentNode.currentStyle['textDecoration']); /* IE */
  8. }

We have disabled the most common deprecated HTML tags using CSS only.

The attributes

HTML 4 includes a number of deprecated attributes that can be annoying to handle. Let’s start with disabling the align attribute:

  1. *[align] { text-align:inherit; } /* Standard browsers */

This works for standard browsers. But what about IE6 that doesn’t understand the attribute selector? We can upgrade the expression to include a tertiary operation that checks if the align attribute has been assigned. So here is the CSS that disables the align attribute in all browsers:

  1. *[align] { text-align:inherit; } /* Standard browsers */
  2. * { text-align:expression(this.align ? this.parentNode.currentStyle['textAlign'] : ''); } /* IE */

Next up is the <img> attributes. In addition to the previous align attribute, we also want to disable the border, vspace and hspace attributes. Since margins and borders aren’t inherited we can simply add the following rule:

  1. img { margin:0; border:none; } /* All browsers. Borders & margins are not inherited */

This is where we encounter the first non-solvable problem in IE6. vspace and hspace is not equal to margin in IE6, so IE6 will still apply the vspace and hspace. The solution in this case is to add a minimal JavaScript to address IE6 by removing the attributes onload:

  1. window.onload = function() {
  2. for (i=0;i<document.getElementsByTagName('img').length;i++) {
  3. document.getElementsByTagName('img')[i].removeAttribute('vspace');
  4. document.getElementsByTagName('img')[i].removeAttribute('hspace');
  5. }
  6. }

We would prefer to avoid external JavaScript altogether, but in this particular case we can not find any other alternative. So let’s leave it with that. Next, let’s disable the type attribute in <ol> tags:

  1. ol { list-style-type:decimal; } /* All browsers. Removes the type attribute */

And then the bgcolor in body tags:

  1. body { background-color:transparent; /* All browsers */> }

The table

Now we reached the final chapter: the table. Using tables was the main layout technique in the old days, so HTML 4 has a number of deprecated table attributes. But we don’t want the client to use tables for layout at all, so it’s best to disable all deprecated attributes for table tags, including width, height, bgcolor, valign and border:

  1. table,tr,th,td {
  2. width:auto; /* All browsers */
  3. height:auto; /* All browsers */
  4. background-color:transparent; /* All browsers */
  5. vertical-align:inherit; /* All browsers (works in IE) */
  6. border:none; /* All browsers. Borders are not inherited */
  7. }

Wrapping it up

Using these CSS snippets and possibly also the minimal JavaScript, we can disable most deprecated HTML 4 tags and attributes while gracefully allowing natural inheritance. We do not need to “educate” the client, since they will be automatically forced to use proper markup instead. On a side note: It’s important to present a number of classes for the client to use instead, so they don’t encounter any limitations.

The complete source code:

 <style type="text/css"> font,basefont { color:inherit; /* Standard browsers */ color:expression(this.parentNode.currentStyle['color']); /* IE */ font:inherit; /* Standard browsers. Font instead of font-size for Opera */ font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */ font-size:100%; /* All browsers. Sizes are inherited */ } center { text-align:inherit; /* Standard browsers */ text-align:expression(this.parentNode.currentStyle['textAlign']); /* IE */ } s,strike,u { text-decoration:inherit; /* Standard browsers */ text-decoration:expression(this.parentNode.currentStyle['textDecoration']); /* IE */ } *[align] { text-align:inherit; } /* Standard browsers */ * { text-align:expression(this.align ? this.parentNode.currentStyle['textAlign'] : ''); } /* IE */ img { margin:0; border:none; } /* All browsers. Borders & margins are not inherited */ ol { list-style-type:decimal; } /* All browsers. Removes the type attribute */ body { background-color:transparent; /* All browsers */ } table,tr,th,td { width:auto; /* All browsers */ height:auto; /* All browsers */ background-color:transparent; /* All browsers */ vertical-align:inherit; /* All browsers (works in IE) */ border:none; /* All browsers. Borders are not inherited */ } </style> <script type="text/javascript"> window.onload = function() { for (i=0;i<document.getElementsByTagName('img').length;i++) { document.getElementsByTagName('img')[i].removeAttribute('vspace'); document.getElementsByTagName('img')[i].removeAttribute('hspace'); } } </script> 

Now we have taken care of all deprecated HTML4 tags and attributes and you are all ready for HTML5 production.

Working with HSL in CSS | CSS Buttons demo | Avoiding Flickering in jQuery | Galleria Demo