CSS 排版与正常流 —— 重学CSS

CSS 排版与正常流 —— 重学CSS

盒 ( Box )

讲到排版,我们需要引入的第一个概念就是 “”。之前我们在《模拟浏览器》和之前的一些 CSS 的文章中都讲到了排版相关的概念。

而我们真正去讲到排版的时候,我们需要用到的单位一定就是 “”。

在真正进入详细了解 “盒” 的概念之前,我们先来做认识一下 3 个比较容易混交的概念。

  1. 标签 ( Tag ) —— 源代码
  2. 元素 (Element) —— 语义
  3. 盒 ( Box ) —— 表现

HTML 代码中可以书写开始,结束,和自封闭。

标签是一个源代码的概念,所以方式我们提到在 HTML 代码中写的肯定都是标签。

一对起止,表示一个。

元素是存在我们脑子里的一个概念,它是语义领域的一个概念,所以一对起止标签它一定是表示一个我们脑子里面的概念。

DOM 树中存储的是和其他类型的节点 ( Node )。

DOM 树中存储的不全是元素,因为DOM 树中存储的东西叫节点 ,所以元素只是是节点的一种。

比如说我们的文本节点也是节点,但他并不是元素。再比如我们的注释节点,它也是节点但是它也不是元素。当然还有 CDATA 节点,还有 processing-instruction,DTD等这些都是会存入 DOM 树的,当时它们都并不是元素。

很多同学的理解,DOM 树中存储的都是元素,不过这样也没有错。因为其他的节点相对来说都没有那么重要。

CSS 选择器中的是。

其实这里还可以加一个 “或”,在《CSS 选择器》中讲到的,CSS 选择器选中的是元素或者是。

CSS 选择器中的,在排版时可能产生多个。

这个地方是大家需要注意到的一个概念,CSS 选择器选中的元素,它不一定和盒是一一对应的关系。它有可能是一对多的关系的。但是有盒一般来说必定是有对应的元素的。我们不可能无中生有产生一个元素,即使是号称是无中生有的伪元素也是依附于一个选中的元素产生的。

排版和渲染的基本单位是

在我们的《模拟浏览器》的实现过程中,我们的排版盒渲染都是直接拿元素当盒去用了。但是这是一个很粗糙的做法,在实际上我们很多元素都会产生多个盒。

比如说 元素就会因为分行而产生多个盒。又比如说带有伪元素,被伪元素选择器选中的元素也会生成多个盒。所以我们排版盒渲染的基本单位都是盒

CSS 排版与正常流 —— 重学CSS
  • padding 主要影响的是盒内的空间 —— 主要决定盒内的空间排布,也就是 content 区域的大小
  • margin 主要影响的是盒外的空间 —— 决定了盒周围空白区域的大小

盒模型里面的 宽 (width) 是有讲究的,盒子的宽度是有可能被 属性所影响的。最常见的两个值就是:

content-box

设置的 属性只包含 的内容的空间。也就是说:

= + + +

CSS 排版与正常流 —— 重学CSS

border-box

使用,我们的 width 就包含了 padding 和 border 的尺寸了。回去看看我们盒模型的图,我们可以看到的黄色线括着的区域,它所占据的空间和范围。

这样当我们给一个盒,padding 和 border 的时候,就不会影响我们给予盒子的 width。这样我们就可以保证我们盒子在没有 margin 的时候它所占据的空间就是与我们 width 一致的。

呈现出来的效果就是 padding 和 border 都会往内挤压空间,而不会影响盒子的宽度。

这里我们就讲完盒模型了,我们就发现它所影响的属性就是 ,,,这几个属性。这些都是影响我们盒模型的总体尺寸,在排版中会影响着这个盒模型所占据的范围。

CSS 排版与正常流 —— 重学CSS

如果我们看到上面这个图,可能有一些同学知道是什么,有一些同学完全不知道他在干什么。其实这个就是 80 年代印刷厂工人在进行排版工作。

这个传统的排版技术,其实与我们现在网页的是息息相关的。在很多文章中,我们会把翻译成,有时候也会翻译成。但是我个人也觉得翻译成是最贴切的。因为 CSS 当中的是源自于传统的排版技术。

传统的排版方式,我们需要先把字版放入一个一个字框里面,按照文字的顺序排列号,然后再把这些字框一个一个的排列进我们的排版框里面。

所以所谓排版就给我们所有可见的东西放到正确的位置上去。而在 HTML 里面,我们是有 “盒” 这样一个东西,在 CSS 的排版里我们。

  1. 文字

一切 CSS 的排版,都不会逃出这与这样两东西。所以我们的排版就是给每一个文字安排到正确的位置上,然后给每一个盒安排到正确的位置上。

在不考虑盒模型的情况下,我们需要关注的就是位置和尺寸,所以排版中并没有什么特殊的内容。

字排版

CSS 排版与正常流 —— 重学CSS

很负责任的告诉大家,其实一点都不奇怪。如果我们知道前端的 HTML 和 CSS 的排版概念都是源自于专业排版知识,而这些排版使用方式如果出现在我们的书籍里面,我们都会觉得挺自然的。但是真正让我们去理解这些知识,我们都会觉得很困难。

这个就可以追溯到 HTML 最早期整个的排版设计,都是从文字出版行业过来的专家所做的。所以它使用的思路都是那个时代的一个专业的思路。跟我们自然人脑子里面的理解,可能就会有一些差异了。

正常流排版

接下来我们就正式进入正常流的排版讲解。

正常流排版的整个过程,与实现 flex 的过程比较类似,有这几个步骤:

  • 收集盒与文字进行
  • 计算盒与文字在行中的排布
  • 计算行与行之间的排布

我们发现其实这个与我们 flex 的排版非常的像。其实我们会发现所有的排版算法,基本上都是差不多的。不论是哪个软件,哪个规则,它们都是这么几个步骤。

接下来我们来看看具体的一个排布规则:

CSS 排版与正常流 —— 重学CSS
  • 块级排布的我们就叫 —— Block level formatting context (块级格式化上下文)
  • 行内排布的我们就叫 —— Inline level formatting context (行内级格式化上下文)

很多在比较早期学习前端,甚至在一些 “0 基础” 的班里面学前端的同学,都会听说过 “块级元素” 和 “行内元素” 两种说法。其实与我们讲到的 BFC 和 IFC 就是这个概念最原本的意思。

行级排布

CSS 排版与正常流 —— 重学CSS

首先我们看到 ,也就是一个字体的原点。而原点标识的位置就是我们文字的基线的位置,而这个文字都是以基线作为原点的坐标,然后再用这个坐标来定义这个文字的位置。

所以说基线就是在 这个横向的坐标,然后这个文字就会有一个 和一个 , 就是文字最尾端的坐标位置,而 就是文字最顶端的位置。

然后文字也有相反的两个值 和 ,而这两个值就是刚好相反,是文字开始的位置和底部的位置。

也可以理解为从底缘的基线到文字的最顶端的距离,这就是 。而底缘的基线到文字的最底端的距离就是 。而 到 ,从原点到文字开始和文字结束的距离。

最后这里面的 就是整个字占用的空间。

以上讲的就是横向排版的时候,而纵排又有另外一套的逻辑:

CSS 排版与正常流 —— 重学CSS

我们大致了解了这个文字在字体里面是如何定义之后,我们就可以来讲讲 CSS 里面的行模型了。这里我们重点讲 5 条线,其他还有一些线和位置例如 和 这种我们就不去讲了。

这个 base-line 和文字的顶原和底缘,分别叫做 、 和 。就是图中的一条黄线和两条绿线。

结合刚刚讲到的, 就是用来与英文字母对齐的。然后这里面有一个 和一个 ,如果我们的字体大小不变,这两个线是不会变得。

如果我们使用多个文字的字体混排的话,这个 和 是由 最大的一个字体决定的。然后这个文字的上缘和下缘可以理解为两条固定的线。

如果行高是大于文字的高度的时候,我们就会有 和 ,就是在图中的两条白色的线。

好!如果我们只有文字的话,这个行模型就这样子排布的。但是我们一旦涉及到跟盒的混排,就会涉及到一个 和 的偏移问题。

CSS 排版与正常流 —— 重学CSS

最后呈现出来的效果如下:

CSS 排版与正常流 —— 重学CSS

这里我们会发现盒子的对齐的位置发生了变化。盒的基线变成了它里面文字的最后一行的基线。也就是说,当一个盒子里面有文字的时候,这个盒子的对齐就会基于里面文字的基线做对齐。

这里如果我们在 的下一行加一个文字 ,我们又会发现另一种现象。

CSS 排版与正常流 —— 重学CSS

这个是特别需要注意的问题,行内盒 的基线是随着自己里面的文字去变化的。所以说大部分情况下是不建议大家给行内盒使用基线对齐的。

所以我们在使用的时候就需要给一个 ,属性值我们可以给 ,或者是都是可以的。

我们先看看 —— 顶缘对齐

div class="wrapper">   div class="base-line">     div>div>  div>  span class="

来源:三钻

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年9月12日
下一篇 2020年9月12日

相关推荐