Roger Lipscombe
Roger Lipscombe

Reputation: 91825

Can I make headings step down one size in CSS?

In CSS, can I make it so that, in a particular class of div, headings are each the next size down? Meaning that, h1 is h2-sized, h2 is h3-sized, and so on? But without actually specifying those sizes?

I'd like to be able to set h1, h2, h3, once, and then merely shift them all down one in a particular case.

Upvotes: 1

Views: 153

Answers (2)

Labu
Labu

Reputation: 2582

Jukka's answer is one way, but I would solve this another way that can be more robust if you're solving stuff responsively.

Here's an article on Smashing Magazine about building a proper baseline for copy that's a great read if you're building copy heavy interfaces.

So, you would start by setting up a proper baseline for the text, and then use percentages to scale your heading sizes based on the baseline.

Note: These are example values.. I haven't tested anything.

body { font-size: 1.2em } /* Baseline */

article { font-size: 80% } /* 0.8 of ^ Baseline */
aside { font-size: 60% } /* 0.6 of ^ Baseline */

/* x% of the parent font-size */
h1 { font-size:160% }
h2 { font-size:140% }
p{ font-size:100% }
etc...

This will affect all the copy in the body, article & aside, and the text size will scale relative to the baseline size.

Example:

<h1>Font size = 1.2em * 160% = 1.92em</h1>
<p>Font size = 1.2em * 100% = 1.2em</p>

<article>
    <h1>Font size = 1.2em * 80% * 160% = 1.536em</h1>
    <p>Font size = 1.2em * 80% * 100% = 0.96em</p>
</article>

<aside>
    <h1>Font size = 1.2em * 60% * 160% = 1.152em</h1>
    <p>Font size = 1.2em * 60% * 100% = 0.72em</p>
</aside>

This makes it easy to set a different baseline for different @media queries, and have all the text size properly.

Further example:

We change the baseline with a media query:

/* Small screen, so beef up the font size */
@media only screen and (max-width: 320px){
    body { font-size:1.4em }
}

This will affect all our previous styles as follows:

<h1>Font size = 1.4em * 160% = 2.24em</h1>
<p>Font size = 1.4em * 100% = 1.4em</p>

<article>
    <h1>Font size = 1.4em * 80% * 160% = 1.792em</h1>
    <p>Font size = 1.4em * 80% * 100% = 1.12em</p>
</article>

<aside>
    <h1>Font size = 1.4em * 60% * 160% = 1.344em</h1>
    <p>Font size = 1.4em * 60% * 100% = 0.84em</p>
</aside>

2c

Upvotes: 1

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201558

By the HTML5 CR (see 4.4.11 Headings and sections there), you can use the article or section element for the purpose, since they start new nesting levels so that e.g. an h1 inside them corresponds to h2 outside them. Newest versions of browsers generally implement this, as you can e.g. by viewing the following on them:

<!doctype html>
<title>Headings</title>
<h1>Heading</h1>
<h2>Heading</h2>
<article>
<h1>Heading</h1>
</article>
<section>
<h1>Heading</h1>
</section>

However, support is still limited and will be so for a long time. IE 8 (and older) will be us for years. And although there are polyfills to implement the new HTML5 elements on those browsers, e.g. the famous html5shiv.js does not handle the headings.

So the most robust approach is to set your font sizes explicitly. You can use contextual selectors, though, e.g.

<style>
h2, .article h1 { font-size: 130%; }
</style>
...
<div class=article>
<h1>...</h1>
...
</div>

(or maybe use article element with html5shiv).

Upvotes: 2

Related Questions