Negative CSS Margins Are Not Cool

Posted March 5, 2008 at 8:29 PM

Tags: HTML / CSS

This is a bit of blanket statement, so clearly it is not going to be true all of the time; but, it is my very strong opinion that if you have any negative margins on an XHTML element, then the code is not cool. I know that every now and then I come out with these very black and white statements like this and get heat for it, but I just feel this so strongly in my gut. Plus, I have spent too much time filling in on projects where, time and time again, negative margins have been breaking layouts across browsers and on pages with dynamic content. It's driving me a little bananas.

Now, before you get all steamed up and throw the tomatoes, take a moment and think about it. A negative margin? Shouldn't that very idea seem like a physical impossibility? How can an object have a negative margin? Yes, we all know what it does at a practical CSS level, but the very idea of it feels so wrong. Shouldn't your code feel right? Shouldn't you be proud of it and want to take it home and have it meet your mother and then let it sleep in another room because even though you love the code so much you're at your mother's house and it's her house, her rules?

Instead of using a negative margin, maybe try floating an element? Or perhaps positioning it absolutely to its parent? Before you even consider a negative margin, please consider what would happen if other elements on the page changed height or width. My guess is that your negative margin depends way too much on other parts of the page in a way that is not necessary.

There are times when negative margins can add nice little accents for design such as a slightly offset image or icon. But, if you are using a negative margin as an integral part of your page layouts, you might want to try and rework the code.


 
 
 

 
Keep Your Negative-Margin Fingers Off My <BODY> And Out Of My Box Model  
 
 
 

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Mar 5, 2008 at 9:06 PM // reply »
38 Comments

Some good comments. The only time I've used negative margins are when I couldn't get one of the major browsers to behave the same way as the others. But I am very far from a CSS expert, so I'm sure there are better ways to solve the problem...


Mar 5, 2008 at 10:08 PM // reply »
2 Comments

There are plenty of situations where negative margins are appropriate. Why is a negative margin any worse than a negative value on a position, or text-indent, for example? Negative margins affect elements that occur after them in the document flow in a unique way that floats or absolute positioning can't match. Only use positive margins if you like, but you'll be limiting the tools at your disposal to create effective websites.


Mar 5, 2008 at 10:08 PM // reply »
2 Comments

There are plenty of situations where negative margins are appropriate. Why is a negative margin any worse than a negative value on a position, or text-indent, for example? Negative margins affect elements that occur after them in the document flow in a unique way that floats or absolute positioning can't match. Only use positive margins if you like, but you'll be limiting the tools at your disposal to create effective websites.


Mar 6, 2008 at 1:13 AM // reply »
153 Comments

Concrete example of a good use for a negative margin:

Take a blank piece of unlined paper. Skip down a few inches, then write on it -- a few lines, then a few paragraphs. Add a quick bulleted list. Draw a box that represents an image.

Now look at what you've done. Odds are, unless you've got some deep-seated psychological issues, you didn't start at the extreme left edge of the page, but indented a bit. Similarly, your writing probably doesn't hit the far right edge of the page, but again has some space. Let's call it 0.5 inch.

But is it margin or padding? It doesn't make sense to have the paragraphs and lists and images, and all of the other child elements you might have, worrying about adding in a 0.5 inch margin, so instead we just add the padding to the body:

body { padding: 2in 0.5in 0.5in 0.5in; }

Yes, you could also technically do it this way, but it's just silly:

body > * { margin-left: 0.5in; margin-right: 0.5in; }

Now go back and give the page a nice big title, such as "OMG Best Web Page EVAR". Beneath that title, draw a line. But here's the trick: draw the line from the extreme left edge of the page to the extreme right edge of the page. Take a crayon or highlighter and color in the background for the top part of your page that has the title.

How do we do that in CSS? The body already has padding, but we want the color to go to the edge of the page, not be some colored-in square with a half-inch of white all around it.

#title {
margin: -2in -0.5in 0.25in -0.5in;
padding: 0.25in;
border-bottom: thin solid maroon;
color: maroon;
font-size: 120%;
background-color: yellow;
font-weight: bold;
}

See?

The other advantage of doing it this way is that the box for the content has "sane" coordinates that start where the content starts, and not at the extreme left/right edges of the page. That is, if I want to indent something another 0.5in, I don't have to remember that I've already got 0.5in and so set my margin to 1.0in, and then work some magic to set nested elements back to 0.5in so that they aren't all at 1.0in.

Down that path lies madness.


Mar 6, 2008 at 8:09 AM // reply »
106 Comments

But then what if you add more elements to the page that you want to start from the left of the page and go all the way across? And what if you edit the body tag padding? You then have to go back in and manipulate the negative values to match the changes in the body tag.


Mar 6, 2008 at 9:16 AM // reply »
7,210 Comments

@Richard,

To me, negative margins are very different than a negative position. Position coordinates are just relative to a given 0,0 axis. Some of those coordinates are going to be negative. Negative values, in an of themselves are not bad. I just think with margins, they should be used with extreme caution.

@Rick,

I see what you are saying. I have never done that personally, but I see where it cold be useful. Let me ask you this, could the same thing be done with:

#title {
position: relative ;
left: -.5in ;
top: -2in ;
padding: .25in 1in .25in .25in ;
}

... the numbers might not add up exactly, but I think the same effect can be achieved via relative positioning. The problem is that to get the full width, you have to add padding (unless you know the width of the content area, then you can just set the explicit width).

I believe that a negative relative position will work the same way as a negative margin, but will make more sense from a box-model standpoint.


Mar 6, 2008 at 11:01 AM // reply »
153 Comments

Gareth- It has been my experience that the vast majority of the time any content I add to a page will be within the borders, and only a few rare exceptions will break out of their box into the margins. Thus, it's easier to not have to remember for most new content, than it is to have to remember every time I start using something new on my page.

And, yes, if I decide that I want a 0.75in margin around the page instead of a 0.5in margin, I do have to remember to change the elements that break through that margin. But again, the whole point here is that there are fewer cases where elements break through the margin than there are that do not. Thus, fewer places to change.

Ben- Relative positioning does, I agree, make more sense from a box model standpoint. However, in practice, I've found that it has been poorly implemented by browsers enough times as to make it almost useless. Give it another 2-5 years, and I'll start switching code over to your method.


Mar 6, 2008 at 11:16 AM // reply »
153 Comments

Ben -

Another point about your method -- it borks with the padding. If my title text wraps, then the padding on the left will not equal the padding on the right. This probably isn't a big deal for titles, as it won't be so obvious, but for paragraph content it could be a problem. I've used the same technique for callouts and blockquotes, like so:

http://rickosborne.org/school/cet4583/a1.html

That page was done for an assignment for my web development class for school, so ignore all the goofy JavaScript crap that was required for the assignments, but you can see the methodology I was talking about. The pullquote in purple uses negative margins to break out of the box. Your method would lead to strange padding.


Mar 6, 2008 at 11:20 AM // reply »
112 Comments

There are at least two really good use cases for negative margins:

* Centering an element - By setting an element with a "left: 50%" and a negative margin of half the elements width you can very easily center an element on the page. It's also a case where the negative margin makes sense.

* Columizing a list element - using a negative margin-top is one way to easily convert an ordered list into columns. It allows you to use compact semantic HTML, but still divide the list into columns.


Mar 6, 2008 at 11:22 AM // reply »
7,210 Comments

@Rick,

Yeah, I figured that would happen with the padding. That's why I was saying if you know the exact width, you can use explicit widths which will work nicely with the box model. However, when it comes to things like paragraphs and titles, I kind of feel that those shouldn't have explicit widths, but rather just fit with the parent.

I think your use of the negative margin is probably the *easiest* way to solve the problem without adding extra markup containers.

While I have not used your technique personally, I think it is ok. More than anything else, I want people to stop and really think about their negative margins. I am in the middle of re-coding a site right now that crazy negative margins all over the place because it was done to fix core problems with the CSS. Now, I have clean it all up :(

Carry on with your negative margin titles, blockquotes, and what have you.


Mar 6, 2008 at 11:24 AM // reply »
7,210 Comments

@Dan,

Yeah, that negative-left margin for the centering of things like light box is wicked cool. Again, one of the cases where negative margin does make life easier.

I am not sure I follow about the list customization.


Mar 6, 2008 at 12:19 PM // reply »
112 Comments

@Ben:

Here's a link that explains the negative margin-top trick to convert an HTML list into columns: http://www.communitymx.com/content/article.cfm?page=2&cid=27F87


Mar 6, 2008 at 12:50 PM // reply »
7,210 Comments

@Dan,

That's a pretty nifty trick.


Mar 9, 2008 at 3:53 PM // reply »
8 Comments

There's no reason to use negative margins for that columned list.
Relative positioning works perfectly well.


Mar 17, 2008 at 5:47 PM // reply »
112 Comments

@Robert:

While you can use can use a negative top to specify the position, using a negative marginTop is nice because you only have to apply the negative margin to the first element in the new column. If you use negative top margin, then you have to carry the negative value to each item in the second column.


Jun 6, 2009 at 1:13 PM // reply »
1 Comments

Do you know of a better way than described in this article I just found to have a semantic, validating, minimalistic xhtml and css without using negative margins?

http://www.mindfly.com/blog/post/2009/01/Get-Refreshed-Liquid-Layouts-With-Simpler-CSS-and-Without-A-Semantic-Mess.aspx

Floating by it's nature causes semantic nightmares yet the negative margin solution does bug me a little. However this is the ONLY layout that I have found that doesn't use floats and still manages to control the column lengths without pesky height issues and has no extra divs or spans.

I'd be interested in hearing your input and if you think it's worth it or not.


Aug 19, 2009 at 2:20 PM // reply »
1 Comments

negative margins are the devil.

abs positioning != margins in any way. negative positioning in 3d programming is totally kosher and expected. the perspective is only slightly different in page layout since the origin starts at the top left rather than center.

to me, using negative margins proves you haven't constructed your document correctly [or you're forced to work with some other guy's layout].

thanks for being strong man - fight the power!


Aug 19, 2009 at 3:14 PM // reply »
112 Comments

Since this topic got revived from the dead, it reminds me that I just read an article recently talking about negative margins are extremely valid CSS.

Here's the article--I found it very interesting:

http://www.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/


Aug 19, 2009 at 3:17 PM // reply »
7,210 Comments

@Dan,

I've had that Smashing mag article open in a tab for like two weeks! I haven't yet carved out time to read it, but I refuse to close it (cause I know I'll never get to it at that point).


Aug 25, 2009 at 2:35 AM // reply »
2 Comments

Negative CSS Margins Are Cool


Sep 6, 2009 at 1:12 PM // reply »
7,210 Comments

@Dan,

Even after reading that Negative Margins articles, I'm not fully convinced. To be honest, some of the explanations of behavior went a bit over my head. And, the fact that behavior is different for floats... I don't know.

The one thing that I have used it for is centering modal windows and that works quite nicely.


Oct 7, 2009 at 6:44 AM // reply »
1 Comments

Yes, I agree with you and I also found negative margin problem breaking layout in one of my project...thanks.


Post Comment  |  Ask Ben

Recent Blog Comments
Feb 9, 2010 at 7:57 AM
Ask Ben: Converting a Query to an Array
@Stju, Did you actually test this? I ask because there is a fatal flaw in it - you are using the same Row struct for every row. Since Structs are passed by reference, every subsequent update you ma ... read »
Feb 9, 2010 at 7:50 AM
Using jQuery's SlideUp() and SlideDown() Methods With Bottom-Positioned Elements
@Thomas, Not bad. I suppose you could do the same with Top as well as margin. ... read »
Feb 9, 2010 at 7:47 AM
Ask Ben: Creating A PDF And Attaching It To An Email Using ColdFusion
@Johan, I don't think I have one off hand. Basically, you'd just want to use the File attribute of CFDocument to save the PDF to disk. Then, you'd want to use the File attribute of CFMailParam to a ... read »
Feb 9, 2010 at 5:34 AM
Creating A "Remember Me" Login System In ColdFusion
Any change you could show how to take advantage how the J2ee session stuff in your code? http://kb2.adobe.com/cps/182/tn_18232.html ... read »
Feb 9, 2010 at 5:32 AM
Creating A "Remember Me" Login System In ColdFusion
This may help: http://bugs.farcrycms.org/browse/FC-79 Its the session variables' option being selected in the CF Admin ... read »
Feb 9, 2010 at 4:14 AM
Ask Ben: Converting a Query to an Array
Exellent script! [code removed] ... read »
Feb 9, 2010 at 3:16 AM
Using jQuery's SlideUp() and SlideDown() Methods With Bottom-Positioned Elements
Just a quick fix for the code example above: $('.panel').height() should instead be... $('.panel').outerHeight() ... read »
Feb 9, 2010 at 3:09 AM
Using jQuery's SlideUp() and SlideDown() Methods With Bottom-Positioned Elements
I came across this page because I was searching for a certain behavior. I didn't just want the element to slide up; I wanted it's contents to slide up with it. As if the contents were written on a p ... read »