views:

3442

answers:

4

How should CSS 'margin' and 'padding' be used for vertical inter-paragraph spacing:

  • Can the vertical space between paragraphs be defined using padding and/or using margins?
  • If it can be done with either, then which is the better or more normal one to use?
  • Do you tend to define non-zero padding and non-zero margins, and if so then how much of each?

The Example of margins, padding, and borders explains in theory what the difference is between margin and padding: I'm questioning how much of each to use in practice, to render a normal, good-looking page.


Secondly, given markup like the following ...

<p>Paragraph.</p>
<ul>
<li>List item.</li>
<li>Another list item.
<p>List paragraph.</p>
</li>
</ul>

If you want equal vertical space between each paragraph and/or list item, then:

  • Would you tend to define the <ul> as having zero margin+padding of its own?
  • Or would the <ul> normally have non-zero margin, which would then have no effect because this margin will be collapsed with the margin of the <li> within it and of the <p> which precedes it?


Thirdly (and I'm not sure whether I ought to ask this third question), the specification for collapsing margins says, "If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it." If I have an empty paragraph like the following one in the middle ...

<p>Hello</p>
<p></p>
<p>World</p>

... then I'd expect to see this as an empty paragraph, i.e. with an extra amount of vertical space between the Hello and the World:

  • What would prevent this empty paragraph's margins from collapsing, and the empty paragraph therefore being invisible: is it non-zero padding which does this?
  • In what scenario is it useful for a box to have adjoining top and bottom margins which collapse?


Answers to any or all of these three questions would be welcome.

I'm not especially interested in IE-specific box model problems at the moment: instead I want to know about how to use the standard.

A: 

Hehe, well... web browsers are different, I'd say that what goes well with Firefox usually goes well with the standard but that's not entirely true either.

According to the xhtml1-strict.dtd only <li/> can be child of <ul/>. I suggest you get yourself an designer which knows about the standards. These are formal specifications that you can verify your HTML with.

<p>Paragraph.</p>
<ul>
    <li>List item.</li>
    <li>Another list item.
    <p>List paragraph.</p> <!--illegal here-->
    </li>
</ul>

But back to your question (which by the way is a pain to answer). There are many cases where you would define non-zero margin and padding. I tend to prefer additional margin when padding isn't needed, and then pad when margin doesn't work. Every situation is different and you'll need to know when one is preferred.

I won't go into details, because I think you're on the right track here. Keep experimenting and I know you'll get it. But do keep in mind that web browsers do things differently.

I'm not sure about that collapsing margin thing, but white-space sometimes counts as margin. If a bunch of elements occur without white-space in between them that's sometimes different than if there where no white-space.

Again, it's a lot to take in so I won't go into the specifics, but you'll need know about these things and you'll get this knowledge by practicing.

The paragraph and list margins by default are not the same cross browsers, when you start doing all that layout you'll want to define a set of base CSS rules for your page. And if you want help on what margins to set I suggest you take a look at the canons of page construction.

p { margin: 1em 0; }
ul { margin: 1em 0; }
ul > li { margin: 1em 0; }

The above rules are just an example but what they do is that they ensure that the top and bottom margins for paragraphs and list items are the same despite browser. Things like this is what makes your page look the same cross browsers.

Keep testing out things and read the excellent CSS blogs out there. Ask for help when you run into the really obscure edge cases. These people have spent a great deal of time trying to solve and your time is better spent learning how they did it than reinventing the wheel.

John Leidegren
I think that my xhtml fragment validates: I nested the <p> inside an <li>, and not directly in the <ul>.
ChrisW
In summary, you prefer to use margins and not padding.
ChrisW
@ChrisW - No, I'm saying that sometimes you have to use padding, but if you don't need to use padding use margin.
John Leidegren
A: 

The main thing you need to know is that adjacent (vertical) margins mere so if you have:

p { margin: 1em 0; }
...
<p>Paragraph one</p>
<p>Paragraph two</p>

The space between them will be 1em not 2em.

Padding is separate. If the paragraphs had padding it would be inside their boxes. The source of truth for all these things is the W3C CSS standard. For example, collapsing margins:

In this specification, the expression collapsing margins means that adjoining margins (no padding or border areas separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.

In CSS2, horizontal margins never collapse.

Vertical margins may collapse between certain boxes:

  • Two or more adjoining vertical margins of block boxes in the normal flow collapse. The resulting margin width is the maximum of the adjoining margin widths. In the case of negative margins, the absolute maximum of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the absolute maximum of the negative adjoining margins is deducted from zero.
  • Vertical margins between a floated box and any other box do not collapse.
  • Margins of absolutely and relatively positioned boxes do not collapse.

Please consult the examples of margin, padding, and borders for an illustration of collapsed margins.

Borders are a little different, particularly in tables where they can collapse into each other or not depending on CSS.

Now the story doesn't end there of course. Browsers can vary on how they calculate combinations of width, margins, borders and padding but that's largely diminished by forcing browsers into standards mode (with a DOCTYPE) and a large topic in and of itself (as is what you do to minimize these sorts of problems).

cletus
The fact that margins merge and padding doesn't should tell me something about what they're useful for, but I don't know what. Is it possible (wild guess on my part) that the norm if there is one is to have tiny but non-zero (i.e. one-pixel) padding, and effective (e.g. 6-point or 12-point) margins?
ChrisW
I had already quoted the standard, so I kind of know the effect of padding and of margin. Some effects (e.g. non-zero spacing between paragraphs) can be done with either, and I wondered which (padding or margin) *should* be used for inter-paragraph spacing, with an ideal standards-compliant browser.
ChrisW
+1  A: 

To answer your 3rd question;

The second < P > as an empty block level element simply wont be rendered.

You can force the element to be rendered while empty by giving it a height or padding, or including a non breaking space &nbsp; inside the para. (there are probably more ways to do this).
Normal whitespace (eg newlines, tabs or spaces) don't seem to work in this regard.

Edit #2 :: To properly illustrate how this all works, save this locally and see what renders.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html>
    <head>
     <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
     <title>Page Title</title>
     <style type="text/css" media="screen">
      p { margin:10px; background-color:#ccc;}
      p.padding { padding:5px; background-color:#eec; }
      p.height { height:30px; background-color:#cee; }

     </style>
    </head>
    <body>

     <p>text</p>
     <p class="padding">i have padding</p>
     <p class="padding"></p>
     <p></p>
     <p></p>
     <p></p>
     <p></p>
     <p>5 empty paragraphs before this, only one will render. (it has padding)</p>
     <p>& nbsp;</p>
     <p>  </p>
     <p>     </p>
     <p>





     </p>
     <p>3 whitespace before me, one will render, it has &amp;nbsp;</p>
     <p class="height">im 30 px high</p>
     <p class="height"></p>
     <p></p>
     <p></p>
     <p>3 empty before me, 1 will show (it has height)</p>
     <p>text</p>
     <p>text</p>

    </body>
</html>
garrow
Is it true that it wouldn't be rendered if it had only margins, because margins collapse, but *would* be rendered if it had any padding? Does vertical padding (if defined) still exist even when the content is empty? Because if there is padding I'd guess that would prevent the margins being adjacent.
ChrisW
Normal whitespace isn't signfificant, e.g. http://www.w3.org/TR/2000/WD-xhtml-modularization-20000105/conformance.html#s_conform_user_agent says "Leading and trailing whitespace inside a block element must be removed".
ChrisW
Padding **does** give the element layout.
garrow
Thanks for confirming that. Do you happen to know whether a block would have padding, if its style has padding defined but if it had no/empty content? Or does all padding disappear when there's no content?
ChrisW
Padding or height make the element render, even if empty, see the empty p.padding in the example.
garrow
+2  A: 

To answer your first question, it generally does not matter if you use margin or padding to add spacing between elements, however if you apply a border to an element and use padding to make a space it will push out the border that far.

To answer you second issue just take a look at this code and maybe play around with it:

<html>
<head>
<title>Box Model Tests</title>
<style type="text/css">
/* Just to get rid of the annoying padding/margin setting that is default
 in most browsers on the body tag from messing up our experiments */
body{
margin: 0px;
padding: 0px;
}
p{
margin: 0px;
padding: 0px;
}
/* It appears that if you modify the ul padding it tends
 to remove the bullet points, that is if you set the paddign to zero */
ul{
margin: 0px;
}
</style>
</head>
<body>
<p>Paragraph.</p>
<ul>
<li>List item.</li>
<li>Another list item.
<p>List paragraph.</p>
</li>
</ul>
</body>
</html>

Keep in mind that in the example above all the remaining space has to do with properties of the font, which can be changed using the same methods as any other element.

And to the third:

I think 'garrow' is right about the empty <p> I don't run into this issue that often as I use <p> less and less in my layouts however this article looked very interesting, and I think offers a better explanation than W3C did.

teh_noob
Ah! There's a clue, in your first sentence: might it be normal to specify margins (because they collapse nicely) instead of specifying padding (i.e. specify zero padding)? Except that you specify a padding when you also specify a border, because in that case you want some padding inside the border?
ChrisW
Well you don't necessarily have to specify zero padding, in some cases you want padding to make the document look nice. And yes this is especially true when you add a border, its always nice to have padding to make sure the border is not right next to the text.
teh_noob
If you have a border, then I see why padding is necessary. Do you know any example of when you haven't specified a border, but you would still prefer to use padding instead of using a margin?
ChrisW
I can't think of any specific instance when I have done this, but when I make a layout with divs I from time to time have to use padding for spacing, but not that often. I like to let the elements inside each div to use its own margin/padding to create a space. I try to keep things logical.
teh_noob