我的问题基本上归结为:为什么在同一行中存在其他对齐时,vertical-align:baseline被忽略了?
示例:如果第二个span具有vertical-align:bottom,则第一个span的垂直对齐如果是基线则被忽略;它表现得好像它也有底部.
span:first-child {vertical-align:baseline} span:last-child {font-size:3em; vertical-align:bottom;}
<p> <span>one</span> <span>two</span> </p>
如果所有跨度都具有基线以外的垂直对齐,或者如果它们都是基线,则它们的行为与预期一致.
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>
如果这是正常行为,那为什么不在任何地方描述?我没有找到任何说明基线和顶部/底部以这种方式相互干扰的来源.
解决方法
vertical-align
用于对齐inline-level elements.这些是元素,其display
属性的计算结果为:
>内联
>内联块
>内联表(在此答案中未考虑)
内联级元素以行的形式排列在一起.一旦有多个元素不适合当前行,就会在其下面创建一个新行.所有这些线都有一个所谓的线框,它包含了线的所有内容.尺寸不同的内容意味着不同高度的线框.
在下图中,线框的顶部和底部用红线表示.
在这些线框内,垂直对齐属性负责对齐各个元素.
底线
垂直对齐的最重要参考点是所涉及元素的基线.在某些情况下,元素封闭盒的顶部和底部边缘也变得很重要.
内联元素
线高的顶部和底部边缘由红线表示,字体的高度由绿线表示,基线由蓝线表示.
在左侧,文本的行高设置为与font-size相同的高度.绿色和红色线在每侧折叠成一条线.
在中间,行高是font-size的两倍.
在右侧,线条高度是字体大小的一半.
请注意,如果行高小于字体高度,则内联元素的外边缘(红线)无关紧要.
内联块元素
从左到右,您会看到:
>具有in-flow内容的内联块元素
>一个内联块元素,内容为in-flow,溢出:隐藏
>没有in-flow内容的内联块元素(但内容区域有高度)
边距的边界用红线表示,边框是黄色,填充绿色,内容区域是蓝色.每个内联块元素的基线显示为蓝线.
内联块元素的基线取决于元素是否具有in-flow内容.的情况下:
> in-flow内容内联块元素的基线是正常流程中最后一个内容元素的基线(左侧示例)
> in-flow内容但溢出属性评估为除可见之外的其他内容,基线是边距框的下边缘(示例在中间)
>没有in-flow内容,基线再次是边距框的下边缘(右边示例)
线框
使用vertical-align时,这可能是最令人困惑的部分.这意味着,基线被放置在需要的地方,以满足所有其他条件,如垂直对齐和最小化线盒的高度.它是等式中的自由参数.
由于线框的基线是不可见的,因此它可能不会立即显而易见.但是,你可以很容易地看到它.只需在问题的行尾添加一个字符,如图中的“x”.如果此字符未以任何方式对齐,则默认情况下它将位于基线上.
在它的基线周围,线框有我们称之为文本框的内容(图中的绿线).文本框可以简单地被视为行框内的内联元素,没有任何对齐.它的高度等于其父元素的字体大小.因此,文本框仅包含行框的无格式文本.由于此文本框与基线相关联,因此它会在基线移动时移动.
片段
如果您想在此处使用各种vertical-align和font-size进行一些实验,那么您可以使用一个片段来试用它.也可在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制作.
资料来源:请注意,这是由Christopher Aue撰写的Vertical-Align: All You Need To Know的摘录.