inline formatting context

CSS 内联格式化上下文与层叠上下文

line-box

每一行是由一个或多个行内元素(HTML标签元素或匿名内联元素文本内容)组成,专业术语称为行盒(line-box). 而 line-box 的高度由 不是由单一元素决定。

line-box 说明:

<p>  
    Good design will be better. 
    <span class="a">Ba</span> 
    <span class="b">Ba</span> 
    <span class="c">Ba</span> 
    We get to make a consequence. 
</p>  

// 这个示例表明默认基线的存在与对齐,参考文字大小字体的的基线。
<p>  
    Xx 小字体
    <span>vertical-align不影响 span ? 影响了父级</span>
    abcXx
    <span>大字体 XXxx</span>
</p>  
<style>  
span:first-child {  
  line-height: 40px;
  vertical-align: bottom;
}
span:nth-child(2) {  
  font-size: 22px;
}
</style>  

line-height

看了几篇文章,line-height 都说是两行字体基线的距离, 那么在 CSS 是这样吗? 不是的。

内容区域总是在虚拟区域的中间。以下为测试用例:

<p class="demo">dgfasdgfdsaf我是文字 </p>

.demo {
  line-height: 50px;
  vertical-align: top;
}
无论怎么设置 行高 和 vertical-align 文字都是居中的。

如果hegiht的值是auto,然后使用line-height时content-area严格上等于line-height。这个也可以解释上面得这个例子。

测试

font-size 16px 不意味 高度也是 16px

<p>我是字体,设置为 16px, 但我的高度不是 16px </p>  

line-box计算的小细节:

  • 对于内联元素,padding和border增加了其background区域,但不会增加内容区域高度(甚至是line-box高度)。因此,你在屏幕上看到的不一定就是内容区域。margin-top和margin-bottom对内联元素不生效。
  • 对于行内替代元素,inline-block和blocksified行内元素,padding,margin和border都会增加高度,所以内容区域和line-box的高度也会增加

通过上面的内容(W3Cplus 翻译的,自己偷懒就不翻译了。)可以知道一些概念的存在,但是细节还是没有描述清楚。

所以下面继续。

line-height

先看 MDN:

  • 对于块级元素,CSS属性line-height指定了元素内部line-boxes的最小高度。
  • 对于非替代行内元素,line-height用于计算line box的高度。
  • 对于替代行内元素,如button或其他input元素,line-height没有影响[1](原文未提到,对于部分替代元素,line-height依然可以影响元素的样式布局)。
// 测试用例: 
.block {
  line-height: 30px;
}
.inline {
  line-height: 30px;
}
  <p class="block">block</p>
  <span class="inline">inline</span>

 通过 chrome 检测元素: p 高度为 30px; span 高度为 21px

深入行高 此文讲的确实很透彻。

按照上面的 PDF 来详细说下属性: normal 可以使用 font 进行简写: <font-size>/<line-height> => font: 1em/normal arial, helvetica, sans-serif, inherit;

  • 继承属性的特殊说明 inherit, 在设置为 百分比的时候
body {  
font-size: 16px;  
line-height: 120%;  
}
h1 { font-size: 32px; }  
p { font-size: 16px; }  
footer { font-size: 12px; }  

继承比较特殊,类似 rem 单位的设置, 上面会计算出 line-height: 16px * 120%; 下面的 几个元素会继承这个值,所以都是 16px * 120%。 按照 CSS 规范来说,这是一个 calculated value

所以在常见的框架中,都会看到设置的是 数值: 1.2 或其他值。

Types of boxes

  • conitaing box
  • block box
  • line-box
    • inline-box
    • anonymous inline boxes

The height of line boxes is determined by the tallest inline box (or replaced element) inside the line.

目前为止: 算是有点眉目了。

所以目前最小单位是: inline-box。

但是此文的 content-area 是有问题的。以 chrome 看到的来说,上文才算是在正确的。

测试用例区

line-height 和 vertical-align 的结果与我预想的不一致,所以才产生这篇文章来解决这事。另外下面的所有的示例需要结合上面的概念来分析。

测试用 DOM: (以英文字体为测试基准)

<p>  
    [ASDFG xxxXXX **指示 1** ]
    <span>vertical-align 到底产生了什么样的影响 [指示 2 ] </span>
    多行测试
</p>  

第一种情况:

span {  
  line-height: 40px;
  vertical-align: bottom;
}

第一眼我以为是 指示1 处的字与底部对齐,而不是 span 对齐了。所以我很纠结。 但通过把 inline-box 这个概念放进去就好理解了。 因为每一行的最小高度是由 line-box 提供的, 而 p 本身没有设置行高,那么内部的匿名 inline-box 高度自然是字体本身的 content-area 高度,所以最终着这一行的高度由 span 决定了,span内的字体的 content-area 撑满了 span 的行高。而匿名 inline-box 默认与父元素的基线对齐,造成了 指示1 处文字来进行对齐动作的假象。

第二种:

p {  
  line-height: 80px;
  vertical-align: top;
}
span {  
  line-height: 40px;
  vertical-align: bottom;
}

此时出现的情况就应该是我最初预想的了。因为 p 设置了行高,内部匿名 inline-box 就继承了这个大小,改变内部的最小的高度。

就上面两种情况而言,变化的就是 line-box 的行高, 而这个行高是由内部 inline-boxs 决定的。

第三种:

<p>  
    vertical 指示1
    <span>vertical-align不影响 span ? 影响了父级 指示2</span>
    abcXx 指示1
    <span>ssss 指示3</span>
</p>

p {  
  line-height: 80px;
  vertical-align: top;
}
span:first-child {  
  line-height: 40px;
  vertical-align: bottom;
}
span:nth-child(2) {  
  line-height: 200px;
}

按我的预想是: 指示1 文字,即匿名 inline-boxs 会与顶端对齐,但是没有,所以又迷了。

第四种:

p {  
  line-height: 80px;
  vertical-align: top;
}
span:first-child {  
  line-height: 40px;
  vertical-align: bottom;
}
span:nth-child(2) {  
  line-height: 200px;
  vertical-align: top;  // 这里加上 vertical-align 才产生了预想的结果
}

以上所有

参考链接:

快速测试: https://jsbin.com/fomapibimo/edit?html,css,output:
JS Bin on jsbin.com

好了这里就差了个图了。

概念:

  • em-box = font-size = content-area
  • content-area + (half-)leading = inline box
  • inline box(min/max) = line-box

描述:

  • em-box = the em-box defined in the given font
  • font-size = the value used with the em-box to scale the font for display
  • content-area = in non-replaced elements, the box described by the font-size of each character in the element, strung together; in replaced elements, the intrinsic height of the element plus any margins, borders, or padding
  • (half-)leading = the difference between font-size and line-height, applied equally above and below the content-area for each element
  • inline box = the addition of (half-)leading to the content-area for each element; for non-replaced elements, the height of the inline box of an element will be exactly equal to the value for line-height; for replaced elements, the height of the inline box of an element will be exactly equal to the intrinsic height of the element plus any margins, borders, or padding
  • line-box = the box which bounds the highest and lowest points of the inline boxes which are part of the line

区分:

  • block inline element
  • replaced element & non-replaced element
  • inline-box
  • line-box

主要在于清楚这几个概念,明白在不同模式下的表现。