这是转载,先保留着,遇到一个非常奇怪的问题,
<a style="display: block;width: 300px;height: 100px;background: #1B6D85;">
<div style="width:50px;height:50px;display: inline-block;background: #204D74;"></div>
<div style="width:150px;height:50px;display: inline-block;background: #122B40;">
<span id="">测试内容</span>
</div>
</a>
如下一段代码,结果是
将a转为块元素,里面有左右两个区域,转为行内块元素,假如里面没有行内元素span,那么两边对齐顶部,
没有问题,但是有了测试内容span,如上出现诡异问题,后面的span被挤下来一点点,
唯一能够明确的地方在于,是属性vertical-align在默默影响着一切,至于到底为什么在那个位置,原理见下文分割线内容
个人不是很懂,暂时不做深究,解决办法就是在出现问题的div上,加上vertical-align:top,顶部对齐解决问题
基线、底线、顶线、中线、vertical-align
顶线:中文汉字的的上端沿;
中线:横过英文字母x的中间的线;
基线(base line)并不是汉字文字的下端沿,而是英文字母“x”的下端沿;
底线:中文汉字的下端沿;
内容区:指底线和顶线包裹的区域(行内元素display:inline可以通过background-color属性显示出来),实际中不一定看得到,但确实存在。内容区的大小依据font-size的值和字数进行变化。
行高(line-height):包括内容区与以内容区为基础对称拓展的空白区域,我们称之为行高。一般情况下,也可以认为是相邻文本行基线间的距离。
行距:指相邻文本行间上一个文本行底线和下一文本行顶线之间的距离。当然,我更愿意认为是(上文本行行高-内容区高度)/2+(下文本行行高-内容区高度)/2。
行内框:是一个浏览器渲染模型中的一个概念,无法显示出来,但是它又确实存在,它的高度就是行高指定的高度。
行框(line box):同行内框类似的概念,行框是指本行的一个虚拟的矩形框,也是浏览器渲染模式中的一个概念。行框高度等于本行内所有元素中行内框最大的值(以行高值最大的行内框为基准,其他行内框采用自己的对齐方式向基准对齐,最终计算行框的高度)。
https://www.2cto.com/kf/201410/343609.html
https://christopheraue.net/design/vertical-align翻译而来
我们需要 谈谈这个!
是的,我们来谈谈CSS属性vertical-align
。它的用途是将文本和元素彼此相邻。就像在一些文本旁边居中一个图标。
但是,它可能是一个真正的卑鄙小人,有时候所有看似神秘的规则在起作用。例如,可能会发生这样的情况:您更改的元素vertical-align
根本不会更改其对齐方式,但旁边的其他元素会执行此操作!真高兴啊!
因此,为了最大限度地减少未来的痛苦,我通过W3C的CSS 规范来澄清vertical-align
一劳永逸的行为。
让我们来解决游戏规则吧!
您将在本文中学到什么:
- 在行框中的内联级元素上垂直对齐行为。⬀
- 内联级元素和线框具有基线,顶部和底部。⬀
- 垂直对齐对齐基线,顶部和底部。⬀
- 示例:如何将图标置于一些文本旁边。⬀
- 示例:基线可能如何移动。⬀
- 示例:如何在底部没有间隙的情况下垂直居中元素。⬀
- 示例:如何消除两个对齐元素之间的间隙。⬀
垂直对齐行为在行框中的内联级元素
vertical-align
用于对齐内联级元素。这些是元素,其display
属性的计算结果为
- 排队,
- 内联块或
- 内联表(本文未考虑)。
内联元素基本上是包装文本的标签。
内联块元素就是它们的名字所暗示的:块元素直接生成。它们可以具有宽度和高度(可能由其自己的内容定义)以及填充,边框和边距。
内联级元素以行的形式排列在一起。一旦有多个元素不适合当前行,就会在其下面创建一个新行。所有这些线有一个所谓的行框,包围了线的所有内容。不同大小的内容意味着不同高度的线框。在下图中,线框的顶部和底部用红线表示。
高高在上 的一行文字。文字中的短文。这可能发生。
线框勾勒出我们正在播放的字段。在这些线框内,属性vertical-align
负责对齐各个元素。那么,关于什么是元素对齐?
关于基线,上衣和下装
垂直对齐的最重要参考点是所涉及元素的基线。在某些情况下,元素封闭盒的顶部和底部边缘也变得很重要。让我们看一下每个相关元素类型的基线和外边缘的位置:
内联元素
aAÄqQ
aAÄqQ
aAÄqQ
在这里,您可以看到彼此相邻的三行文本。线高的顶部和底部边缘用红线表示,字体的高度用绿线表示,基线用蓝线表示。在左侧,文本的行高设置为与font-size 相同的高度。绿色和红色线在每侧折叠成一条线。在中间,行高是font-size的两倍。在右侧,线条高度是字体大小的一半。
内联元素的外边缘与其线高的顶部和底部边缘对齐。这并不重要,如果该行高度比字体的高度。因此,外边缘是上图中的红线。
内联元素的基线是行,字符坐上。这是图中的蓝线。粗略地说,基线位于字体高度中间的某个位置。有关详细定义,请查看W3C规范。
内联块元素
C
C
从左到右,您可以看到:具有流入内容的内联块元素(“c”),具有流入内容overflow: hidden
的内联块元素以及没有流入内容的内联块元素(但是内容区域有高度)。边距的边界用红线表示,边框是黄色,填充绿色,内容区域是蓝色。每个内联块元素的基线显示为蓝线。
Inline-block元素的外边缘是其边框的顶部和底部边缘。这些是图中的红线。
Inline-block元素的基线取决于元素是否具有in-flow内容:
- 在流内容的情况下,内联块元素的基线是正常流中的最后一个内容元素的基线(左边的例子)。对于最后一个元素,根据其自己的规则找到其基线。
- 如果流入内容但
overflow
属性评估为其他内容visible
,则基线是边距框的下边缘(示例位于中间)。因此,它与内联块元素的底边相同。 - 如果没有流入内容,则基线也是边距框的下边缘(例如右侧)。
线盒
x这可能发生。
你已经在上面看过这个设置了。这次我画了线框文本框的顶部和底部(绿色,下面更多)和基线(蓝色)。我还通过给出灰色背景来突出显示文本元素的区域。
行盒具有顶部边缘对齐该线的最上面的元件的顶部边缘和底部边缘对准线的最底部元件的底部边缘。这是上图中红线所示的方框。
线框的基线是可变的:
CSS 2.1没有定义线框基线的位置。
- W3C规格
使用vertical-align时,这可能是最令人困惑的部分。这意味着,基线被放置在需要满足所有其他条件(如垂直对齐和最小化线盒高度)的位置。它是等式中的自由参数。
由于线框的基线是不可见的,因此它可能不会立即显而易见。但是,你可以很容易地看到它。只需在问题的行尾添加一个字符,就像我在图中添加了“x”一样。如果此字符未以任何方式对齐,则默认情况下它将位于基线上。
在它的基线周围,线框有我们称之为文本框的内容。文本框可以简单地被视为行框内的内联元素,没有任何对齐。它的高度等于其父元素的字体大小。因此,文本框仅包含行框的无格式文本。该框由上图中的绿线表示。由于此文本框与基线相关联,因此它会在基线移动时移动。(旁注:此文本框在W3C规范中称为strut)
哎呀,这是最难的部分。现在,我们知道要把事情放在眼里的一切。让我们快速总结一下最重要的事实:
- 有一个叫做线框的区域。这是发生垂直对齐的区域。它有一个基线,一个文本框和一个顶部和底部边缘。
- 有内联级元素。这些是对齐的对象。它们具有基线和顶部和底部边缘。
垂直对齐对齐基线,顶部和底部
通过使用vertical-align
上面列表中提到的参考点设置成一定的关系。
相对于线框的基线对齐
x baselinesubsuper-50%+ 10px
- baseline:元素的基线恰好位于线框的基线顶部。
- sub:元素的基线移动到线框的基线以下。
- super:元素的基线偏移到线框的基线之上。
- <percentage>:元素的基线相对于线框的基线相对于线高移动了一个百分比。
- <length>:元素的基线相对于线框的基线移动了绝对长度。
特殊案例vertical-align: middle
值得拥有自己的数字:
x中间
- middle:元素顶部和底部边缘之间的中点与线框的基线加上x高度的一半对齐。
相对于线框的文本框对齐
xtext-toptext-bottom
也可以在相对于线框的基线对齐的情况下列出这两个案例,因为文本框的位置由基线确定。
- text-top:元素的上边缘与线框的文本框上边缘对齐。
- text-bottom:元素的下边缘与线框的文本框底边对齐。
相对于线框的外边缘对齐
X顶部底部
- 顶部:元素的上边缘与线框的上边缘对齐。
- bottom:元素的下边缘与线框的下边缘对齐。
在正式的定义被发现,当然,W3C的规格。
为什么纵向对齐表现它的行为方式
我们现在可以在某些情况下仔细研究垂直对齐。特别是,我们将处理可能出错的情况。
以图标为中心
困扰我的一个问题是:我有一个图标,我想在一行文本旁边居中。只是给图标a vertical-align: middle
似乎并没有以令人满意的方式集中它。看看这个例子:
中心?
中心!
<!-- left mark-up -->
<span class="icon middle"></span>
Centered?
<!-- right mark-up -->
<span class="icon middle"></span>
<span class="middle">Centered!</span>
<style type="text/css">
.icon { display: inline-block;
/* size, color, etc. */ }
.middle { vertical-align: middle; }
</style>
这是一个例子,但我画了一些你从上面已经知道的辅助线:
x居中?
中心!
这揭示了我们的问题。因为左侧的文本根本没有对齐,所以它位于基线上。问题是,通过对齐盒子,vertical-align: middle
我们将它与小写字母的中间对齐而没有上升部分(x高度的一半)。因此,带有上升的角色在顶部突出。
在右侧,我们采用字体的整个区域并垂直对齐其中点。文本的基线稍微偏移到线框的基线以实现此目的。结果是图标旁边的一个很好的居中文本。
线盒的基线运动
使用时这是常见的陷阱vertical-align
:线框基线的位置受该线中所有元素的影响。让我们假设,元素以这样的方式对齐,线框的基线必须移动。由于大多数垂直对齐(顶部和底部除外)是相对于此基线完成的,因此也会导致该线中所有其他元素的调整位置。
一些例子:
-
如果跨越整个高度的线条中有一个高元素,
vertical-align
则对其没有影响。它的顶部和底部下方没有空间,可以让它移动。为了实现相对于线框基线的对齐,线框的基线必须移动。短盒有一个vertical-align: baseline
。在左侧,高高的盒子对齐text-bottom
。在右边,它是对齐的text-top
。你可以看到基线跳起来带着它的短框。<!-- left mark-up --> <span class="tall-box text-bottom"></span> <span class="short-box"></span> <!-- right mark-up --> <span class="tall-box text-top"></span> <span class="short-box"></span> <style type="text/css"> .tall-box, .short-box { display: inline-block; /* size, color, etc. */ } .text-bottom { vertical-align: text-bottom; } .text-top { vertical-align: text-top; } </style>
将高元素与其他值对齐时会出现相同的行为
vertical-align
。 -
即使设置
vertical-align
为bottom
(左)和top
(右)也会移动基线。这很奇怪,因为根本不应该涉及基线。<!-- left mark-up --> <span class="tall-box bottom"></span> <span class="short-box"></span> <!-- right mark-up --> <span class="tall-box top"></span> <span class="short-box"></span> <style type="text/css"> .tall-box, .short-box { display: inline-block; /* size, color, etc. */ } .bottom { vertical-align: bottom; } .top { vertical-align: top; } </style>
-
将两个较大的元素放置在一条直线中并垂直对齐它们会移动基线,使其完成两个对齐。然后调整线框的高度(左)。添加第三个元素,由于其对齐而不超出线框的边缘,既不会影响线框的高度,也不会影响基线的位置(中间)。如果它*超出了线框的边缘,则再次调整线框的高度和基线。在这种情况下,我们的前两个框被按下(右)。
<!-- left mark-up --> <span class="tall-box text-bottom"></span> <span class="tall-box text-top"></span> <!-- middle mark-up --> <span class="tall-box text-bottom"></span> <span class="tall-box text-top"></span> <span class="tall-box middle"></span> <!-- right mark-up --> <span class="tall-box text-bottom"></span> <span class="tall-box text-top"></span> <span class="tall-box text-100up"></span> <style type="text/css"> .tall-box { display: inline-block; /* size, color, etc. */ } .middle { vertical-align: middle; } .text-top { vertical-align: text-top; } .text-bottom { vertical-align: text-bottom; } .text-100up { vertical-align: 100%; } </style>
内联级元素下面可能会有一点差距
看看这个设置。如果您尝试垂直对齐li
列表的元素,这种情况很常见。
<ul>
<li class="box"></li>
<li class="box"></li>
<li class="box"></li>
</ul>
<style type="text/css">
.box { display: inline-block;
/* size, color, etc. */ }
</style>
如您所见,列表项位于基线上。在基线下面是一些空间来庇护文本的下降。这导致了差距。解决方案?只需将基线移开,例如通过将列表项与vertical-align: middle
以下项对齐:
<ul>
<li class="box middle"></li>
<li class="box middle"></li>
<li class="box middle"></li>
</ul>
<style type="text/css">
.box { display: inline-block;
/* size, color, etc. */ }
.middle { vertical-align: middle; }
</style>
对于具有文本内容的内联块,不会发生这种情况,因为内容已经将基线向上移动。
内联级元素之间的差距正在打破布局
这主要是内联级元素本身的问题。但由于它们是垂直对齐的要求,因此了解这一点很好。
您可以在列表项之间的前一个示例中看到此差距。差距来自标记中存在的内联元素之间的空白区域。内联元素之间的所有空白区域都折叠为一个空格。例如,如果我们想要将两个内联元素放在一起并给出它们width: 50%
,那么这个空间就会受到阻碍。没有足够的空间容纳两个50%的元素和一个空间。因此该行分为两行破坏布局(左)。要消除差距,我们需要删除空格,例如使用html注释(右)。
50%宽
50%宽...并在下一行
50%宽
50%宽
<!-- left mark-up -->
<div class="half">50% wide</div>
<div class="half">50% wide... and in next line</div>
<!-- right mark-up -->
<div class="half">50% wide</div><!--
--><div class="half">50% wide</div>
<style type="text/css">
.half { display: inline-block;
width: 50%; }
</style>
垂直对齐揭秘
是的,就是这样。一旦你了解规则,它就不是很复杂。如果vertical-align
不表现,请问这些问题:
- 线框的基线和顶部和底部边缘在哪里?
- 内联级元素的基线和顶部和底部边缘在哪里?
这将解决问题的解决方案。