写点什么

关于 CSS 排版,其实从毕升开始,我们就开始用正常流了

  • 2019-04-17
  • 本文字数:2063 字

    阅读完需:约 7 分钟

关于CSS排版,其实从毕升开始,我们就开始用正常流了

你好,我是 winter。这是我在极客时间《重学前端》专栏的第 24 篇文章「CSS的正常流」,今天分享给你。


我想,在 CSS 中,大家最讨厌的大概就是排版部分了。因为早年的 CSS 设计上不能够很好地支持软件排版需求,导致大家需要使用很多黑科技,让很多新人望而却步。现在 CSS 提供了很多种排版方式,我们有很多选项可以选择自己适合的那一种,然而,正常流却是我们绕不开的一种排版。


我们能够在网上看到关于正常流的各种资料,比如:块级格式化上下文、margin 折叠等等……这一系列的概念光是听起来就令人非常头痛。


很多同学一定会奇怪:正常流到底正常在哪里。事实上,正常流本身是简单和符合直觉的东西。我们之所以会觉得它奇怪,是因为如果我们从严苛的 CSS 标准角度去理解正常流,规定排版的算法,就需要引入上述那些复杂的概念。但是,如果我们单纯地从感性认知的层面去理解正常流,它其实是简单的。


下面,就让我们先抛弃掉所有的已知概念,从感性认知的角度出发,一起去理解一下正常流。

正常流的行为

首先,我们先从词源来讲一讲排版这件事。


在毕昇发明活字印刷之前,排版这项工作是不存在的,相应的操作叫做“雕版”。人们要想印刷书籍,就需要依靠雕版工人去手工雕刻印版。


活字印刷的出现,将排版这个词引入进来,排版是活字印刷的 15 道工序之一,不论是古代的木质活字印刷,还是近代的铅质活字印刷,排版的过程是由排版工人一个字一个字从字架捡出,再排入版框中。实际上,这个过程就是一个流式处理的过程。


从古代活字印刷开始,到现代的出版行业,再到今天的 Web,排版过程其实并没有什么本质的变化,只不过,今天在我们的 CSS 中,排版需要处理的内容,不再是简单的大小相同的木字或者铅字,而是有着不同字体和字号的富文本,以及插入在富文本中大小不等的盒。


并且,在这些过程中,都会有一个正常流的存在。那么,正常流是什么样的呢?


我们可以用一句话来描述正常流的排版行为,那就是:依次排列,排不下了换行。这个操作很简单吧,我想,任何一个不懂排版的人都会将其作为排版时的第一反应。


理解了正常流的基本概念,剩下的功能只需要在它的基础上延伸一下就好。


在正常流基础上,我们有 float 相关规则,使得一些盒占据了正常流需要的空间,我们可以把 float 理解为“文字环绕”。



我们又有 vertical-align 相关规则,规定了如何在垂直方向对齐盒。vertical-align 相关规则看起来复杂,但是实际上,基线、文字顶/底、行顶/底都是我们正常书写文字时需要用到的概念,只是我们平时不一定会总结它们。


除此之外,margin 折叠是很多人非常不理解的一种设计,但是实际上我们可以把 margin 理解为“一个元素规定了自身周围至少需要的空间”,这样,我们就非常容易理解为什么 margin 需要折叠了。

正常流的原理

我们前面描述了正常流的行为,接下来我们要切换一下模式,用比较严谨的姿势来理解一下正常流。


在 CSS 标准中,规定了如何排布每一个文字或者盒的算法,这个算法依赖一个排版的“当前状态”,CSS 把这个当前状态称为“格式化上下文(formatting context)”。


我们可以认为排版过程是这样的:


格式化上下文 + 盒/文字 = 位置


formatting context + boxes/charater = positions


我们需要排版的盒,是分为块级盒和行内级盒的,所以排版需要分别为它们规定了块级格式化上下文和行内级格式化上下文。


与正常流一样,如果我们单纯地看格式化上下文,规则其实是非常简单的。


块级格式化上下文顺次排列元素:



行内级格式化上下文顺次排列元素:



注意,块级和行内级元素的排版,受文字书写方向的影响,这里我们讲上下左右只是为了方便你直观理解。


当我们要把正常流中的一个盒或者文字排版,需要分成三种情况处理。


  • 一、当遇到块级盒:排入块级格式化上下文。

  • 二、当遇到行内级盒或者文字:首先尝试排入行内级格式化上下文,如果排不下,那么创建一个行盒,先将行盒排版(行盒是块级,所以到第一种情况),行盒会创建一个行内级格式化上下文。

  • 三、遇到 float 盒:把盒的顶部跟当前行内级上下文上边缘对齐,然后根据 float 的方向把盒的对应边缘对到块级格式化上下文的边缘,之后重排当前行盒。


我们以上讲的都是一个块级格式化上下文中的排版规则,实际上,页面中的布局没有那么简单,一些元素会在其内部创建新的块级格式化上下文,这些元素有:


  • 浮动元素;

  • 绝对定位元素;

  • 非块级但仍能包含块级元素的容器(如 inline-blocks, table-cells, table-captions);

  • 块级的能包含块级元素的容器,且属性 overflow 不为 visible。


这里的最后一条比较绕,实际上,我个人喜欢用另一种思路去理解它:


自身为块级,且 overflow 为 visible 的块级元素容器,它的块级格式化上下文和外部的块级格式化上下文发生了融合,也就是说,如果不考虑盒模型相关的属性,这样的元素从排版的角度就好像根本不存在。


好了,到这里我们已经讲完了正常流的排版详细规则,但是理解规则仅仅是基础,我们还需要掌握一些技巧。我在《重学前端》的第24讲,对正常流的使用技巧,给出了详细的解答。


拓展阅读:


JavaScript词法:为什么12.toString会报错?


一个浏览器是如何工作的?


2019-04-17 15:494319

评论

发布
暂无评论
发现更多内容

阿里P8耗时半年总结的Java核心面试知识,助我轻松拿下蚂蚁offer

Java 程序员 面试 java编程 java技术宅

数字经济时代,国家与国家的核心竞争力就是算力

CECBC

分布式认知工业互联网

CECBC

多维数据分析(OLAP)技术选型(1):对什么进行选型

水滴

OLAP 通信协议 技术选型 多维分析 存储格式

排序——插入排序

若尘

数据结构 排序 排序算法 插入排序

并发王者课-铂金8:峡谷幽会-看CyclicBarrier如何跨越重峦叠嶂

MetaThoughts

Java 并发 多线

iOS开发 · iOS音视频开发 - ARKit 教学:如何搭配SceneKit来建立一个简单的ARKit Demo

iOSer

ios ios开发 ARKit iOSAR.

一文讲懂Hive高可用、HiveServer2高可用及Metastore高可用

白贺BaiHe

数据仓库 7月日更 HiveServer2高可用 Metastore高可用 Hive高可用

Rust从0到1-Cargo-安装来自Crates.io的程序

rust cargo install

涨薪50%,从小厂逆袭,坐上美团L8技术专家(面经+心得)

Java 编程 程序员 面试

iOS不行?还是个人能力有限?

ios 程序员 IT 编程之路

Ubuntu Server 20.04安装KVM虚拟机

玏佾

ubuntu 虚拟机 Ubuntu20.04 kvm

为什么nginx主机的io使用率会100%?

BUG侦探

nginx proxy_buffering docker镜像

架构实战营 模块一作业

面向对象的猫

「架构实战营」

CloudQuery 使用教程 No.4 数据查询(下)

BinTools图尔兹

dba 数据库管理工具 国产数据库 运维开发

CDH安装搭建(一)

大数据技术指南

CDH 7月日更

双非小伙暑期实习斩获腾讯WXG offer,这不比博人传燃?

北游学Java

Java 腾讯 面试

必看!史上最全云原生全景图解读攻略来啦

尔达Erda

容器 微服务 运维 云原生 技术人

疯了吧!这帮人居然用 Go 写“前端”?(一)

尔达Erda

开发者 云原生 大前端 后端 开发

不愧是阿里内部“SpringCloudAlibaba学习笔记”竟然在GitHub霸榜月余

Java 编程 架构 微服务

并发王者课-铂金7:整齐划一-CountDownLatch如何协调多线程的开始和结束

MetaThoughts

Java 多线程 并发

动手训练属于自己的无人车,这个超强服务现已开源!

亚马逊云科技 (Amazon Web Services)

架构实战营模块1课后作业

蔸蔸

模块2作业

cherrycheek

并发王者课-铂金6:青出于蓝-Condition如何把等待与通知玩出新花样

MetaThoughts

Java 多线程 并发

合肥智慧社区平台建设解决方案,平安小区建设

论文解读丨文档结构分析

华为云开发者联盟

模型 文档 文档结构分析 分割 文档结构

阿里技术分享:闲鱼IM基于Flutter的移动端跨端改造实践

JackJiang

flutter 即时通讯 IM

Flink 的底层API

五分钟学大数据

flink 7月日更

基于MaxCompute快速打通数据仓库和数据湖的湖仓一体实践

阿里云大数据AI技术

GrowingIO Design 组件库搭建之Select组件

GrowingIO技术专栏

select 组件实现 virtualList

关于CSS排版,其实从毕升开始,我们就开始用正常流了_大前端_程劭非_InfoQ精选文章