Even though ‘paragraph spacing’ (here referring to setting the space above and/or below a paragraph or other text element) is a simple enough concept in itself, when dealing with it in the context of web pages it can be worth reassessing our methodology. Are you using CSS as efficiently as you could be?
Print design and text frames
When thinking about ways to apply paragraph spacing to text in documents, I’m often reminded of my time working at a printer’s studio. When using QuarkXPress, and later InDesign, we could use ‘paragraph styles’ to assign spacing above or below text, and different people in the studio had their own ways of working things. If I remember correctly, I usually inserted space before my paragraphs, and my colleague who sat at the desk next to me inserted space after his paragraphs. It was interesting to discuss the pros and cons of each approach, and I enjoyed picking up tips which I could then use in future.

14pt 'space before' applied to a paragraph in InDesign
Now, when a heading or paragraph which is set to have space before it (e.g. 14pt) sits at the top of a text frame in a QuarkXPress or InDesign document (e.g. a non-breaking subheading that happens to start a new page), it does not have its before paragraph spacing applied, and continues to butt up against the top of its containing text frame.
In the context of print artwork, this approach by desktop publishing software works well and avoids many awkward situations. However, a web page requires more strict application of style rules. There is no such concept as a text frame in web pages – they are themselves textual documents.
The issue in web pages
For us web designers, a heading or paragraph keeps its top margin even if it is the first element in its parent element, which means we sometimes have to explicitly assign styling to get rid of unwanted margin-top values.
An old way
One suboptimal method was to assign a class to the first text element (in the example below, a heading) to which we wished to give a zero top margin.
<h1 class="first">Heading</h1>
<p>Lorem ipsum dolor sit amet...</p>
</div>
A disadvantage to this method is that we were introducing a presentational-only class, meaning it was inefficient and did not really align with the concept of keeping our markup structural. If a new element was inserted before the heading (e.g. an image), we would have had to manually remove the class from our paragraph and apply it to our new element instead.
A “new” way
My brother, Ian, came up with a far better way yesterday.
<h1>Heading</h1>
<p>Lorem ipsum dolor sit amet...</p>
</div>
The CSS rule applies our desired zero top margin to any element which is the first child of our article div. It avoids having to assign a class to our element, leaving it free of unsemantic fluff, and thus requires no manual class switching should our content change. We can now set top and bottom margins to elements as we wish, and leave it to our new CSS rule to ensure we don’t have an unsightly gap at the top of the relevant content area. It’s adaptable, elegant, and is a good example of how simple styling a document with CSS can, and should, be.
Of course, this isn’t really a new method, and has been available to us for a long time courtesy of CSS2. The reason it may not have been at the forefront of our minds and present in our work until now is its lack of support in Internet Explorer 6.
Pushing on despite IE6
The above scenario is just one example of where using current capabilities of CSS can save us work and make life as authors of web pages decidedly easier, so it could be well worth investing a little time to get Internet Explorer 6 and 7 (and 8 when wanting to use CSS3) to play along with the rest of the world. Here are some options.
ie7-js
ie7-js is “a JavaScript library to make MSIE behave like a standards-compliant browser”, and you can see the CSS support it adds at the projects test page, as well as the rendering bugs it fixes.
Within the “ie7-js” project there are two main JavaScript scripts: IE7.js and IE8.js. If you decide to use IE8.js, you don’t need IE7.js as all its functionality is included in IE8.js. If you’re new to ie7-js, all the instructions you need are on the main project page.
ie-css3.js
ie-css3.js “allows Internet Explorer to identify CSS3 pseudo selectors and render any style rules defined with them”.
While IE8.js provides support for Internet Explorer for some CSS3 pseudo selectors (the ones which Internet Explorer 8 itself has as I understand it), there are others that it does not handle and which ie-css3.js does: :nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type and :only-of-type.
eCSStender
There is some overlap between IE8.js and ie-css3.js (and feature gap if IE7.js and ie-css3.js are used), meaning there’s still work to do on creating the “complete” solution. eCSStender (pronounced “extender”) sounds very powerful, but I haven’t looked at it in detail yet – it seems to be more complicated to use than the two aforementioned projects. Hopefully I can work it out to see if it can provide the CSS emulation for Internet Explorer that I’m after.
No time like the present
I feel that now is a good time to finally start using more of the CSS2 and CSS3 goodness in my web page styling that Internet Explorer and its market share have hitherto skuppered, so I’ll be testing these projects further with a view to settling on a solution.
Have you had experience with using new types of CSS selectors, and emulating CSS2 and CSS3 capabilities in Internet Explorer? I’d be very interested to hear how you’ve got on.
Update: Chris Coyier has included the basics of this approach in a more concise form at CSS-Tricks – worth reading if the above isn’t clear to you.
9 Comments
I agree that this is a great use of more advanced CSS selectors, but I do have a question. At the beginning of the article you mentioned the pros and cons of putting spacing before or after paragraphs, but didn’t explain those pros or cons. What is the advantage of using margin-top for your paragraphs? I’ve always used margin-bottom, since it avoids having a big gap above the first paragraph, while simultaneously giving some extra spacing beneath the final paragraph of a set, which is generally what I’m after anyways.
Thanks for the article! I’m interested to use some of the IE scripts you listed here in my own work.
Hi Kevin! Thanks for reading and your comment.
I agree that using margin-bottom is usually easier for the reasons you mention. I think where this particular example could come into play even if you do use margin-bottom for paragraphs is when your headings (or whatever other element type that happens to be the first element in your containing element) have extra margin-top applied. Also, it might be useful to use both margin-top and margin-bottom on paragraphs, if its important that every paragraph has at least some margin either side throughout your document.
This kind of CSS rule could also be useful in taking away the margin-bottom of the last element in a particular containing element (perhaps if the containing element already has its own padding-bottom for whatever reason) – the pseudo selector :nth-last-child(N) would then be used instead.
Or you can just use the simpler :last-child.
Ha – of course. :) You can tell I haven’t been using these fancy new pseudo selectors much yet.
usually we use once in a body then no need to give css .class or advanced selector to give {margin-top:0}. we can directly to h1{ margin-top:0}
A benefit of using #article > :first-child/last-child is that you don’t have to know which element comes first within the #article. Applying style specifically to h1 doesn’t give that flexibility, which can be useful in larger, less predictable documents.
By applying margin-bottoms and line-heights to your elements (be they textual or otherwise) you can alleviate the majority of the problems you seem to be encountering as well as achieving a much nicer (and easier) vertical rhythm.
Applying margin-tops seems to be causing you unnecessary grief, for which a hacks (especially JS dependent ones) are not the best solution.
Thanks Harry. Think of the margin-top issue as more of an example of a particular situation that may sometimes come up – it’s not that I’m having problems. As mentioned in another comment, I usually use margin-bottom myself. I still believe it’s a potentially useful example, when applied to headings. Remember, it’s about maintaining flexibility – style and forget, as it were.
The aim of supporting Internet Explorer 6 (and 7 and 8) with CSS 2 and 3 selectors is more of a general thing – this is obviously more useful for other styling considerations than just paragraph/heading spacing.
Thanks, this is useful because I think that most headings tend to need both top and bottom margins/padding, regardless of whether the paragraphs have a bottom margin (ideally), or a top margin.
2 Trackbacks
[...] This post was mentioned on Twitter by bkmacdaddy designs, Nicholas Patten, WPstudios, Pinceladas da Web, Richard Laksana and others. Richard Laksana said: Hacking ‘Paragraph Spacing’ with CSS – http://su.pr/1AGbOI [...]
[...] 本文译自:Hacking ‘paragraph spacing’ with CSS (despite IE)。内容有删改。 Categories: Develop Tags: CSS, JavaScript [...]