TV version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer


Weblog Entry

CSS Problem-Solving

March 10, 2004

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.


Reader Comments

Mike P. says:
March 10, 01h

Great post Dave.

Here’s one, well two, I suppose, that have bit me in the past for some things and now I’m careful of…. Not really bug killing but bug avoiders…

1. Leave a space between your last selector and an opening curly brace.
i.e. don’t do this this -> #mydiv{

2. Careful not to leave a comma between your last selector and an opening curly brace.
i.e. don’t do this -> #mydiv, {

The first one bit me in IE, the second in Mozilla….

web says:
March 10, 01h

I’m with Chris Nott, background color is the best way to help debug complex css/html.

Also setting something to “!important” fixed what I thought to be bugs tons of times.

March 10, 01h

Borders definitely will screw up normal-flow layouts; however, I really just use that for situations where I’m getting display/ redraw issues due to boxes sitting on top of each other. It’s more a way to disabuse myself of misconceptions about my code.

I’ll 2nd (3rd, 4th, nth) the Moz/ Firefox Web Developer tool sets.

March 10, 01h

Another thing that will probably sound crazy, but it makes debugging so much easier for me: I use tabs/ indents to indicate elements exist inside of other elements. It makes CSS easier to scan and is a handy reminder that if I can’t see why something is doing what it’s doing, it might be an inheritance issue. You can see an example of what I mean here: http://www.cbeyond.net/

5
Scott Plumlee says:
March 10, 02h

I’ve also found that copying the style sheet to a new one, making the page use that, and getting rid of the “cascading” in the style sheets helps me pinpoint. Only seeing things that I’ve explicitly declared, rather than allowed to cascade, often gets to the root of the problem. Many times a cascade that isn’t working the way I thought has bit me.

And the DOM inspector in Moz/Firefox is the best tool I’ve seen for checking things out.

blufive says:
March 10, 02h

Great post.

I’ll add to what Scott said about Moz’s DOM inspector.
- Clicking around the DOM tree flashes borders on the elements, without messing up the layout.
- You can browse the style rules being applied to each element, including the browser defaults (great for catching typos in selectors and/or xhtml attributes)
- You can browse the computed style on the elements

The only real problem I have is that whenever I break it out (every time I hit a problem) I end up wishing I had a screen about 2048 by 1536 pixels, so I had enough room on the desktop…

7
Jimmy Cerra says:
March 10, 04h

Instead of using a border, you could add a background to the specific problematic areas. This doesn’t affect the element’s width (which borders do), yet you acheive a simular effect. Unfortunately, you can’t use blanket selectors, or everything would get the styles, but everything has a trade-off.

P.S. Don’t give away all your trick, or nobody will hire you! ;-)

March 10, 06h

If you’re having a problem in IE Windows that seems to be unsolvable, and you’re using the XHTML Strict DOCTYPE, try ripping out the DOCTYPE and see if this clears it up. This has worked for me (well, eventually, after several headfulls of hair have been torn out and Bill Gates’ family have been cursed for several generations) on numerous occasions, for reasons I’m yet to get to the bottom of.

Yes, I know it’s got to do with Quirks mode, but I haven’t worked out a way to overcome the problem while leaving the DOCTYPE in there, so no, my pages don’t validate - even though they are valid in every way but having the DOCTYPE, if that makes sense.

I’ve come across this in all sorts of instances, including funny positioning glitches and gaps, and to give a recent example, if you put the DOCTYPE back into the pages in my otherwise beautifully valid CSS tutorial

http://www.westciv.com/style_master/academy/hands_on_tutorial/index.html

all the links in both the left navpanel and the horizontal one become “non-links”.

So, in summary: ditch the DOCTYPE and see what happens.

Guybo says:
March 10, 06h

Another common problem solving technique (which applies to more than just CSS) is the process of elimination…

Sometimes, for particuliar problems I’ll save a copy of my CSS file and then delete the first half of all the CSS and see if this effects the problem. If it does then halve again; otherwise you know it’s in the other half. Repeat and in a few steps you’ll zoom in on the offending code.

feather says:
March 10, 07h

Chris Pederick’s toolbar rocks, but none of you have mentioned what I have found to be *the* best tool that is there…

Under the “Information” set of buttons, you need to toggle on “View Style Information”

Once you set that on, your cursor turns to a crosshair, and no matter what element of the page your cursor is over, it shows the DOM/inheritance path to that element in the status bar.

Then, when you click on an element – it pops open a new tab that has a list of all the style rules that apply to that element, along with the line number.

It is, quite simply, the sweetest debugging tool I’ve found…. better than the original Mozilla DOM inspector and its somewhat clumsy interface

11
David House says:
March 10, 12h

I have a very useful bookmark in my ‘Useful Stuff’ folder, which basically generates a new stylesheet which marks out a load of the classes and ids:

javascript:(function(){var newSS; newSS=document.createElement(‘link’);newSS.rel=’stylesheet’; newSS.type=’text/css’;newSS.href=’http://www.codepoetry.net/stuff/css-debug.css’; document.documentElement.childNodes[0].appendChild(newSS);})();

Hope that helps someone!

Gordon says:
March 10, 12h

A simple one, learnt the hard way: double-check the spelling of all your elements. That DIV tag that is set as “active” in the HTML is actually “activated” in the CSS!

And I’ll second the usage of colour tip. I always start with every element having a background color and border color set, garishly if need be.

March 10, 12h

I keep the following in all my CSS nowadays:

/* DEBUGGER
div {border: 1px solid red;} */

And uncomment whenever things go wrong.

beto says:
March 10, 12h

Great piece of advice. I do the border thing countless times daily and comment values on and off/reload to see if there is any difference. Many times, this is the only accurate way to figure out what is going on. Being exposed to repeated issues from both IE and Mozilla has given me a good knowledge of what to expect of the behavior of a given CSS property in each browser and most importantly, how to fix it quickly. Another tip is to set parent element’s padding to 0 at all times and mess around with the child elements’ padding to compensate…

March 10, 12h

Good tips. And Tom, that little bit of code is genius; I think I’ll start using that!

Something that I did recently on a client’s site after a few maddening hours of debugging is what I’ve dubbed ‘sketching.’ After writing the HTML and before adding the images and actual content, I start styling with brightly-coloured blocks and obvious borders in place of where the images would usually be, to make sure everything is positioned properly in every browser. Big blocks are much easier to work with than images!

March 10, 12h

Instead of toggling a border (which can change the total width/height of an element and, thus, screw up a layout), use background colours.

March 10, 12h

If you’re using Firefox, the Web Developer toolbar (http://www.chrispederick.com/work/firefox/webdeveloper/) has some nifty debugging tools; it’ll outline elements for you, show you ID and class details, hide images, etc. It’s exceedingly handy.

March 10, 12h

I find the Web Developer Toolbar for Mozilla/Firefox to be very useful when doing CSS problem solving. It has buttons for validating html/css, viewing source in new tab, turning off javascript, and putting borders around element, among other features. All of the techniques can be done manually, but it’s great to have easy access to it in a toolbar.

The Web Developer Toolbar:
http://www.chrispederick.com/work/firefox/webdeveloper/

March 10, 12h

Your first tip is my favorite. Turning on borders has saved me so much time in the past. I usually color them #f00 for debugging visibility. It helps a lot to see just where the browser is putting that box.

That debugging stylesheet over at codepoetry looks promising as well, but I couldn’t get it to work with Firefox on my pc.

Trent says:
March 10, 12h

When you first encounter a problem, try to get it fixed in the most standards-compliant browser you have. Then go back and try to get it looking right in IE^h^h^h the less standards compliant browser.

21
Michael says:
March 10, 12h

To test borders I include the link below in my footer during development. It turns on all the div borders with a click. It doesn’t work in all browsers but it helps. I had to encode it for this forum.

<a href="javascript:d=document; el=d.getElementsByTagName(‘div’); for(i=0;i<el.length;i++) el[i].style.border=’1px dashed red’; el=d.getElementsByTagName(‘span’); for (i=0;i<el.length;i++) el[i].style.border=’1px solid black’;void(0)">Show DIVs</a>

March 10, 12h

Opera and Mozilla can both show outlines as well as borders, which don’t take up space in the layout. (Opera’s support is standard CSS, Mozilla’s is valid custom CSS.)

Opera also has two user styles that might be useful. One shows structural elements by name, the other outlines everything for you.

I find another tip handy. Reduce the browser window smaller and smaller until the layout starts to break. Don’t assume “if it works at full screen, it must be OK”. I’ve two layouts now that break badly when IE6/Win goes a tiny few pixels below 1024 width. One was due to an overlong line of text in a blockquote, the other I solved last night by clearing a div below a line of floats. In both cases, my side menu was disappearing to the bottom when the window got too narrow.

This tip can also show what happens when images and text overlap. I found a background image on the right was covering my header graphic on the left, when reducing the window too small, yet only in IE6. By testing in the three common Windows browsers at once I was able to see this. The solution turned out to be z-index. IE6 required the background image to be -1! But that made it disappear in other browsers, which were happy with a z-index of 1. So this has required me to add a standard hack to supply the value needed to IE6.

Test your layout in all manner of screen shapes and sizes. Even ones beyond your current monitor size. Switch it to a higher size, even if it becomes too fuzzy to read, just to see what happens. The results may surprise you.

March 11, 02h

Good set of reminders Dave. I’ve done similar things in the past to solve CSS design issues, including and not limited to:

A) Apply a coloured border… (though “outline” is preferable if supported)

B) Set a background colour, which is sometimes preferable to A as it doesn’t change the sizes of elements by adding a pixel.

C) Use a translucent coloured PNG/dithered transparent GIF as an element background… much like B but you’d still be able to “see through” it. Handy for browsers that don’t support CSS3’s RGBA/HSLA colour model (though the current CSS validator doesn’t support CSS3 either)… and stops you putting non-validating CSS which may break rules when you least expect them.

But personally, I wouldn’t wanrt to advocate:

“So, in summary: ditch the DOCTYPE and see what happens.”

DOCTYPE switching, not ditching works… plus there’s the minimal test-case CSS debugging method:

http://www.positioniseverything.net/articles/mys-bug.html

March 11, 02h

You can’t always add a background image - if your layout problems stem from using one to start with!

Don’t forget also that the DOM Inspector allows you to EDIT styles! So you can make an element stand out, or even delete it altogether, and the changes appear instantly, but without changing your actual file.

March 11, 03h

to: Maxine Sherrin

Ripping out the DOCTYPE isn’t necessary, but having the directive at the begin of the page will put IE into quirksmode… I think I read it on Tantek’s site but it solved my big ‘Why isn’t IE rendering the code right’-Mystery

http://club.studiant.be/translatio/test/ <- a revision of my site, finally with a decent css markup (the current has valid xhtml but looks like hell when run in compliant mode)

26
Bob Cieszkowski says:
March 11, 09h

I find the border trick to be invaluable. But sometimes I want to see the the varying levels of containers which one color alone doesn’t help. I like to use this:

div {border: solid 1px blue; padding: 2px;}
div div {border-color: red;}
div div div {border-color: green;}
div div div div {border-color: orange;}
div div div div div {border-color: purple;}
div div div div div div {border-color: yellow;}

Kris says:
March 11, 09h

If you use the border trick, somtimes adjacent borders of the same color can make hard to distinguish the boxes. If you however apply the border-style ‘ridge’ with a decent (2-4px) border-width, these adjacent borders become a lot clearer.

One of the things I sometimes do when i have trouble getting a style applied, is seeking for a parent element with an ID on it.

For example, if the following class doesn’t work for one reason or the other that I cannot find out…
p { color: red; }
p.foo { color: green; }

I simply apply..
#parent p.foo { color: green; }
..to override it and be done with it.

Gordon says:
March 11, 09h

Somewhat related - when checking a design in Firefox be aware that it doesn’t compensate for the lack of a scroll bar - so no you aren’t going mad your design does leap over 17 pixels or so when it doesn’t require a scrollbar (on one page) and then leap back when the scrollbar reappears!
Sorry shouldn’t be venting here!

29
Timo Brimhall says:
March 11, 10h

I know there is a dislike for IE out there but I like using the IE Booster utility to help debug.
http://www.paessler.com/iebooster/

March 11, 12h

This web development bookmarklets make all the difference for me:

http://www.squarefree.com/bookmarklets/webdevel.html

I specially like the edit and test styles, computed styles (let’s you click on any part of the page to see what selectors and attributes are being applied) and show blocks.

Hope it helps

March 11, 12h

OK. It’s 5 am so please forget misspellings.
Here’s a funky favelet I use for debuggin. Forget red borders and DOM inspector.
Add to Favorites or copy and paste the following 4 lines on your address bar:

javascript:void(z=document.body.appendChild( document.createElement(‘script’))); void(z.language=’javascript’); void(z.type=’text/javascript’); void(z.src=’http://ultimorender.com.ar/funkascript/beta/script/csswatcher.js’);

DOUBLE CLICK to get background highlighting and AGAIN to lock highlight on an element.

(Actually I keep the script within the HTML while developing, so I don’t have to click again and again on the favelet)

March 11, 12h

Do’h. It has turned my quotes into curly quotes. The preview didn’t do that!
OK, here’s a link to get the thing:
http://ultimorender.com.ar/funkascript/favelets/cssdebug.htm
enjoy

dusoft says:
March 12, 02h

I would recommend instead od turning on borders, turning of the background - It’s much more visible.

Also when in doubt or having bg image and want to have bg colour over, use background: #XXX; after specifying background-image.

To turn off, but not to delete property in CSS sheet, I prefer to do prepend ‘a’ character before properties to be turned off.

E.g.:

margin: 50px;
border: 1px;
font-size: medium;
becomes:
amargin: 50px;
border: 1px;
font-size: medium;

And margin is turned off. Most of the browsers will just ignore it.

34
Andrew Cameron says:
March 12, 03h

Excellent list, I use many of those myself. One that I came across recently was the apparently optional xml declaration that for certain pages, IE6 doesn’t find optional with XHTML Strict. I was developing a complex Intranet application with the target browsers being IE5.0 and above. I deployed a beta and found that because of a different PHP installation, some things weren’t quite right. I did some fixing and some random deleting of markup and found that although IE5.0 and 5.5 worked fine, my DIVs were all over the place in IE6.

Utterly confused, I took the bare markup of a page home to try it, and thankfully the first line that was different from my working page was the xml declaration. I stuck that in and my week-long pain was over! You could say I’m not the biggest fan of IE’s quirks.

This also ties in with another tip - keep backups of the “last working version” of your site and do side-by-side, line-by-line markup comparisons. If something is different, it’s most likely the problem. Hope this helps someone.

March 12, 05h

>comment ‘em out.

That should be comment ’em out.
http://kandent.com/archives/2004_02/basic_html_typography.html

tekp says:
March 14, 05h

As posted by Gordon way up at the top:

I once had in my XHTML and in the syle #layout-counter. It took be a good ten minutes to actually realise what had gone wrong and by then I had a few bruises on my forehead and fists.

March 15, 01h

In Firefox at least, you can also do:

* {
border:1px solid red;
}

To get borders on everything. And Jesse’s site at squarefree.com is great - there’s a bookmarklet there called ancestors that shows the id and class of the element you hover over in the status bar.

March 15, 07h

Great advice and hints - many thanks.

Have to agree about the edit styles bookmarklet from Jesse Ruderman http://www.squarefree.com/bookmarklets/webdevel.html - it is a great time saver - it opens a window with the style sheet so that the effect of changes made in the css can be seen immediately without needing to save and refresh the page.

March 16, 03h

Nice one Dave!

Gota agree with that idea on borders. I have the web developer tool bar on firefox also, but using a border in your css really does help to only pick out one or two elements, and of course see what the hell IE is doing to my pages now.

About that Style Information option on the toolbar someone mentioned earlier …. How on earth do you get it to work??

Mine is always greyed out so that I never have that option. Does it not work with imported css?

March 17, 05h

I totally agree about the borders. Except, I have a favelet from http://www.accessify.com/tools-and-wizards/accessibility-checking-favelets.asp that automatically turns them on all divs and makes them red. A huge timesaver!

Dan Tshin says:
March 20, 05h

I’m in the middle of designing a site for a Thai NGO (http://www.jpthai.org/ - not yet in production), which will then be cut up into modules to be served by a CMS. As this is my first “real” web standards project, I jumped into researching a bunch of tools.

I really like Web Developer by Chris Pederick! Just awesome.

Also, from my background in software development, I find CVS a necessary tool to manage version differences - I’m using TortoiseCVS http://www.tortoisecvs.org/ on my WinXP box. For diffs (I manage to mess up working CSS files once in a while - and need to “revert”) It calls up WinMerge http://winmerge.sourceforge.net/ to compare a CSS file between checked-in versions.

Yeah, I know this is more meta-development stuff. Just some more (good) tools to add to your mix. Lots of the tips above are great!

October 14, 10h

Phil Baines,

My “View Style Information” was greyed out also until i did …

Right click -> customize -> drag css into components box -> drag css back out of components box