HTML

You are currently browsing articles tagged HTML.

I’ve been working on a web project that has gone through multiple iterations, and many hands, before landing on my desk. Over that time (and while it’s been in my care, as well as before), the stylesheets have acquired quite a few geological layers. The primary CSS file has had over 2,000 lines, with more than 600 selectors spread over almost a dozen stylesheets. Since the site has gone through multiple revisions and adjustments–at least five major versions in the month or so I’ve been working on it–a lot of these selectors aren’t being used anymore.

This is a classic case of the Lava Flow anti-pattern:

When code just kind of spews forth and becomes permanent, it becomes an architectural feature of the archeological variety. Things are built atop the structure without question and without hope of changing what is beneath them. The existing code is seen as an historical curiosity.

The best thing to do with lava is to blast it away, leaving just the useful bedrock. But removing unused CSS selectors is a tedious and error-prone undertaking; my Java IDE can tell me which methods and variables are no longer in use, and profile an application for redundancies and deprecated components, but I didn’t have a comparable development tool for styles. Luckily, my core development philosophy–somebody smarter than me has already solved this problem, and has probably put the information out on the Internet–panned out, and I discovered the Dust-Me Selectors Firefox add-on.

Dust-Me Selectors can look at an individual page, or at an entire site, and tell you which selectors are actually in use. It generates a nice report, broken down by stylesheet file and including line numbers, that will direct your blasting caps and jackhammers at the problem areas. After running it through my pages, I was able to reduce that main CSS file to just over 1,000 lines (it’s a complex site), with less than 200 selectors defined.

The tool can be run against individual pages or against a sitemap; for a large site, a sitemap is by far the best approach. If you don’t have a sitemap.xml file yet, it’s relatively easy to generate one, either with your development tools or CMS, by hand for a short list of pages, or with a simple script. I found that it was less reliable in single-page mode: your coverage won’t be as good, and things like Ajax windows are going to get in the way of accurate results. A comprehensive sitemap ensures coverage.

It’s also a good idea to use caution when pruning the styles; I went through the list of flagged selectors and disabled them with comments, visually testing the site as I went along. There were a handful of cases where Dust-Me flagged styles that were actually in use, primarily within jQuery code that was manipulating element classes on the fly. After I verified that my leaner, meaner CSS files were working, I moved all of the commented code out into a new file just in case some of those selectors need to be resurrected in the future.

There are a few reasons to tidy up your CSS files. Download performance, though not as much of an issue in the broadband world, is a factor: my old core file was about 41KB, and my new one is 17KB. Browser performance, too, is a factor: parsing unneeded CSS code may be a very tiny drag on performance for faster machines and browsers, but every millisecond you save on unnecessary parsing is time you can put the browser to work doing something more interesting and useful.

The best argument for cleaning up the lava flow, though, is maintainability. Scrolling through those 2,000 lines of code in search of an errant style, or trying to debug a rendering issue when looking across a dozen files for a class or ID, is a drag on productivity. In the heat of battle, it’s far too easy just to add another selector to the bottom of the file, which only contributes to the chaos. Pruning the excess weight early in the development process makes it much easier to maintain clean code as the project moves along.

Tags: , , , , ,

Doing anything relatively complex in CSS while maintaining cross-browser support is the bane of web design. All of the major browsers–Firefox, Safari, Opera, and the various flavors of IE–interpret CSS in their own quirky ways (even Firefox slips on a couple of obscure CSS2 items), and none of them seem to agree on the particulars of their quirks. And since most web designers and developers can’t dictate the browser that their visitors will use–”works best in IE” or “please use Firefox” is so tacky–we need to engage in all sorts of trickery to get things to render passably well in the most common browsers.

This is especially frustrating in the case of Internet Explorer, where the differences between versions can be as great as their differences with other browsers. CSS “hacks” that exploited IE6’s failure to parse certain CSS selectors, for example, fail in IE7: or at least, the hacks fail, but the behaviors those hacks tried to mitigate are still there.

In the project I’m currently working on, I wanted to avoid muddying my CSS files with hard-to-decipher hacks. I want my CSS code to be readable and extensible, and to future-proof my design as much as possible against future browser quirks. Client-side JavaScript browser-sniffing techniques are less than reliable, since they often rely on the same kinds of “what features does this browser support” tricks as CSS hacks. In the past–for example, when working with IBM WebSphere Portal Server–I’ve relied on server-side rendering to deliver different CSS files to different browsers, but I wanted to minimize that, too, since I’m modifying an existing J2EE application that is as platform-agnostic as possible.

Then I discovered a hack that Microsoft built into Internet Explorer: conditional comments.

<!--[if IE 5]>
Welcome to Internet Explorer 5.
<![endif]-->

Now, there are a few things that are fundamentally wrong about conditional comments. The worst thing about them is that they violate the whole idea behind comments: comments should NOT contain executable code. Indeed, a common practice for disabling code in any language I’ve used is to “comment it out”: wrap your code in comments, and it becomes invisible to your compiler/interpreter. Wrapping code in comments and intending that code to execute is simply upside down.

Still, this seems to me a more acceptable hack than the other options. It doesn’t rely on browser bugs that, one would hope, the browser manufacturer will fix at some future point; it doesn’t result in unreadable CSS code; and it’s relatively unobtrusive, requiring only a head-scratching bit of commented code that executes in some browsers. Since it’s built on a “feature” of the browser most likely to cause you grief, this is a reasonable workaround that doesn’t adversely affect people who are able to use more standards-compliant browsers.

In my project, I deliver a full stylesheet to all browsers, and then conditionally include subsets that modify the CSS just for the browsers that misbehave.

For example, here’s an unordered list that is styled differently for IE6, IE7, and all other browsers, by using conditional comments:


  • Apple
  • Orange
  • Pear
  • Mango

If you’re using IE 7, you’ll see a blue background on the list items, and a yellow background on mouse hover; in IE 6, you’ll see the blue background but hovering won’t change the color (because IE 6 doesn’t support the “:hover” pseudo-class on non-anchor elements; more on that later . . .); and in any other browser, you’ll see an orange background with a blue hover. Here’s the code:

<style>
<!--
// all browsers (including IEx) see this CSS
ul.conditional-comments-example {
list-style:none;
color:#fff;
width:20em;
padding:3em;
border:1px dashed gray;
}
ul.conditional-comments-example li {
padding-left:2em;
background-color:#E17C1C;
}
ul.conditional-comments-example li:hover {
background-color:#1E4262;
}
-->
</style>
<!--[if IE 7]>
<style>
<!--
// only IE 7 sees this CSS
ul.conditional-comments-example li {
background-color:#016BAD;
}
ul.conditional-comments-example li:hover {
background-color:#ECE990;
color:#000;
}
-->
</style>
<![endif]-->
<!--[if IE 6]>
<style>
<!--
// only IE 6 sees this CSS
ul.conditional-comments-example li {
background-color:#4289AE;
}
ul.conditional-comments-example li:hover {
background-color:#EEEBD9;
color:#000;
}
-->
</style>
<![endif]-->

This is a trivial example, but useful for illustration purposes. In my own case, I found this approach helped me to fix some positioning problems (Firefox and Safari support “display:table” styles, IE doesn’t) and an annoying “jump” in mouse-over code that’s exhibited in IE.

This technique has some potential, if used sparingly and carefully; it would be nice if we didn’t have to use it, but it’s much cleaner than most of the other solutions I’ve seen.

Tags: , , , ,

Switch to our mobile site