<small> tag makes height of paragraph larger
Asked Answered
P

4

14

I have the following fiddle:

http://jsfiddle.net/tompazourek/sn5jp/

<p>some normal-sized text</p>

<p>some <small>small</small>-sized text</p>

p { line-height: 20px }

When I inspect the page in Chrome, I find out that the computed height of the first paragraph is 20px, but the computed height of the second paragraph is 21px.

Why is the <small> tag causing these problems? How can I fix this?

Every occurence of <small> in the paragraph text messes up my baseline grid.


EDIT: I later also found an interesting article relevant to this topic: Deep dive CSS: font metrics, line-height and vertical-align.

Pinhead answered 4/5, 2014 at 20:51 Comment(1)
This is really mysterious. If you replace the small element by a span element and test with different font sizes, you’ll notice that anything smaller (even by one pixel) than the parent element’s font size makes the parent element 21px tall, whereas a larger font size up to 19px does not do that (the height stays at 20px).Handle
B
14

Explanation:

There are a few things happening here.

In your example, the small element is an inline-level element, which means that its vertical alignment is determined by the vertical-align property.

The default vertical-align value is baseline, which means that the baseline of the small element will be aligned to the baseline of the parent box:

Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin edge with the parent's baseline.

Next, you need to consider the line-height property and how it is calculated. You also need to take leading and half-leading into account. In CSS, half-leading is determined by finding the difference between the element's line-height and font-size, dividing that in half, and then placing the calculated amount of space above and below the text.

For illustration, here is an example image demonstrating this (taken from W3.org):

enter image description here

Since the line-height is 20px, and the small element has a font-size of 13px, then we can determine that 3.5px of space is added above and below the small element's text:

(20px - 13px) / 2 =  3.5px

Likewise, if we calculate the half-leading of the surronding text nodes, which have a font-size of 16px, then we can determine that 2px of space is added above and below the surrounding text.

(20px - 16px) / 2 =  2px

Now if we relate these half-leading space calculations back to the vertical-align property, you will notice that more space is actually being added below the baseline of the small element. This explains why the computed height of the p element containing the small element was larger than the computed height of the other p element.

With that being said, you would expect the computed height of the p element to continue increasing as the font-size of the small element decreases. To further illustrate this point, you will notice that the computed height of the p element is 23px when the font-size of the small element is set to 6px.

p { line-height: 20px; }
small { font-size: 6px; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>

Potential Workarounds:

Since we know that the height difference results from the extra space that is added to the baseline, we could change the vertical-align value of the small element to top:

p { line-height: 20px; }
small { vertical-align: top; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>

Alternatively, you could give the small element a line-height of 17px, which would result in 2px of space being added above and below the element (which is the same amount of space that is added for the surrounding text like we calculated above).

// Surrounding text that is 16px:
(20px - 16px) / 2 =  2px

// Small element text that is 13px:
(17px - 13px) / 2 =  2px

p { line-height: 20px; }
small { line-height: 17px; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>

However, you really don't want to be calculating any of that and hardcoding it, which means that you should just use a relative line-height and omit the px units.

Since the the font-size is 16px and the desired line-height value is 20px, you would divide the line-height by the font-size and get 1.25:

p { line-height: 1.25; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>

If you don't want to use a relative line-height: 1.25, and you want to continue using line-height: 20px, then you could of course reset the small element's line-height value back to the initial value, which is normal.

p { line-height: 20px; }
small { line-height: normal; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>
Benjaminbenji answered 4/5, 2014 at 20:56 Comment(4)
Okay, you just found a way how to fix the problem. Kudos for that :). But still the <small> text aligned to the top looks weird. Also I still don't truly understand the reason and the mechanism of what is happening underneath.Hardly
Yes, I just noticed this issue again somewhere and thought it deserved a proper explanation. Thank you again for this elaborate answer :) it looks great. I'll keep the question open for some time, but it looks like you'll win the bounty. :)Hardly
Now this is a combination of good question & good answer I haven't seen in a long time. I have pondered this question for so long but couldn't explain it. Thanks both of you :)Festus
@JoshCrozier I read your answer again in detail today, and I still don't understand everything. I follow you until the vertical-align workaround, but then the last three line-height workarounds still involve something I don't quite get. I made another snippet where the text is wrapped onto two lines, and the second paragraph consists only of <small> text with line-height: 17px. What I don't get is why both paragraphs are still equal height of 40px. Somehow I'd assume that if the <small> sets line height to 17px, it will be only 34px high.Hardly
S
1

The alternative to the answers posted by Josh Crozier would be to reset small line-height alltogether:

p { line-height: 20px }
small {line-height: initial;}
<p>some normal-sized text</p>

<p>some <small>small</small>-sized text</p>
Shanklin answered 13/2, 2017 at 20:51 Comment(0)
I
0

You can use a relative value for line-height. In your case, the base font size is 16px, so a 20px line height in relative units would be 1.25

p { line-height: 1.25; }
<p>some normal-sized text</p>
<p>some <small>small</small>-sized text</p>
Interpellation answered 13/2, 2017 at 17:20 Comment(0)
S
0

This happen because of small tag has font-size:smaller and p tag has bigger size then small tag so this difference of small and p tag making this problem. When you are putting small tag into p tag then increase height because small tag taking small space then p tag.

Soving this problem you have to give line height to small tag 19px, like this:

p { line-height: 20px }
small{line-height: 19px}
<p>some normal-sized text</p>

<p>some <small>small</small>-sized text</p>
Suzetta answered 16/2, 2017 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.