Line-Height as a Percentage Not Working

line-height as a percentage not working

line-height: 100% means 100% of the font size for that element, not 100% of its height. In fact, the line height is always relative to the font size, not the height, unless its value uses a unit of absolute length (px, pt, etc).

Why does unitless line-height behave differently from percentage or em in this example?

Based on clues in the proposed answers, I think the rendering behavior seen in these examples is counterintuitive, but correct, and mandated by the interaction of several rules in the spec, and the overall CSS box model.

  1. CSS calculates the leading L needed for a box by the formula
    line-height = L + AD, where AD is "the distance from the top to
    the
    bottom"
    of the font. Then "half the leading is added above A and the other
    half below D." So text that has font-size:16px and
    line-height:24px will have 4px of leading above and below. Text
    that font-size:8px and line-height:24px will have 8px of leading
    above and below.

  2. By default, however, "user agent must align the glyphs ... by their
    relevant
    baselines.".
    This starts to explain what's happening here. When line-height is
    specified by percentage or em, a computed value is inherited by the
    child (here, the smaller span). Meaning, the smaller span gets
    the same line-height as the parent block. But because of the L +
    AD formula, the text of that span has more leading on the top and
    bottom, and thus the baseline sits higher in its box. The browser
    pushes down the smaller span vertically to match the baselines.

  3. But then the browser has a new problem — how to deal with the line
    spacing in the enclosing block, which has been disrupted by this
    baseline-adjusting process. The spec resolves this too: the
    line-height of a block-level element "specifies the minimal
    height of line boxes within the
    element".
    Meaning, CSS makes no promise that you'll get your exact
    line-height, just that you'll get at least that amount. So the
    browser pushes the lines apart in the enclosing block so that the
    realigned child box will fit.

The reason this is counterinitutive is that it's the opposite of how most word processors and page-layout programs work. In these programs, a smaller stretch of text within a paragraph is aligned by its baseline (like CSS) but line height is enforced as a distance between baselines, not as a box surrounding the smaller text. But that's not a bug — CSS is designed around a box model. So in the end, we could say that this spacing behavior is a consequence of that model.

That still leaves us to explain the behavior in the example with the unitless line-height:

  1. First, note that when no line-height is specified, the browser
    will apply a unitless line-height by default. This is required by
    the
    spec:
    the initial value of line-height is normal, which is defined to
    have "the same meaning as <number>", and the spec recommends a
    value "between 1.0 and 1.2". And that's consistent with what we see
    in the examples above, where the paragraphs with line-height: 1.5
    have the same behavior as the paragraphs with no line-height setting
    (i.e., they are impliedly getting line-height: normal)

  2. As others have pointed out, when the paragraph has
    line-height: 1.5, the calculated line-height of the paragraph is
    not inherited by the smaller span. Rather, the smaller span
    calculates its own line height based on its own font size. When the
    paragraph has line-height: 1.5; font-size: 14px, then its
    calculated line height is 14px * 1.5 = 21px. And if the smaller
    span only has the property font-size: 50%, then its font size is
    14px * 50% = 7px, and its line height is 7px * 1.5 = 10.5px (which
    will generally be rounded to a whole pixel). But overall, the
    smaller box is half the size of the surrounding text.

  3. As before, the browser will vertically align the smaller span to
    the adjacent baseline. But this time, because the box around
    smaller is shorter than the surrounding text, this realignment
    doesn't have any side effects in the enclosing block. It already
    fits, so there's no need to spread the lines of the parent paragraph, as
    there was before.

Both cases represent a consistent implementation of the spec. That's good news, because it means we can predict the line-spacing behavior.

That brings us back to the original reason for this question. While I now understand that the CSS box model requires this behavior, as a practicing typographer, this is rarely the behavior I want. What I want is for the lines within a paragraph to have consistent & exact line spacing, even if some spans of text within that paragraph are smaller.

Unfortunately, it seems there's no way to directly enforce exact line spacing in CSS as one can in a word processor or page-layout program. Again, this is because of the CSS box model: it doesn't use a baseline-to-baseline line-spacing model, and line-height is specified to be a minimum measurement, not maximum.

But we can at least say that unitless line-height values produce the best approximation of exact line spacing in CSS. Fussy typographers like myself should feel comfortable using them, because unitless values are endorsed by the spec, and they produce consistent results across browsers. They are not a hack, nor are they deprecated.

The caveat is that they're still only an approximation. Unitless line-height values don't change the underlying CSS box model, nor the CSS box-positioning rules. So it's possible that in some edge cases, they won't have the intended result. But eternal vigilance is the price of good typography. Be careful out there.

is line-height:1 equivalent to 100%?

The real reason is that the way they work is different and it can be understood by having a look at the W3C Specs for line-height and inheritance. The below is what the spec for line-height says about the unitless value (<number>) and the percentage value.

<number> - The used value of the property is this number multiplied by the element's font size. Negative values are illegal. The computed value is the same as the specified value.

<percentage> - The computed value of the property is this percentage multiplied by the element's computed font size. Negative values are illegal

As BoltClock points out in his comment (correctly, as usual), inheritance always works the same way and it is always the computed value that gets inherited. The confusion with wordings was because I was referring to an older version of the spec whereas the new one is very clear and is using the right words.

When unitless value (number) is specified, the specified value for line-height is the number which is also the computed value. So, h1 (child) inherits the number which is 1 but it still needs to resolve this number into an actual line-height that can be used. So, the used value is calculated based on specs by multiplying the inherited factor with the h1 element's font-size (which is 2em = 32px) and sets line-height as 32px.

For the percentage, the computed value for line-height at body is 100% of body's font-size (which is 16px) and so is equal to 16px. Now since this 16px is the computed value, the h1 child inherits this value and uses it as-is because there is no need for further resolutions.

This is the reason why there is a difference between the two snippets as in one the line height for the h1 is 16px and in another it is 32px.


If we set the line-height: 100% directly at h1 then we can see that the outputs match because now the h1 calculates its own line-height as 100% of 2em (or 32px) which is same as 1 * its font-size.

h1 {
line-height: 100%;
}
<h1>
Hello <br> world
</h1>

About the basis for calculation of line height property using percentages inside of a fixed height

line-height as a percentage (e.g., 700%) or a constant (e.g., 7) is calculated on the basis of the font-size. Thus, the following declaration font: 12px/2 Sans-Serif will make text size 12 pixels in a line that is 24 pixels (2 * 12).

For your example, to place the text at the bottom of the container, using line-height property, you can do the following: http://jsfiddle.net/07r139tz/.

HTML:

<div class="container">
<h1 class="enormous">VOCÊ APRENDE</h1>
</div>

CSS:

* {
margin: 0;
padding: 0;
border: 0;
}

body {
padding: 10px;
}

h1.enormous {
font: 2em/1 Sans-Serif;
display: inline-block;
vertical-align: bottom;
}
.container {
background-color:red;
width: 300px;
height: 125px;
line-height: 125px;
}

Set line-height as a percentage relative to the parent element

Here's another way to center an element vertically. I came across this technique some time ago. Basically it uses a pseudo element and vertical-align: middle.

.block::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}

/* The element to be centered, can
also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}

Line-height doesn't change relatively (based on the size of its parent div)

Unitless values: use this number multiplied
by the element's font size

line-height: 1.5;

so it will be 150% of your elements font-size and will increase if you increase the font-size but while using px the line height will stay 30px even if you increase the font size of your element.

Jquery .css line-height not working

Try this

jQuery.each(jQuery('[id^=drop_]'), function(index, value) {

alert(jQuery(this).css("line-height"));

jQuery(this).css("line-height", "35px");

alert(jQuery(this).css("line-height"));

});
p { line-hieght: 10px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id="drop_first">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>

<p id="drop_second">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>

<p id="drop_third">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>

<p id="drop_fourth">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>

<p id="drop_fifth">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>


Related Topics



Leave a reply



Submit