CSS

  • 盒模型
  • line-boxes(行盒/行框)
  • line-box (行内盒子)
    • 匿名内联元素
    • 非替换元素
    • 替换元素
      • inline-block 元素的各条线的位置
    • line-height
  • line-boxes(行盒)
  • 结语

盒模型

  说到盒模型我们都知道,盒模型有两种,一个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的值,也就是默认的那个normal; 并不是网上传的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)的内容高度,背景与内边距和外边距的颜色可能会“渗入”进相邻的行框。

例如:

它的各条线的位置和匿名内联框相同,计算方式也是相同的,span就是个命名的行内盒子。

替换元素

  替换元素的内容实际由该内联元素的属性提供,比如img标签的src属性,img标签会使用src属性指定的图片,替换该元素的位置。

关于替换元素各条线的位置,以img为例:

vertical-aligin:baseline | top | text-top | middle | text-bottom | bottom …

  • baseline:子元素盒子的baseline与父盒子的baseline对齐。
  • text-top 子元素盒子的顶部和行盒子里内容区域的顶部(text-top)对齐。
  • center子元素盒子垂直中点(替换元素 )与行盒子的baseline+字母 x 高度的一半对齐
  • top 将子元素盒子的顶部和其所在的line box顶部对齐
  • bottom和top类似,只不过是底端对齐

  行内盒子的vertical-align等于text-top或者text-bottom的时候依赖的是其父元素也就是行盒(line-boxes)的text-top和text-bottom位置,行盒的text-top和text-bottom线的位置则是由其父元素的font-size、font-family等属性决定的。而对于所有的行内盒子(line-box) 来说,在定位的时候其实都不需要知道他们的text-top和text-bottom这两个线的位置,因为行内盒子就是最小的元素,它没有子元素了,也就没有元素需要这两条线来确定位置了,或者说行内盒子没有这两条线都可以。

行内盒子最应该关心的线应该是 top、bottom、baseline和middle这四条线

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. 在没有流入内容的情况下(即替换元素例如img、canvas等等),基线边就是替换内容的底部边缘。

baseline 的位置
  在有子元素并且有内容的情况下,父元素(行盒)基线所在的位置是取在子元素还在默认位置时(可以理解为父元素中只有一个子元素时)他们的基线与父元素顶部距离最大的那个元素的基线位置(一般是最高的那个),其他同行元素相对于父元素的基线对齐。

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-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

CSS中的行盒(line-boxes)和行内盒子(line-box)相关推荐

  1. css中标签显示模式、块元素、行内元素、行内块元素、显示模式转换

    标签显示模式display: HTML标签一般分为块标签(块元素:block-level)和行内标签(行内元素:inline-level)两种类型,但是还有第三种说法行内块元素:table-row-g ...

  2. [译] 关于CSS中的float和position (父容器div内的子元素div为float时,父元素无法撑开(或高度自适应)的解决方式)

    测试案例:http://blog.csdn.net/goodshot/article/details/44408245 当构建页面排版时,有不同的方法可以使用.使用哪一种方法取决于具体页面的排版要求, ...

  3. html左浮动不管用图片往下放,html - 如何在HTML / CSS中水平对齐图像(浮动和显示内联块不起作用) - 堆栈内存溢出...

    我有一个水平排列的图像库,但是后来我做到了,以便当您将鼠标悬停在图像上时,图像上会覆盖文字,现在我以前没有什么东西可以用来使它们水平排列. 我尝试在所有选择器上使用左浮点数(同样使用display i ...

  4. CSS基础(9)- 行盒的盒模型

    本系列笔记是基于[渡一教育]袁进老师的html+css基础课程而记录,仅作为个人记录以及阅读使用. 文章目录 行盒的盒模型 显著特点 行块盒 空白折叠 可替换元素 和 非可替换元素 参考资料 行盒的盒 ...

  5. CSS 常用语法与盒模型分析

    CSS基础知识 CSS规则由两个主要的部分构成:选择器,以及一条或者多条声明 selector {property: value;property: value;... property: value ...

  6. 雪碧图的概念及优缺点,以及行盒的简述

    什么是雪碧图?它的优缺点是什么? 1.雪碧图的概念:实际是指CSS中的图片拼合技术,将多个背景图拼合在同一张图片上,在使用时按照需求对图片位置进行改动. 优点:当多个图片合成一张图片时,减少了加载网页 ...

  7. html 设置min height,CSS中min-height使用技巧

    DIV+CSS中最小高度设定min-height设定 最小高度可以设定一个BOX的最小高度,当其内容较少时时,也能保持BOX的高度为一定,超出就自动向下延伸,但到目前为止,只有Opera 和 Mozi ...

  8. 如何将php里面的首行缩进,如何实现首行缩进效果

    可以通过CSS中的text-indent属性来实现首行缩进效果 我们在写页面的时候,尤其是碰到那些文本内容过多导致页面效果不好看时,这时我们可以通过首行缩进的方法来使文章内容更加有层次感.我们可以通过 ...

  9. line boxes盒模型

    <p>这是一行普通的文字,这里有个 <em>em</em> 标签.</p> 这段html代码涉及4种boxes: 1.首先是p标签所在的containi ...

最新文章

  1. Apache Spark机器学习.1.7 机器学习工作流示例
  2. pandas.DataFrame.multiply()含义解释
  3. js+php在线截图 jquery fileupload.js,另一种图片上传 jquery.fileupload.js
  4. Java-命令行传递参数
  5. 类与对象的定义与使用小结 1114
  6. MacBook 没有响应的应用程序 CUH
  7. python 求组合数最快方法_快速计算投资组合波动率的方法
  8. 【毕业设计6】基于51单片机的红外避障小车
  9. 《软件过程管理》 第七章 软件过程的质量管理
  10. 程序员年薪30万,被准丈母娘各种刁难,网友说:分手吧!
  11. Html 排版与标签(一)
  12. 软件测试技术课后习题:第4章白盒测试-广东高等教育出版社,主编杨胜利
  13. 电商搜索里都有啥?详解闲鱼搜索系统(长文)
  14. 数据分析报告这样写,才算真正读懂了数据
  15. 占据栅格地图构建(Occupancy Grid Map)
  16. 用户划分——RMF方法
  17. 深度学习机器学习面试题——GAN
  18. MATLAB与C++的接口问题
  19. 15 三极管主要参数
  20. 怎么处理H5棋牌游戏app下载链接在微信中打不开或者显示已停止访问该网页

热门文章

  1. Word背景默认为绿色,如何更改默认为白色
  2. 计算机科学 在职双证,计算机在职研究生有双证吗
  3. 阿里云视频云正式支持AV1编码格式 为视频编码服务降本提效
  4. 网页左右两边加广告横幅
  5. c语言数组124048,根据GPS经纬度判断当前所属的市区
  6. 程序员眼中的中国传统文化-王阳明《传习录》29
  7. Duplicate entry ‘XXX‘ for key ‘XXX.PRIMARY‘解决方案。
  8. HEVC解码器HM源码阅读(三)读取一个NALU
  9. excel可以用python语言_用python打开excel的方法
  10. Kindle 通过邮箱发送电子书