CSS Problem-Solving

March 10, 2004 11AM PST

After spending an hour debugging CSS with Tim Bray this morning, it occurs to me that the most valuable skill to possess in the maddeningly complex minefield of today’s browser landscape isn’t, in fact, knowing which browsers do what to which properties. It’s problem-solving.

Browsers are the wild card in CSS. If everything worked according to spec, the development process (once you’ve figured out the complexities of the box and float models) would be relatively straightforward. But we’re not living in that perfect world, and most of the time what they do isn’t quite so important as how you cope with what they actually do.

To that end, the CSS Crib Sheet was meant to aid the process of debugging, and it covers a few points, but I realized this morning that there are some tricks I use to diagnose a problem that don’t show up on any resource guides. I figured I’d share.

Turn on borders.
One of the biggest problems I’ve faced is visualizing what exactly is happening, and why. Is that extra space a margin, or some padding? Is it the margin of the parent element, or the child? Is it even caused by either of the two elements, or something else? By applying an arbitrary bright-coloured and obvious border (#F00, #0F0, and #00F) to each element, parent and child(ren), the boxes reveal their constraints and spacing a lot more obviously. Background colours often help too.
Check your selectors.
Likewise, using the border trick or background colours to highlight the element you think you’re working on can save a lot of frustration. Due to cascading and inheritance, your selector may not actually be applied properly. Do something to check when in doubt; make the element obvious by making it ugly. If the change doesn’t take effect, then the selector is your cuplrit.
Adjust values.
Font size too small in Mozilla, but fine in IE? Bump it up a bit. Even the slightest bit helps. Going from 0.9em to 0.91em can make a world of difference. Similarily, adjusting margin and padding to wild values that you have no intention of keeping can often make a difference in how something renders, and frequently will squeeze out the root problem through process of elimination. You can always set them back after you’ve solved it.
Hide selective elements.
Speaking of process of elimination, how do you know that the element you’re working with is the problem? Try hiding surrounding elements, and leaving parent elements (all the way up the chain, as far as the body itself if necessary) as unstyled as possible. Comment them out, don’t delete them, because you’ll need them later. Sometimes widths and heights and floats and margins and so on can interact in ways that you don’t expect. Reduce and isolate the problem as much as you can, to make sure other elements aren’t having a deleterious effect.
Get rid of unneeded CSS.
If you have dummy properties that aren’t contributing to the net styling, comment ‘em out. Remove all possible variables by reducing your declarations to the bare minimum needed for the effect you’re trying to achieve. Sometimes things you wouldn’t suspect will be at fault.
Set your margins to 0.
When in doubt, specifically set the margins of your element(s) to 0. You can’t always rely on a browser’s default values.
Validate.
Good lord, nothing is going to work if you have improperly nested and unclosed elements! Always make sure your (X)HTML is kosher before even starting to think about your styling.

These are but a few; there are more I’ll write up as I use them. Feel free to comment with your own problem-solving techniques. (This could very well end up an offshoot resource the way the Crib Sheet did.)

Remember, the key is to highlight the behaviour. Why the browser is displaying a quirky behaviour doesn’t always make sense, but if you can work around the problem just by quick testing, it doesn’t necessarily have to.