May 18th, 2009

Fine tuning typography – styling grouped headers with CSS

Recently I have been working with my colleague Ben on a potential  new typography design for a website.  We came across issues in how to style headers and groups of headers differently using CSS and HTML,  This is our solution to these issues.

The typography is part of a wider site redesign we are working on and which I will write about later.  For this redesign we have heavily involved the editors in the design and development process to make sure we address the concerns they have with the current design including:

  • Spaces around headers
  • Spacing around groups of headers
  • Different content requiring different typography

In this article I will address what we have done with the first two points.

What we need to do

Rather than a final signed off typographical design we received a design where there were lots of questions about what was possible to do in HTML. Ben and I then had to come up with solutions to:

  • Keeping to a 16px vertical grid
  • Styling individual headers
  • Styling headers as groups differently, i.e. H2 followed by H3.
  • Keep this as easy as possible for the editors and other users writing content

Keeping to a 16px typographical vertical grid

A vertical grid is when you setup all the leading and spacing to a particular number or a multiple of that number.  For example, if you choose a 16px line height then all height and spacing should be 16px or a multiple thereof. This leads to a vertical rhythm which looks good and is easy to read.   The design delivered to us  specified a 16px vertical grid so everything we did should stick to this grid.

There is a very good article on A List Apart on typographical vertical grids if you would like to know more.  If you would like me to write more on typographic grids then let me know.

Example of HTML following a vertical grid

Example of HTML following a vertical grid

Styling individual headers

When we saw the design we noticed that the headings were not set to the vertical grid. The reason for this was that editors were very concerned about spacing around the headers and this had been reduced at a cost of breaking the grid.  We therefore set ourselves the challenge of tweaking the spacing so it would obey the vertical grid while obeying the spirit of the original design, especially to reduce the spacing around the headers.

When styling headers on a vertical grid I find it useful to think about a piece of string which is of a set length.  For example a heading could have 16px leading plus 16px bottom spacing.  This would be a piece of string 32px long. What would happen if you want to reduce the bottom spacing?  If you cut the string and halve the bottom spacing all the writing following the header would not follow the vertical grid.  The reason is that the header now only takes up 24px of space, this is not divisible by 16 throwing the text after it off the grid.

Therefore to make sure the vertical grid is followed throughout the text, the spacing you take off the bottom of the header should be added as top spacing.  The text that comes after will then follow the grid.  Going back to my string analogy, you can place the header anywhere on the string with more space before or after but you cannot cut any part of the string off.

For our grid we set the following:

  • H1: 24px font size, 32px leading, bottom spacing of 16px
  • H2: 14px font size, 16px leading, 24px top margin, 8px bottom margin
  • H3: 12px font size bold, 16px leading, 16px top margin, 0px bottom margin
  • Paragraph text: 12px font size, 16px leading, 16px bottom margin.
h1 {
    font-size: 24px;
    line-height: 32px;
    margin: 0 0 16px;

h2 {
    font-size: 14px;
    line-height: 16px;
    margin: 24px 0 8px 0;

h3 {
    font-size: 12px;
    line-height: 16px;
    margin: 16px 0 0 0;

The styled headers with and without grid

Please note that for this article I will give all sizes in pixels, although for the final code these should be converted to ems so the text can be re-sized by the user.

Notice that on the H3 we set a 16px top margin, if this appears below a paragraph or other element that has a 16px bottom margin, the margins will collapse resulting in only 16px of space between them rather than 32px.  By adding the 16px top margin to the header your are defensively coding to ensure there is enough space if a header is ever added below an element that has no bottom spacing.

Margin collapsing

Before I go any further I need to quickly explain margin collapsing.  If you put two elements above each other and the top element has a bottom margin and the bottom element has a top margin you will find that the two margins collapse with only the largest margin between them.  This also occurs if you have an element inside another.  If they both have spacing above or both have spacing below, the two margins will collapse.  We will have to deal with margin collapsing in the next section.

Styling groups of headers differently

The editors wanted groups of headers styled differently to reduce the space around them as this is a common problem with our current design.  Therefore we needed to style groups of headers such as H2 followed by H3 differently.

Now lets add more text with an H2 followed by an H3 and a paragraph. Taking margin collapsing into account, this ends up with the following:

  • Above H2: 24px
  • Between H2 and H3: 16px
  • After H3: 0px;

The H3 top margin of 16px is larger than the 8px of H2 bottom margin, so the margins collapse to 16px of space between the H2 and H3.  Add this to the 24px above H2 and you get a total of 40px.  This is not divisible by 16 and as you can see in the image below the text beneath the headers is not aligning to the vertical grid.

Text is no longer aligning on the grid

Now we want to reduce the spacing between H2 and H3 to 4px.  To do this, Ben came up with the very good idea of using adjacent selectors.  An example of an adjacent selector is:

h2+h3 { color:red; }
How an adjacent selector is styling an H3 followed by an H2 red

How an adjacent selector is styling an H3 followed by an H2 red

This would style any H3 which is immediately after an H2 with a font colour of red.  This works in all modern browsers apart from (the less modern) IE6.   For IE6 users the design and vertical grid will break and will have more gaps compared to users viewing the website in other browsers.  As this is not harming the user experience we felt we felt this was an acceptable graceful degradation for people using an old browser such as IE6.

Therefore we can change the space in between the H2 and H3 with:

h2+h3 { margin: 4px 0 0 0;}

Now due to margin collapsing, the space between h2 and h3 is now 8px.  We have set top margin of H3 to 4px but H2 has a bottom margin of 8px.  The margin bottom of H2 is now taking priority as it is the largest margin.

Margin collapsing is creating two much space

The problem

We need to override the H2 but only if there is an H3 immediately after it.  Unfortunately after researching there is no way we can do this with a CSS selector and apply to H2s that only come immediately before an H3.

A solution would be to add a class to H2s that come before an H3, unfortunately this would require editors to edit the source code as our CMS only allows for one sort of header to be applied.  We felt a javascript solution which would dynamically add a class to H2s would not be appropriate as applying classes after the DOM has loaded could cause the content to shift about.  This we felt could be annoying to users .

The solution

The solution was to change the markup through the using our CMS editor.

After looking at the CMS, I realised that you can apply bold styling and then H2 to a piece of text, and the CMS would produce the following HTML markup:

<h2><strong>my header</strong></h2>

By setting the following CSS we can change strong from an inline-element to a block element allowing us to changing the spacing around the H2:

h2 strong { display: block; }

We now need to reduce the space between H2 and H3, this is done by adding a negative bottom margin to the strong tag:

h2 strong {
    display: block;
    margin-bottom: -4px;

This has now reduced the space between H2 and H3 to the correct 4px.  However, the text following H3 is now outside the grid.

Spacing between H2 and H3 is correct but text following H3 is now outside the grid

We now need to add more space above the H2 to bring everything back onto the grid.  The margin-top of H2 and the strong tag will collapse to whatever the highest margin value is.  If we set a top margin for H2 strong to be the additional space we want, the margin would collapse and our extra spacing will not be counted.  Therefore, we will add padding instead.  There is already 24px space above the H2 and we have 4px between H2 an H3 which makes a total of 28px.  Consequently, we need to add 4px padding to add everything up to 32px which is divisible by 16.

h2 strong {
    display: block,
    margin-bottom: -4px
    padding-top: 4px;

The text after H3 now aligns to grid

Alternatively, we could have added a margin-top of 28px to the strong tag and as this is the largest number the top margin would collapse to 28px.  I find that adding the padding makes more sense to me in the way I think but you may prefer adding the larger margin instead.


We have now created typography that styles headers and groups of headers differently.  This is almost all done using CSS with the exception that an editor will have to bold H2s in the CMS if an H3 is to come afterwards.

Therefore the editors can now style a group of headers differently purely through using the CMS editor and with no editing of the source code.  This will produce the following look.

Final typography

Going forward

Our solution was based on our CMS and yours may be different, for instance you may have to use something other than the <strong> tag.  If you cannot do this you may want to adopt a javascript solution where you parse through the DOM and apply a class to any H2 before an H3.

For the sake of this example I have kept to H2 and H3, but you will also need to deal with H3 and H4 and other permutations depending on your designs.

I hope you find this useful and please leave a comment if you want any more information.

You should follow me on twitter here

Share the love


Feel free to join the discussion, or trackback.

todd hodes says:

this article makes me realize why a decades-old out-of-the-box FrameMaker, or well-written LaTeX of any era, still looks so much better than MS Word all these years.

Seems that as soon as you vary font sizes, eg for the obvious case of headings/subheadings/legends, you lose your vertical spacing grid, and it just … looks wrong. (in addition, varying individual fonts breaks inter- text class proportions, and paddings, both another matter.)

refreshing insight! something i could never quite put my finger on until now.

Phil says:

Hi Todd, I am glad you like the article, hopefully work like this will mean people can start experimenting more. Your point about MS Word is very good, I have created a very good Word document with the idea of a grid but have never got it completely obeying a vertical grid.

Under says:

You can affect CSS in the order displayed. Want to only affect an H3 as is appears after an H2?

h2.h3 {margin-bottom: -8px;}

Only the first instance?

h2.h3:first-child {color: blue;}

Good article about the vertical grid, though!

Phil says:

Hi Under, I am not sure what you mean with h2.h3 { style here } could you give some more information.

Ben Haldenby says:

Hi Under, I think you may be referring to adjacent sibling selectors. You’d use an addition symbol not a period. So, to style an H3 that follows an H2: h2+h3 { } or only the first instance: h2+h3:first-child {}. Hopethat helps.

AndrewBoldman says:

da best. Keep it going! Thank you

Rich McPharlin says:

Fine tuning typography - styling grouped headers with CSS , great article, really well though out and very much enjoyed.


Schedule says:

Maybe you should make changes to the blog subject Fine tuning typography – styling grouped headers with CSS | We love nice things to something more better for your blog post you write. I liked the blog post still.

Phil says:

Hi Schedule thanks for your comment

manny pacquiao shane mosley says:

Fine tuning typography – styling grouped headers with CSS | We love nice things mosley pacquiao updates jqtupbahlwyozm, mosley pacquiao odds, bahlqyjetixopc.

ramadan 2013 prayer times says:

We are a group of volunteers and starting a new scheme in our community.
Your website offered us with valuable info to work on.
You have done an impressive job and our entire community will be grateful to you. says:

s better to use whole foods made from scratch for good health.
In fact, I always suggest to those overweight vegetarians to keep to a max of 4 pounds a week so you won’t suffer loose skin post weight loss. When you’re about to start on your weight loss plan,
it’s a good idea to think about your end goal and chunk it down into smaller goals.

Joesph says:

With applications like Viigo and Pocket Express, you can keep up to
date on entertainment, sports, financial, political, U.
Aside from making you happy, you are also made strong to face life’s challenges.
How about getting some friends together and setting up some walking time.

parencontres says:

Hey! I’m at work browsing your blog from my new
apple iphone! Just wanted to say I love reading through your blog and
look forward to all your posts! Carry on the fantastic work!

sell structured settlement payments says:

Periodic payments can be distributed either monthly, bi-monthly, or with any other desired payment schedule.This iis where the inflation that was factored in must
be disccounted to present-day value, based on the amount of future settlement pawyments you’re selling.
The mentioned aggravating factors are the reason why animal bite victims have the right to assert for compensation claim or

business stationery says:

business stationery…

Fine tuning typography - styling grouped headers with CSS | We love nice things…

flooring system says:

When some one searches for his essential thing, thus he/she desires to be aavailable that in detail, thus
that thing is maintaied over here.

my weeb site flooring system

Johnk912 says:

I’m pleased that I seen this website, precisely the proper information that I was trying to find! beeeaegeadcd

decorative concrete ma says:

It’s not my first time to go to see this site, i am browsing this website dailly and get nice
facts from here every day.

Join the conversation

Head of teddy bear appearing over the footer