line-height
and vertical-align
are simple CSS properties. So simple that most of us are sure that they understand how they work and how to use them. Unfortunately, this is not true - in fact, they are probably the most complex properties, since they play an important role in creating a little-known CSS feature called the inline formatting context.line-height
can be specified as a length or a dimensionless value, but its default value is normal
(standard). Good, but what does “standard” mean? Often they write that it is (usually) 1, or maybe 1.2. Even in the CSS specification there is no clear answer to this question .font-size
value, but the problem is that the font-size: 100px
looks different for different typefaces. In this regard, the question arises: will the line-height
always be the same or may it differ? Is this value between 1 and 1.2? How does vertical-align
affect line-height
?p
tag containing three span
elements, each with its own font-family
: <p> <span class="a">Ba</span> <span class="b">Ba</span> <span class="c">Ba</span> </p>
p { font-size: 100px } .a { font-family: Helvetica } .b { font-family: Gruppo } .c { font-family: Catamaran }
font-size
in different headsets, the height is different:font-size: 100px
create font-size: 100px
elements? I measured these values: Helvetica - 115px, Gruppo - 97px and Catamaran - 164px.font-size
.background
property applies.font-size
, not on the calculated height).p
element when displayed on the screen may consist of several lines with the appropriate width. Each line consists of one or several line elements (inline elements) (HTML tags or anonymous line elements for text content) and is called a line box (box-box). The height of the row container depends on the heights of its children . That is, the browser calculates the height of each line item, and according to it the height of the container row (from the topmost to the lowest point of its children). As a result, the height of the container line is always enough to hold all its children (by default).Each HTML element is actually a stack of string containers. If you know the height of all containers in a row, then the height of the element is also known.
<p> Good design will be better. <span class="a">Ba</span> <span class="b">Ba</span> <span class="c">Ba</span> We get to make a consequence. </p>
span
elements.::first-line
does not help display the height of the first line container.line-height
is the line-height
, and this is the height that is used to calculate the height of the line container.line-height
is the distance between baselines. In CSS, this is not the case.line-height
(virtual area) may be equal to, greater than or less than the content area. If the virtual area is smaller, then the leading value is negative and the row container is visually smaller than its children in height.img
, input
, svg
, etc.);inline-block
and all inline-*
elements;height
, margin
and border
properties. If auto
specified for height
, line-height
is applied, and the height of the content area is equal to line-height
.line-height
? The answer to this question, as in the case of calculating the content area, must be searched among the font metrics. So back to FontForge. The size of the em square for Catamaran is 1000, but we see a lot of values for the upper and lower offset elements:line-height: normal
, this value is added to the Ascent / Descent metrics (table "hhea").line-height: normal
will be equal to the content area, which is 1640 units or 1.64.font-size: 100px
the content area is 112px (1117 units), and line-height: norma
l - 115px (1150 units or 1.15). All these metrics are individual for each font and are set by the font designer.line-height: 1
ineffective. Let me remind you that dimensionless values depend on the font-size
, not on the content area, but the fact that the size of the content area exceeds the size of the virtual area is the cause of many of our problems.line-height: 1
. If it comes to that, out of 1117 fonts installed on my computer (yes, I installed all the fonts from Google Web Fonts), 1059 fonts, that is, 95%, calculated line-height
more than 1. In general, their calculated figure line-height
ranges from 0.618 to 3.378. (It did not seem to you - 3,378!)line-box
:margin-top
and margin-bottom
.inline-block
elements and blockified string elements - padding
, margin
and border
increase the height
and, therefore, the height of the content area and the row container.vertical-align
can play a leading role in the string formatting context.baseline
. Remember these font metrics, such as the height of the upper and lower detail elements (ascender / descender)? These values determine where the baseline is and, therefore, the ratio between the upper and lower parts. Since the ratio between the upper and lower remote elements is rarely 50/50, this can lead to unexpected results, for example, with elements of the same level. <p> <span>Ba</span> <span>Ba</span> </p>
p { font-family: Catamaran; font-size: 100px; line-height: 200px; }
p
tag with two single-level span
elements that inherit font-family
, font-size
and fixed line-height
. Baselines are the same, and the height of the container line is equal to their line-height
.font-size
? span:last-child { font-size: 50px; }
line-height
values, but sometimes fixed values are required to create an ideal vertical rhythm. Honestly, no matter what you choose, you will always have problems aligning the string.p
tag with line-height: 200px
, which contains a single span
that inherits its line-height
<p> <span>Ba</span> </p>
p { line-height: 200px; } span { font-family: Catamaran; font-size: 100px; }
p
has its own distinct font-family
value (by default, this is a serif). The base lines of the p
and span
tags are in all likelihood at different heights, and therefore the height of the container row is larger than expected. This is because browsers perform a calculation, assuming that each container of the line starts with a zero-width character, which is called “strut” in the specification.vertical-align: middle
will save us? As stated in the specification, the middle
“aligns the container with the vertical midpoint (midpoint) with the baseline of the parent container plus half the x-height of the primary element.” The ratio of baselines, as well as x-heights (x-height), can be different, so you can not rely on the middle
alignment. And the worst part is the fact that in most of the middle
scenarios, the “center” is never truly. This is influenced by too many factors that cannot be specified via CSS (x-height, the ratio of the upper and lower outliers, etc.).vertical-align: top / bottom
- alignment at the top or bottom of the container row;vertical-align: text-top / text-bottom
— Aligns to the top or bottom of the content area.vertical-align: top
. Invisible line-height
can give a strange, but expected result.vertical-align
also accepts numeric values that shift the container above or below relative to the baseline. This last option may come in handy.line-height
and vertical-align
interaction, but now the question is, can we manage font metrics through CSS? In short, no. Although I would really like this. In any case, I think it is time to have some fun. Font metrics are constant, so at least we should have something.font-size
, at which the height of capital letters will be 100px. p { /* */ --font: Catamaran; --fm-capitalHeight: 0.68; --fm-descender: 0.54; --fm-ascender: 1.1; --fm-linegap: 0; /* */ --capital-height: 100; /* font-family */ font-family: var(--font); /* , */ --computedFontSize: (var(--capital-height) / var(--fm-capitalHeight)); font-size: calc(var(--computedFontSize) * 1px); }
vertical-align
based on the ratio between the upper and lower outweigh elements.line-height: normal
and the height of the content area: p { … --lineheightNormal: (var(--fm-ascender) + var(--fm-descender) + var(--fm-linegap)); --contentArea: (var(--lineheightNormal) * var(--computedFontSize)); }
p { … --distanceBottom: (var(--fm-descender)); --distanceTop: (var(--fm-ascender) - var(--fm-capitalHeight)); }
vertical-align
as the difference between these distances, multiplied by the calculated font-size
value (This value should be applied to the string child element). p { … --valign: ((var(--distanceBottom) - var(--distanceTop)) * var(--computedFontSize)); } span { vertical-align: calc(var(--valign) * -1px); }
line-height
and calculate it, keeping the vertical alignment: p { … /* */ --line-height: 3; line-height: calc(((var(--line-height) * var(--capital-height)) - var(--valign)) * 1px); }
span::before { content: ''; display: inline-block; width: calc(1px * var(--capital-height)); height: calc(1px * var(--capital-height)); margin-right: 10px; background: url('https://cdn.pbrd.co/images/yBAKn5bbv.png'); background-size: cover; }
line-height
);line-height: normal
depends on the font metrics.line-height: n
virtual area may become smaller than the content area.vertical-align
.line-height
and vertical-align
properties of its children.Source: https://habr.com/ru/post/337450/
All Articles