CSS:vertical-align 那些事

1. vertical-align 基础

是不是用过 vertical-align?

还想实现垂直居中?

然而并不好用?

图:vertical-align 不好用?

先看 MDN 给的定义

The vertical-align CSS property specifies sets vertical alignment of an inline or table-cell box.

The vertical-align property can be used in two contexts:

  • To vertically align an inline element's box inside its containing line box.
  • To vertically align the content of a cell in a table.

Note that vertical-align only applies to inline and table-cell elements: you can't use it to vertically align block-level elements.

很清楚!很明白!

  • 不适用于 “块级元素”;
  • 适用于设置 table-cell内容的垂直对齐方式;
  • 适用于设置inline elememts's boxline-box中的垂直对齐方式;

2. table-cell 中使用 vertical-align

还是看 MDN 的定义

—— https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align#Values_for_table_cells

代码示例:

运行效果:

这个例子想说明以下几点:

  1. top、middle、bottom,就是在垂直方向上与 cell 的 top、middle、bottom 对齐;
  2. baseline 是指 cell 的 baseline 与 row 中其他 cell 所对齐的 baseline 对齐;
  3. 至于 row 的 baseline 在哪?为什么会变?继续往下看;

3. 字体设计

字体设计

多少也得懂点

3.1. baseline(基线):

In European and West Asian typography and penmanship, the baseline is the line upon which most letters "sit" and below which descenders extend. In the example to the right, the letter 'p' has a descender; the other letters sit on the (red) baseline.

Northern Brahmic scripts have a characteristic hanging baseline; the letters are aligned to the top of the writing line, marked by an overbar, with diacritics extending above the baseline.

East Asian scripts have no baseline; each glyph sits in a square box, with neither ascenders nor descenders. When mixed with scripts with a low baseline, East Asian characters should be set so that the bottom of the character is between the baseline and the descender height.

—— https://en.wikipedia.org/wiki/Baseline_(typography)

3.2. meanline(中线):

In typography, the mean line, also called the midline, is half the distance from the baseline to the cap height. This may or may not be the x-height, depending on the design of the lower case letters. A very high or very low x-height may mean that the midline is above or below the x-height. Round glyphs will break (overshoot) the mean line slightly in many typefaces, since this is aesthetically more pleasing; a rounded shape will appear visually smaller than flat-topped (or bottomed) shapes of equal height, due to an optical illusion.

—— https://en.wikipedia.org/wiki/Mean_line

3.3. Cap height:

In typography, cap height is the height of a capital letter above the baseline for a particular typeface. It specifically is the height of capital letters that are flat—such as H or I—as opposed to round letters such as O, or pointed letters like A, both of which may display overshoot.

——https://en.wikipedia.org/wiki/Cap_height

3.4. x-height:

Typically, this is the height of the letter x in the font (the source of the term), as well as the v, w, and z. (Curved letters such as a, c, e, m, n, o, r, s, and u tend to exceed the x-height slightly, due to overshoot.) One of the most important dimensions of a font, x-height is used to define how high lower-case letters are compared to upper-case letters.

—— https://en.wikipedia.org/wiki/X-height

3.5. Overshoot:

Overshoot is the degree that capital letters go below the baseline or above the cap height, and lowercase letters go below the baseline or above the mean line. In typeface design, the overshoot of a round or pointed letter (like O or A) is the degree to which it extends higher or lower than a comparably sized "flat" letter (like X or H), to achieve an optical effect of being the same size; it compensates for inaccuracies in human visual perception. Formally, it is the degree to which capital letters go below the baseline or above the cap height, or to which a lowercase letter goes below the baseline or above the x-height. For example, the highest and lowest extent of the capital O will typically exceed those of the capital X. Although the extent of overshoot varies depending on the design and the designer, perhaps 1% to 3% of the cap or x-height is typical for O. Peter Karow's Digital Formats for Typefaces recommends 3% for O and 5% for A.

—— https://en.wikipedia.org/wiki/Overshoot_(typography)

—— https://slate.com/human-interest/2015/04/tobias-frere-jones-explains-the-optical-illusion-that-tricks-our-brains-into-perceiving-typeface-letters-are-of-equal-height.html

3.5. EM:

The name em was originally a reference to the width of the capital M in the typeface and size being used, which was often the same as the point size.

—— https://en.wikipedia.org/wiki/Em_(typography)

3.5. line-height、leading:

leading = line-height - font-size 其中一半leading加到文字上方,另一半leading加到文字下方。

—— http://www.ituring.com.cn/article/18076

摘抄了这么一大堆

目的是让大家对字体中

baseline、x-height 等基本概念

有个直观的认识

4. IFC(Inline formatting contexts)

IFC,简单理解

就是行内级元素的排版容器

并且具有特定的排版策略

An inline formatting context is established by a block container box that contains no block-level boxes. In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.

  • IFC 由 不包含块级元素块容器盒子 建立(只有行内级元素)。
  • IFC中,盒子水平放置,一个接着一个,从包含块的顶部开始。
  • 水平方向的 margin、border、margin 放置于这些盒子之间;
  • 这些盒子在竖直方向有不同的对齐方式(bottom、top、baseline);
  • 包含一整行盒子的矩形区域叫做行盒

—— https://www.w3.org/TR/CSS22/visuren.html#inline-formatting

行高怎么计算?

As described in the section on inline formatting contexts, user agents flow inline-level boxes into a vertical stack of line boxes. The height of a line box is determined as follows: 译:IFC 中,浏览器会将 行内级盒子在水平方向上一个接着一个摆放,每一行形成一个 行盒子,行盒子则会进一步在在竖直方向上堆叠。

  • The height of each inline-level box in the line box is calculated. For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; for inline boxes, this is their 'line-height'.

译:对于每个行内级元素的高度:替换元素的高度由margin-box决定;行内元素的高度则有 line-height 决定。

  • The inline-level boxes are aligned vertically according to their 'vertical-align' property. In case they are aligned 'top' or 'bottom', they must be aligned so as to minimize the line box height.

译:行内级元素在竖直方向上的对齐方式由 vertical-align 指定。但必须在满足所有的对齐条件下,保持行盒子的高度最小。

  • The line box height is the distance between the uppermost box top and the lowermost box bottom.

译:行盒的高度是从最高的盒子的顶端到最低的盒子的底端。

  • Empty inline elements generate empty inline boxes, but these boxes still have margins, padding, borders and a line height, and thus influence these calculations just like elements with content.

译:空的行内元素也会产生空的行内盒子,它也会产生margin、padding、border、line-height,就像有内容的元素一样。

—— https://www.w3.org/TR/CSS22/visudet.html#line-height

一些专业名词的官方解释

行内级元素:

Inline-level elements are those elements of the source document that do not form new blocks of content; the content is distributed in lines (e.g., emphasized pieces of text within a paragraph, inline images, etc.). The following values of the 'display' property make an element inline-level: 'inline', 'inline-table', and 'inline-block'.

行内级盒子:

Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context.

行内盒子:

An inline box is one that is both inline-level and whose contents participate in its containing inline formatting context. A non-replaced element with a 'display' value of 'inline' generates an inline box.

原子行内级盒子:

A non-replaced element with a 'display' value of 'inline' generates an inline box. Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.

—— https://www.w3.org/TR/CSS22/visuren.html#inline-boxes 9.2.2

匿名行内盒子:

Any text that is directly contained inside a block container element (not inside an inline element) must be treated as an anonymous inline element.

—— https://www.w3.org/TR/CSS22/visuren.html#inline-boxes 9.2.2.1

块级元素:

Block-level elements – those elements of the source document that are formatted visually as blocks (e.g., paragraphs) – are elements which generate a block-level principal box. Values of the 'display'property that make an element block-level include: 'block', 'list-item', and 'table'.

块级盒子:

Block-level boxes are boxes that participate in a block formatting context.

块容器:

In CSS 2.2, a block-level box is also a block container box unless it is a table box or the principal box of a replaced element. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes.

块容器元素:

An element whose principal box is a block container box is a block container element. Values of the 'display' property which make a non-replaced element generate a block container include 'block', 'list-item' and 'inline-block'.

块盒子:

Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but are not block-level. Block-level boxes that are also block containers are called block boxes.

—— https://www.w3.org/TR/CSS22/visuren.html#inline-boxes 9.2.1

上面这一堆,是为了说明

IFC 中每一行的行高如何计算

5. 深入 vertical-align?

再看一遍 MDN 的定义

To vertically align an inline element's box inside its containing line box. 译:用于在竖直方向上对齐 行盒 中的 行内元素盒。

有哪些对齐方式?

特别注意:

  • baseline:行内元素盒的基线与行盒的基线对齐;
  • sub:行内元素盒的基线相对于行盒的基线,偏下一点(偏多少浏览器说了算);
  • super:行内元素盒的基线相对于行盒的基线,偏上一点(偏多少浏览器说了算);
  • middle:行内元素盒的中心相对于行盒的基线,偏上1/2 x-height

那么问题来了

行盒的基线在哪?

CSS 2.2 does not define the position of the line box's baseline.

—— https://www.w3.org/TR/CSS22/visudet.html#line-height

The inline-level boxes are aligned vertically according to their 'vertical-align' property. In case they are aligned 'top' or 'bottom', they must be aligned so as to minimize the line box height.

—— https://www.w3.org/TR/CSS22/visudet.html#line-height

简单说

行盒的基线位置不确定

由行盒内所有的行内元素共同决定

在满足所有元素的对齐条件下

保持行盒高度最小

用代码感受一波

代码示例:

运行效果:

再感受一波

代码示例:

运行效果:

不写了,太复杂

大家还是看规范去吧

最后来两个 vertical-align 的经典示例

6. 示例1:模拟ul、li

运行效果:

代码示例:

7. 示例2:模态弹框居中

运行效果:

代码示例:

参考:

《CSS 权威指南》 《CSS 世界》 《CSS 核心技术详解》 MDN 中 vertical-align 的定义: https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align CSS2.2 中 vertical-align 的定义: https://www.w3.org/TR/CSS22/visudet.html#propdef-vertical-align vertical-align 相关的优秀文章: http://phrogz.net/css/vertical-align/index.html https://christopheraue.net/design/vertical-align https://christopheraue.net/design/centering-inline-block-with-vertical-align-middle https://christopheraue.net/design/why-vertical-align-is-not-working

原文发布于微信公众号 - WebJ2EE(WebJ2EE)

原文发表时间:2018-12-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券