ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CSS中的行盒(line-boxes)和行内盒子(line-box)

2021-09-03 19:03:05  阅读:221  来源: 互联网

标签:box bottom top 元素 height boxes line


CSS

盒模型

  说到盒模型我们都知道,盒模型有两种,一个content-box和一个border-box 。
关于盒模型
盒模型
包含块详情

典型盒子的各个区域和边缘

典型盒子的各个区域和边缘

盒模型内部也就是content-box部分有三种情况:

  1. content-box内部是也是盒子,像俄罗斯套娃一样;
  2. content-box内部包含着一行一行的line-boxes(行盒);
  3. content-box 内部两种盒子都存在,但是内部最终还是line-boxes;

每个 HTML 元素实际上是一堆line-boxes。

在这里插入图片描述

line-boxes(行盒/行框)

  在行内格式化上下文中,line-box(行内盒子)从包含块的顶部开始一个接一个地水平排列。这些行内盒子之间遵循水平边距、边框和填充。这些行内盒子可以以不同的方式垂直对齐:它们的底部或顶部可以对齐,或者它们内部文本的基线可以对齐。形成一个矩形区域称为行框(line-boxes)。在这里插入图片描述

line-box (行内盒子)

一个line-box内部有三种,

  1. 直接是文本内容的,这种被称为匿名内联元素;
  2. 非替换元素(例如 span),
  3. 替换元素(例如img)

匿名内联元素

任何直接包含在块容器元素内(而不是内联元素内)的文本都必须被视为匿名内联元素。

<p>Some <em>emphasized</em> text</p>

上面的代码中 some 和text 由就属于匿名内联元素。
在这里插入图片描述

  蓝色部分便是一个line-box,也可说三个line-box并列在一块,每个字符一个,三个line-box的都是一样的,所以合在一起说也是一样的。

  行距、上高、下深这些名词则是继承而来的,有的甚至是铅字印刷时代的名词。想要详细了解的可以看下。你未必知道的CSS故事:揭开leading的面纱

  这些值以及比例是在设计字体时确定的,下面以“Arial”中的“ArialMT”字体为例,说说这些比例。使用fontforge软件打开“Arial”的字体文件我们可以获取一些信息。
在这里插入图片描述
在这里插入图片描述
根据上面的信息我们可以画出下图
在这里插入图片描述

数据以“Arial”为例,非实际比例。

  1. 2048标准高度(em-square)。不同字体的标准高度不同,比如256、1000、1024、2048等等都可以;
  2. 上高为1638,下深为410,这一对可以称为默认的上高和下深,有了上高和下深自然就确定了baseline的位置;
  3. win上高(1854)和win下深(434) 这一对则是windows系统下的上高和下深;HHead上高和HHead下深则是MacOS的,(我没有mac所以也没有测试)有的字体这两对上高和下深可能是不一致的;会出现同样的字体在不同的系统上,显示的位置不同。
  4. leading(行距/线距),leading的值是一分为二的放在内容区域(content-area)上下两个地方。
  5. 有了windows系统下的上高和下深以及行距自然就知道了window下的总高度了2355
  6. capital Height 大写字母的高度,所有大写字母高度都是一样的1467;
  7. x-height 小写字母x的高度 1062;
  8. 字形上高1491和字形下深431则指的是,这套字体中所有的字形达到的最高点和最低点,可以看到有的字形是会突破标准的下深的,不同字体设计不同,有的可能会突破上高,但是一般不会突破系统的上高和下深;因为突破了系统的上高和下深,显示的时候可能会出现重叠的情况;

上述的这些数据均是字体设计的时候就确定的,有了这些比例数据,接下来我们了一计算一些计算真实的line-box高度了。

已知

.main{
    font-family: Arial;
	font-size:100px;
}
  1. font-size对应的就是标准高度2048,同时它也是1em的值,也是标准行高;
  2. windows下的上高、下深和行距加起来(2355)对应的就是window下的line-height;
    那么:
  3. window下的行高就是 100 / 2048 * 2355 = 114.990234375 ≈ 115,此时115就是window下的line-height的值; 并不是网上传的font-size的1.2或者1.3 什么的,而是字体设计时定下的比例;只不过大多数字体的比例都在1.2 到1.3 这个范围附近,推荐的比例也在这范围附近;当然我们可以重新设置这个比例,比如 设置line-height:2; 那么line-height就等于200px = 100 * 2;
  4. 大写字母的高度为 100 / 2048 * 1467= 71.630859375 ≈ 72;
  5. x的高度就是 100 / 2048 * 1106 = 51.85546875 ≈ 52,这也是1ex的值,(ex可以用来做居中对齐,真居中对齐!!!(* ̄︶ ̄));
  6. 线距 100 / 2048 * 67 = 3.271484375 ≈ 3, 一半100 / 2048 * 33.5 = 1.6357421875 ≈ 2;

我们知道大多数屏幕上的每个像素都是一个小灯泡,要么亮者要么不亮,所以像素最终会是个整数,具体如何计算的由浏览器决定,不同浏览器可能不同。
以font-size为100px的“Arial”为例,总leading为3,在chrome 中可以看到,1px被分到了上半部分,2px分配到了下半部分;有兴趣的话可以试验下。
在这里插入图片描述

非替换元素

非替换元素以span为例,span 标签是通用行内容器,并没有任何特殊语义;

  非替换元素的外边距,边框和内边距不会算入行框的计算,但是它们仍然渲染在行内盒周围。这意味着如果用’line-height’指定的高度小于包含的盒(contained boxes)的内容高度,背景与内边距和外边距的颜色可能会“渗入”进相邻的行框。

例如:
流入相邻行框
它的各条线的位置和匿名内联框相同,计算方式也是相同的。

替换元素

  替换元素的内容实际由该内联元素的属性提供,比如img标签的src属性,img标签会使用src属性指定的图片,替换该元素的位置。
在这里插入图片描述
关于替换元素各条线的位置,以img为例:
在这里插入图片描述
从这个图可以看出img元素的top和text-top在同一条线上,baseline、bottom和text-bottom在同一条线上,leading对其无效。知道了各条线的位置,自然也可确定高度了。textarea也是如此。

上面只是一种解释,其实img元素的text-top和text-bottom线在哪里,我们并不需要知道,因为它是一个line-box 它的内部没有其他内容的。

text-top和text-bottom 这两条线对于line-box它是内部字体渲染是的依据和我们关系不大;这两条线在line-boxes中的时候的比较有用,是line-box根据vertical-align属性确定位置的时候的依据,而line-boxes的各条线的位置则是依据其属性计算出来的。

img和textare元素的baseline是这个盒子的下外边bottom margin 的边线,
input和select 标签的baseline是其内部的文字的baseline,其余线的位置和img相同。

PS:
当其它元素的display被设置为inline-* 的时候,top和text-top,bottom和text-bottom的位置也会如此。元素的top和bottom这两条线并不是固定的,始终在元素的最高和最低点,line-height 和height都会影响其位置。

inline-block 元素的各条线的位置

在这里插入图片描述
Inline-block 元素的外边缘(top和bottom)是其margin-box的顶部和底部边缘。

Inline-block 元素的基线取决于该元素是否具有流入内容:

  1. 在流入内容的情况下,行内块元素的基线是正常流中最后一个行框的基线。对于最后一个元素,它的基线是根据它自己的规则找到的。
  2. 如果有流入内容但overflow属性为visible以外的其他值,则基线是外边距框的底部边缘。
  3. 在没有流入内容的情况下,基线边距框的底部边缘。

line-height

  关于line-height 有两种说法,一种是line-height指的是两行文字的baseline之间的距离,另一种说法是一行文字的顶部到底部的距离,两者说法不同但是包含的高度是相同的都等于 行距(leading)+ 上高(ascent)+下深(descent),就CSS而言,或者说就本文而言采用第一种方法更容易理解和计算,就先采用第一种了。但是line-height 并不能理解为两条线之间的距离,个人感觉更应该理解为 line-height = 行距(leading)+ 上高(ascent)+下深(descent),不同的字体和字体大小都会计算出来不同的line-height。

  如果以baseline为标准给line-height下个更准确的定义的话就是,在font-size font-family相同的情况下相邻两个行盒(line-boxes)内的两个vertical-align相同的行内盒子(line-box)的baseline 距离;

  两个相邻的行盒子font-size或者font-family不同导致各自自的line-height不同的时候,它们的各自内部的两个vertical-align相同的行内盒子(line-box)的baseline之间的距离是,各自的line-height除以2然后加起来,如果从这个角度看那么line-height应该是行内盒子(line-box)的top到bottom之间的距离更合理些。

  我想这也是当给inline元素设置margin top/bottom以及padding top/bottom 要么无效要么不影响其垂直布局位置的原因。因为最开始css就是这么设计的,毕竟最开始只有inline和block这两种盒子,line-height就是baseline之间的距离,只是后来出现了inline-block 之类的奇怪的盒子导致前面的理论无法解释后面的盒子的行为。

不管怎么说line-height = 行距(leading)+ 上高(ascent)+下深(descent)这个应该是确定的。

line-boxes

  了解完line-box,有了line-box的高度,再说回line-boxes,计算line-boxes的高度。line-box都确定的情况下,line-boxes的高度主要受到各个line-box的vertical-aligin 属性影响。

举个栗子:

以仿宋字体为例:

 <div class="main">
      <span>Ax</span>
      <span class="baseline">A</span>
      <span class="top">B</span>
      <span class="text-top">C</span>
      <span class="middle">D</span>
      <span class="text-bottom">E</span>
      <span class="bottom">F</span>
    </div>
.main {
  font-family: FangSong;
  font-size: 200px;
  background-color: rgb(255, 0, 255);
  span {
    border: 1px solid #ffff;
    margin-right: 3px;
    background-color: rgb(0, 255, 0);
  }
  .text-top {
    vertical-align: text-top;
  }
  .text-bottom {
    vertical-align: text-bottom;
  }
  .middle {
    vertical-align: middle;
  }
  .top {
    vertical-align: top;
  }
  .bottom {
    vertical-align: bottom;
  }
}

在这里插入图片描述
为什么显示成这样,我们分析一下它的组成,标出各个子元素以及父元素的各条线的位置就知道了
在这里插入图片描述

    父元素的 font-family 和font-size已知的情况下行框的text-top、x-height half、 baseline、text-bottom;这四条线的位置就确定了(或者说确定了它们几个的相对位置),同时也确定了top线的最低位置和bottom线的最高位置,而top和bottom线的具体位置则由其子元素的位置确定之后再确定,所有子元素(除了vertical-align为top和bottom的子元素)中所处位置最高的子元素和所处位置最低的子元素分别确定top和bottom,如果所处最高元素的top比依据父元素计算出来的top线的位置低,则以父元素计算的位置为准,bottom同理;top和bottom确定之后也就可以确定vertical-align为top和bottom的子元素的位置。

    top和bottom被称作是相对于行的值,所以要在其行框确定之后才能确定它们的位置,而text-top text-bottom baseline 等等被称为相对于父元素的值,只要父元素确定了,它们便确定了。(个人推测,详见vertical-align)它俩有点特殊,具体如下

  1. 子元素属性为 vertical-align:top 如果该子元素的总高度超过了其它元素计算出来的line-boxes 高度,此时其它线位置均不变,bottom线的位置下移;在这里插入图片描述

  2. 子元素属性为 vertical-align:bottom ,如果该子元素的高度超过了其他子元素计算出来的line-boxes的高度,此时top线位置不变,其它线均下移;在这里插入图片描述

  3. 两者都超过的时候,其它线的位置以高的那个为准,相等时以vertical-align:top的为准;

  换个角度来说,line-boxes的top和bottom线始终是line-boxes的顶和底;而vertical-align:top/bottom就是始终保持子元素的top/bottom 和line-boxes的对应线重合;

往大了说对于所有的行内盒子(line-box) 来说,在定位的时候其实我们并不需要知道他们的text-top和text-bottom这两个线的位置;vertical-align 定位的时候依赖的是其父元素也就是行盒(line-boxes)的text-top和text-bottom位置,行盒的text-top和text-bottom线的位置则是由其父元素(真实元素)的font-size、font-family等属性决定的。

各个子元素的位置确定之后,line-boxes的top和bottom就可以确定了,然后这个line-boxes高度也就确定了。

  1. vertical-align 还有几个值 比如sub、super,sub使元素的基线与父元素的下标基线对齐。super使元素的基线与父元素的上标基线对齐。至于上标基线和下标基线在哪里css并没有规定,由浏览器各自的实现确定的;
  2. vertical-align 可以使用具体值将baseline相对于原有位置上下移动,从这个角度看上面的那些属性值也可以理解为,一个特殊的数字的别名;
  3. vertical-align 指定为百分比,使元素的基线对齐到父元素的基线之上的给定百分比,该百分比是line-height属性的百分比。可以是负数。

结语

   行盒(line-boxes)就像一个集装箱,把形态各异的行内盒子(line-box)包装起来,形成一个标准块(像一块砖头,怪不得叫搬砖的),一行一行的标准块叠起来,组成盒模型的content部分,从整体上来看所有的html标签最终都是由一个一个的line-box组成的。

参考:

  1. Deep dive CSS: font metrics, line-height and vertical-align
  2. 深入理解 CSS:字体度量、line-height 和 vertical-align
  3. line-height
  4. vertical-align
  5. 你未必知道的CSS故事:揭开leading的面纱
  6. css行高line-height的一些深入理解及应用
  7. 行高的计算与继承
  8. Vertical-Align: All You Need To Know (CSS)
  9. [翻译]关于Vertical-Align你需要知道的事情
  10. css vertical-align你真的很了解嘛
  11. https://drafts.csswg.org/css-display-3/#non-replaced
  12. http://www.ayqy.net/doc/css2-1/visudet.html

标签:box,bottom,top,元素,height,boxes,line
来源: https://blog.csdn.net/qq_15601471/article/details/119903856

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有