美文网首页Web前端之路
css行内元素行为浅析

css行内元素行为浅析

作者: 乱世破碎 | 来源:发表于2018-03-24 11:50 被阅读33次

    引言

    之前一直不是很明确CSS行内元素布局的具体规则,最近看《CSS权威指南》这本书,总算对这部分内容有了系统的理解,故将其中最重要的部分结合我自己的理解整理出来,并做了一些演示。

    一、行内元素的结构

    首先考虑最简单的一种情形,一个块元素包裹一个行内非替换元素。p标签直接包裹文本即满足这种情形,此时p标签内的文本可称为匿名文本,其显示效果与p标签包裹一个span标签等价。

    在jsfiddle上查看

    在这样的一个p标签内,包含了如下几个区域(非替换元素的情形):

           

    • 字符框(em框):每个字符构成单独的字符框,其高度由font-size的属性决定。值得注意的是,实际字形高度可能大于或小于字符框的高度。
    •      

    • 内容区:对于非替换元素,内容区是行内文本内容构成的区域,其范围可以是若干em框构成或由字符字形描述(用户代理决定)。上例中的黄色背景区域即内容区。
    •      

    • 行内框:单个行内元素自身占据空间即行内框,其高度等于line-height的值,上例中行内框即黄色区域和上色区域上下两侧的红色区域,上下红色区域的高度为行间距(line-height值与font-size值之差)的一半。
    •      

    • 行框:行框总是包裹一行内所有的行内框,因此其上边界是行内最高行内框的上边界,下边界是行内最低行内框的下边界。上例中红色区域即行框。此外,行框会存在一个最小高度,由父元素line-height的值决定(这一点很重要)。
    • 关于最小行框,这里有个例子:

      在jsfiddle上查看

      此时p标签内仍然只有一个行内元素,但行框的高度与行内框的高度却不相等(确切的讲,此时行框高度30px,行内框高度21px),这就是行框最小高度的影响。将line-height设置为0可以消除这一影响。如果line-height的属性被设置为一个倍数(浏览器的默认属性就是这么做的),把font-size设置为0也一样能解决问题。(个人更喜欢后一种做法,因为这种情况下子元素的字体大小往往会被重新设置,而行高属性能被正常继承不需要额外编写样式。)

      注:《CSS权威指南》中没有具体解释这种最小行框高度。按我的理解,其意义在于,文档在渲染父元素某一行的时候,就可以确定了这一行的基线(见下文)位置,接下来只需要将行内元素的行内框一个个摆放在基线上,根据vertical-align属性在垂直方向上确定位置后,根据需要调整行框的高度,就行了。这与CSS渲染页面时自上而下的顺序是一致的。此外vertical-align属性对齐时,部分属性的对齐位置也是来自于这个最小行框的(确切的说应该是父元素的字体大小,见下文)。

      二、基线与对齐

      基线是文本中的概念,这条虚拟的线与小写英文字母x的下缘对齐,如图所示。

      基线 在jsfiddle上查看

      值得注意的是对30px的行内元素设置不同行高的情况,这是因为在各个行内框基线对齐之后,行框要保证包裹一行内所有的行内框,因此其高度发生了变化。

      vertical-align属性还可以设置为:

             

      • sub:基线与文本下标的基线对齐。需要注意的是,这里文本下标,是按父元素字体大小计算的下标位置。上标也同样如此。
      •      

      • super:基线与文本上标的基线对齐。
      •      

      • top:行内框顶端与行框顶端对齐。此时匿名的位置看起来很靠上,但是实际上还是基线对齐,只不过顶端对齐的45px高的行内框把行框撑高了。
      •      

      • bottom:行内框底端与行框底端对齐。
      •      

      • text-top:行内框顶端与父元素字体内容区的顶端对齐。
      •      

      • text-bottom:行内框底端与父元素字体内容区的底端对齐。
      •      

      • middle:这个属性值会引起很大的误解,实际上它是将行内框的水平对称轴与父元素字体基线上方0.5ex的位置对齐。ex即小写字母x的高度,对于有的浏览器,即0.5em,有些则会受到字体的影响。因此这一设置并不是总能让行内框在行框内垂直居中,参加middle对齐的例1-例4。通过这四个例子可以发现,要让一个行内元素在行框内(通过设置middle对齐实现)垂直居中,需要达成一个条件,即行框内影响行框高度的行内框同样被设置为middle对齐(本质上是使行内框的水平对称轴与最大行内框(此时行框高度等于最大行内框高度)的水平对称轴对齐来实现垂直居中)
      •      

      • 百分比值和固定值:行内框基线在y方向在父元素文本基线的基础按这个值发生偏移。需要注意的是,当被设置为百分比值时,这一值是根据行内元素自身的line-height值计算的。
      •      

      • inherit:从父元素继承,没啥好说的。
      • 总结下来,vertical-align属性最大的问题在于,在某些情况下,兄弟元素的高度会影响布局,不过在明白其原理之后,就能合理的利用或规避这一点了。

        三、替换元素的情况

        最典型的的非替换元素行内布局时,替换元素与非替换元素的区别主要有三点:

               

        1. 替换元素的内容区包含了外边距、border、内边距和content-box。(而行内非替换元素垂直方向的内外边距、边框、高度的设置不会影响到行内框的高度。)
        2.      

        3. 替换元素自身不接受line-height属性(但这一属性可能会继承到替换元素的内部)
        4.      

        5. 替换元素没有基线的概念,涉及到baseline、sub这种需要基线对齐
        6. 了解了这几点差异后,替换元素的vertical-align属性就很好理解了。以下是最简单的例子,图片的下沿落在父元素文本的基线上。

          在jsfiddle上查看

          可以发现图片的下方会有一定空白区域,即使图片前的文本不存在时,这一空白也一样存在,这就是父元素最小行框的影响。一直以来的解决办法是使父元素的line-height的计算值为0。研究过vertical-align属性后,发现一种新思路:将img的vertical-align属性设置为非基于基线定位的属性,如middle,因为此时行框高度即等于图片高度。

          注:对行内非替换元素设置宽度也是不会生效的,不过对其设置上下边框和内边距虽然不会影响行内框的高度,却能影响背景区域的大小。

          四、inline-block行内块元素

          行内块元素的行为本质上与替换元素是等价的,这里就不过多解释了。

          相关文章

            网友评论

              本文标题:css行内元素行为浅析

              本文链接:https://www.haomeiwen.com/subject/xqdqcftx.html