This is the celebrated journal of Mr. Simon Collison A.K.A Colly

Prevent dynamic collapsing margins

15th July 2004

I’m aware of margin collapsing with CSS. It’s a pain. However, I’ve had a slightly different issue with margins over at IE 6 (PC). Bizarrely, the margins are showing correctly spaced, right up until the user slowly mouses over them.

At that point the margins collapse dynamically, as though powered by Javascript. I couldn’t have designed that with CSS if I’d tried! Luckily, I’ve worked out how to resolve the issue - and the solution is fairly obvious.

image of the elements

To see this problem in action, you’ll need to view CollyLogic on a PC using IE (preferebly IE 6). The boxes in my sidebar have parallel borders all the way around, made with two nested divs. If you gently roll the cursor over the bottom borders of certain boxes, you’ll notice that the two grey lines close up, refusing to open up again. Bloody annoying.

Update: I have now implemented the fix site-wide, so you’ll just have to imagine the effect.

Margin collapsing is a well-known phenomenon. You’ve got two margins meeting up. One is 7px and the other is 2px. You’ll get a 9px space between the elements, right? Wrong. The 7px overrides the 2px. You can of course do what I did, and pretend the problem doesn’t exist because you use a Mac.

In his excellent article No Margin For Error, Andy Budd suggests the following to counter standard ‘collapsing margins’:

There are number of ways to get round margin collapsing issues. One way is to add a border or 1px of padding around the elements so that the borders are no longer touching and so no longer collapse.

If you’re not aware of the issue, Andy’s article gives a great background to the various quirks. Anyway, for some reason, Andy’s advice wasn’t working for me this time (it has before). I had to sit down and make sketches of the various elements and the spacing until I figured out how to beat it.

A way to beat Dynamic Collapsing

Firstly, I’ve created a more semantic method of representing each box, removing a div, replacing it with a styled unordered list. Note, I’m only using these styles on my test page at the moment.

image

The important bit

All I needed to do was create reverse margin and padding statements. The key settings obviously affect the bottom margin/padding for each element. Here are the two important excerpts from the two revised styles:

code example

So, it’s a 0 0 2 0 - 2 2 0 2 reverse on margin and padding. Basically, this removes the need for a bottom margin from the inner (unordered list) box, by adding substitute padding to the outer (hope) box. Thus, no two margins are coming together. The 7px bottom margin of hope has no margin above it to collapse against.

I couldn’t make the settings uniform around all sides here due to my desire to avoid any width padding (which would’ve meant box hack inside box hack - nasty).

So, that seems to have solved it. As I said, I haven’t applied these changes to this page or the rest of the site yet - just the test page. Unlikely to be helpful to many, but hopefully helpful to someone.

The point of all this?

Why the blooming ‘eck does IE (PC) make the margins dynamic! How does that help anyone? If you have another solution, or it’s happened to you, lemme know.

Responses

Lewis Henshall

# Lewis Henshall responded on 17th July 2004 with...

Hmm, I think this may lead to a solution for a related problem. On my Web forms I use the javascript event handlers onfocus and onblur to change the class of the fields, the purpose being to change the style of an active field and make it look all pretty.

Testing it in Internet Explorer I noticed that when the user clicks into a field it (the field, not the user!) actually moves on the screen. Clearly not something that I would want to happen!

I had stopped styling those particular classes, but I’ll get around to putting this information to use and hopefully my fields will be pretty again soon.

:-p

Josh King

# Josh King responded on 17th July 2004 with...

I know this won’t apply in all instances and is a painfully obvious solution, but I try to stick with only specifying top margins. This way I don’t have to worry about what comes after, I only have to worry how much an element should be offset from the one before it.

Simon Collison

# Simon Collison responded on 17th July 2004 with...

Obvious it may be Josh, but that has to be the best approach. Sometimes however, I do need to make an element do several things, in this case avoiding the need for a spacer div under each element, and avoiding the need for a seperate top box div with top margin removed (otherwise the whole side column would be dropped down by 7px). I know there are other ways (neg margins on the sidebar for instance) but for now this solution will work fine - once I finally implement it site-wide.

Lewis, I’ve also had similar problems to the one you describe, and it had been down to CSS positioning being chewed up by IE. Let me know how you get on…

Lewis Henshall

# Lewis Henshall responded on 19th July 2004 with...

What I use is the following:
onfocus=“this.className=‘thisinput’;this.select();” onblur=“this.className=‘nolongerthisinput’;”

The class “thisinput” changes the border colour and the class “nolongerthisinput” changes it back. “this.select();” in the onfocus event handler is just a little extra.

The CSS I am using is:
input, textarea {
border : medium solid #eeeeee;
background : #ffffff;
padding : 0.3em;
margin : 0;
clear : left;
}
input.thisinput, textarea.thisinput, input:focus, textarea:focus {
border : medium solid #000088;
}

Standards compliant browsers wouldn’t need the javascript, because the pseudo property “focus"achieves the effect with a lot less code.

For the contact form (http://www.lewishenshall.co.uk/contact/) on my Web site as it is at the moment, the onblur event handler for 5 input fields and 1 textarea increases the page size by 302 byes. That’s not that much now, but for every additional field that’s an extra 50 bytes just for the onblur code, not including onfocus.

I did used to specify the original background colour using the class “nolongerthisinput.” Through testing I’ve found you don’t even need to specify any code for it. Changing the class from “thisinput” effectively clears any changes that were made by that class, and the style of the field reverts back to those for “input, textarea,” de-cascading I suppose.

Simon Collison

# Simon Collison responded on 21st July 2004 with...

Ah, I had to use IE to see this - nice effect (although on Mac the boxes bust out of their containers). As you say, standards-compliant browsers already have an auto version of this.

Anyway, works fine on our PC - no sign of the input fields repositioning themselves.

Responses are now disabled Your ability to respond is disabled automatically some 30 days after articles are published, or manually much sooner if spamming guttersnipes target a particular article.

Prev 244 Next

Superfluous Aside

Archived in HTML & CSS, Design & Web

This post's Short URL is http://col.ly/s/244

There are 5 responses

External References

Copyright © Mr. Simon Collison 2003-2014. Protected and licensed under a Creative Commons License. Grab the RSS feed

Engineered in Nottingham, scaffolded by ExpressionEngine, steam-pumped by United & kept alive with tea and hugs.