垂直对齐:基线如何处理? [英] What's the deal with vertical-align: baseline?

查看:88
本文介绍了垂直对齐:基线如何处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我了解CSS的知识,但我现在需要向某人解释一些内容,但我发现我做不到.

I thought I knew my way around CSS, but I needed to explain something to someone just now and I found I couldn't.

我的问题基本上可以归结为:当同一行中还有其他对齐方式时,为什么vertical-align:baseline被忽略?

My question basically boils down to: why is vertical-align:baseline ignored when there are other alignments in the same line?

示例:如果第二个跨度为vertical-align:bottom,则第一个跨度的垂直对齐方式为baseline;它的行为就像它也具有bottom.

Example: if the second span has vertical-align:bottom, the first span's vertical alignment is ignored if it is baseline; it behaves as if it has bottom too.

span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:bottom;}

<p>
  <span>one</span> <span>two</span>
</p>

如果所有跨度都具有除baseline以外的垂直对齐方式,或者如果全部为baseline,则它们的行为将与预期的一样.

While if all the spans have a vertical-align other than baseline, or, if they are all baseline, then they behave as expected.

span:first-child {vertical-align:top}
span:last-child {font-size:3em; vertical-align:bottom;}

<p>
  <span>one</span> <span>two</span>
</p>

span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:baseline;}

<p>
  <span>one</span> <span>two</span>
</p>

如果这是正常行为,那么为什么在任何地方都没有描述?我还没有发现任何表示基线和顶部/底部以这种方式相互干扰的消息.

If this is normal behaviour, then why isn't it described anywhere? I haven't found any source that says baseline and top/bottom interfere with each other in such a way.

推荐答案

垂直对齐

vertical-align 用于对齐内联级元素.这些是元素,其 display 属性的计算结果为:

Vertical-Align

vertical-align is used to align inline-level elements. These are elements, whose display property evaluates to:

  • inline
  • inline-block
  • inline-table(此答案未考虑)
  • inline
  • inline-block
  • inline-table (not considered in this answer)

行内元素彼此并排布置.一旦超出当前行的元素数量过多,就会在其下方创建一个新行.所有这些行都有一个所谓的 line box (行框),其中包含了该行的所有内容.内容大小不同意味着线盒的高度不同.

Inline-level elements are laid out next to each other in lines. Once there are more elements than fit into the current line, a new line is created beneath it. All these lines have a so-called line box, which encloses all the content of its line. Differently sized content means line boxes of different height.

在下图中,线框的顶部和底部用红线表示.

在这些线框内,属性vertical-align用于对齐各个元素.

Inside these line boxes the property vertical-align is responsible for aligning the individual elements.

垂直对齐的最重要参考点是所涉及元素的基线.在某些情况下,元素封闭框的顶部和底部边缘也很重要.

The most important reference point to align vertically is the baseline of the involved elements. In some cases the top and bottom edge of the element’s enclosing box becomes important, too.

行高的上下边缘用红线表示,字体的高度用绿线表示,基线用蓝线表示.

The top and bottom edge of the line height is indicated by red lines, the height of the font by green lines and the baseline by a blue line.

在左侧,文本的行高设置为与字体大小相同的高度.绿线和红线在每一侧都折叠为一条线.

On the left, the text has a line height set to the same height as the font-size. The green and red line collapsed to one line on each side.

在中间,行高是字体大小的两倍.

In the middle, the line height is twice as large as the font-size.

在右侧,行高是字体大小的一半.

On the right, the line height is half as large as the font-size.

请注意,如果行高小于字体高度,则内联元素的外边缘(红线)无关紧要.

Note that the inline element’s outer edges (the red lines) does not matter, if the line height is smaller than the height of the font.

从左到右,您将看到:

具有流中的inline-block元素内容和overflow: hidden

一个inline-block元素,没有流中内容(但内容区域具有高度)

an inline-block element with no in-flow content (but the content area has a height)

边距的边界由红线表示,边界为黄色,填充绿色为边界,内容区域为蓝色.每个inline-block元素的基线都显示为蓝线.

The boundaries of the margin is indicated by red lines, the border is yellow, the padding green and the content area blue. The baseline of each inline-block element is shown as a blue line.

inline-block元素的基线取决于该元素是否具有内容.如果是以下情况:

The inline-block element’s baseline depends on whether the element has in-flow content. In case of:

  • 流量包含以下内容的基准: inline-block元素是正常流程中最后一个内容元素的基线(左侧的示例)

  • in-flow content the baseline of the inline-block element is the baseline of the last content element in normal flow (example on the left)

流内内容,但overflow属性的计算结果不是可见的,基线是边界框的底部边缘(中间的示例)

in-flow content but an overflow property evaluating to something other than visible, the baseline is the bottom edge of the margin-box (example in the middle)

没有流入包含基线还是边缘框的底部边缘(右侧的示例)

no in-flow content the baseline is, again, the bottom edge of the margin-box (example on the right)

使用vertical-align时,这可能是最令人困惑的部分.也就是说,将基线放置在满足所有其他条件(例如vertical-align最小化线框高度)所需的位置.它是方程式中的免费参数.

This is probably the most confusing part, when working with vertical-align. It means, the baseline is placed where ever it needs to be to fulfil all other conditions like vertical-align and minimizing the line box’s height. It is a free parameter in the equation.

由于线框的基线是不可见的,因此它可能不会立即显而易见.但是,您可以非常轻松地使其可见.只需在问题的行首添加一个字符,如图中的"x".如果此字符未以任何方式对齐,则默认情况下它将位于基线上.

Since the line box’s baseline is invisible, it may not immediately be obvious where it is. But, you can make it visible very easily. Just add a character at the beginning of the line in questions, like the "x" in the figure. If this character is not aligned in any way, it will sit on the baseline by default.

在它的基线周围,行框具有我们称之为文本框的名称(图中的绿线).可以简单地将文本框视为行框内的内联元素,而无需任何对齐.其高度等于其父元素的font-size.因此,文本框仅包含行框的未格式​​化文本.由于此文本框与基准线绑定,因此它会在基准线移动时移动.

Around its baseline the line box has what we might call its text box (green lines in the figure). The text box can simply be thought of as an inline element inside the line box without any alignment. Its height is equal to the font-size of its parent element. Therefore, the text box only just encloses the unformatted text of the line box. Since this text box is tied to the baseline, it moves when the baseline moves.

如果您想对各种vertical-alignfont-size进行一些实验,可以在其中找到一个片段来进行尝试.也可以在 JSFiddle 中找到.

If you want to do some experiment with various vertical-align and font-size here you have a snippet where you can try it out. Is also available in JSFiddle.

let sl1 = document.getElementById('sl1');
let sl2 = document.getElementById('sl2');
let sl3 = document.getElementById('sl3');
let sl4 = document.getElementById('sl4');
let elm1 = document.getElementById('elm1');
let elm2 = document.getElementById('elm2');
let elm3 = document.getElementById('elm3');
let elm4 = document.getElementById('elm4');
let ip1 = document.getElementById('ip1');
let ip2 = document.getElementById('ip2');
let ip3 = document.getElementById('ip3');
let ip4 = document.getElementById('ip4');
let slArr = [sl1, sl2, sl3, sl4];
let elmArr = [elm1, elm2, elm3, elm4];
let ipArr = [ip1, ip2, ip3, ip4];
let valueArr = ['baseline', 'top', 'middle', 'bottom'];
for (let i = 0; i < slArr.length; i++) {
  slArr[i].addEventListener('change', (event) => {
    elmArr[i].style.verticalAlign = event.target.value;
    elmArr[i].innerHTML = event.target.value;
    addDiv();
  })
}
for (let i = 0; i < ipArr.length; i++) {
  ipArr[i].addEventListener('change', (event) => {
    elmArr[i].style.fontSize = event.target.value + 'em';
    addDiv();
  })
}

document.getElementById('btnRandom').addEventListener('click', () => {
  for (let i = 0; i < elmArr.length; i++) {
    let element = elmArr[i];
    let fontSize = Math.floor(Math.random() * 4 + 1);
    ipArr[i].value = fontSize;
    element.style.fontSize = fontSize + 'em';
    let styleIndex = Math.floor(Math.random() * 4);
    element.style.verticalAlign = valueArr[styleIndex];
    element.innerHTML = valueArr[styleIndex];
    slArr[i].selectedIndex = styleIndex;
  }
}, this);

function addDiv() {
  let view = document.getElementById('viewer');
  view.innerHTML = "";
  elmArr.forEach(function(element) {
    let div = document.createElement('div');
    div.appendChild(element.cloneNode());
    view.appendChild(div);
  }, this);
}

.header span {
  color: #000;
}

select {
  width: 100px;
}

#elms {
  border: solid 1px #000;
  margin-top: 20px;
  position: relative;
}

span {
  color: #FFF;
  font-size: 1em;
}

#elm1 {
  background-color: #300;
}

#elm2 {
  background-color: #6B0;
}

#elm3 {
  background-color: #90A;
}

#elm4 {
  background-color: #B00;
}

div {
  z-index: -1;
}

#div1 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 25%;
}

#div2 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 50%;
}

#div3 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 75%;
}

<div class="header"> <span style="width: 100px;display: block;float: left;margin-right: 20px;">vertical align</span> <span>font-size(em)</span> </div>
<div>

  <select name="sl1" id="sl1">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip1" />
  <br>
  <select name="sl2" id="sl2">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip2" />
  <br>
  <select name="sl3" id="sl3">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip3" />
  <br>
  <select name="sl4" id="sl4">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip4" />
  <br>
  <button id="btnRandom" (onclick)="random()">Random</button>
</div>
<div id="elms">
  <span id="elm1">one</span>
  <span id="elm2">two</span>
  <span id="elm3">three</span>
  <span id="elm4">four</span>
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
</div>
<div id="viewer"></div>

此代码段由 Duannx 创建.

来源:请注意,这是

Source: Please note that this is an extract of Vertical-Align: All You Need To Know written by Christopher Aue.

这篇关于垂直对齐:基线如何处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆