首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

(7)CSS 基本视觉格式化——①“块盒子”格式化

本知识学习用时:3小时,总第38/10000小时

前言:接下来的 9 篇系列文章我们讲一个东西:盒子(BOX)。

“盒模型(box model)”作为 CSS 看待元素的一种方式,CSS 将每个元素都看作由一个盒子表示。从某方面来说,对于初级、中级学习者的我们,大可将 CSS 的学习看作是对“盒子”的学习。

为什么这么说?请看下图我个人的 CSS 学习流程:

图中我们可以看到,几乎所有的内容都是围绕着“盒子”这个东西在展开

本篇我们将阐述最基本的理论知识,将“盒子”的方方面面一步步带到我们跟前。

一、什么是“盒子” ?

“盒子 box”由 CSS 引擎根据文档中的内容所创建,主要用于文档元素的格式化、定位和布局等用途。

盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。

一个完整的“盒子”中心有一个内容区(content area)。这个内容区周围有可选的 padding、边框和 margin。这些项之所以被认为是可选的,是因为它们的宽度可以设置为 0,实际上就是从“盒子”上去除这些项。

一个完整的“盒子”

二、“视觉格式化模型”概述

CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。

通俗的讲就是:页面(文档树)可以想象成是由一个个 box 组合而成的,而“视觉格式化模型(Visual formatting model)” 是一套规则,将这些 box “布局”成访问者看到的样子。

每个盒子的“布局”由以下因素决定(本篇文章和下一篇文章主要讲解第①、②点,其属于“最基本的视觉格式化”,而对于剩下的要点,我们在接下来的系列文章中会挨个讨论):

① 盒子的尺寸:精确指定、由约束条件指定或没有指定;

② 盒子的类型:行内盒子(inline box)、行内级盒子(inline-level box)、原子行内级盒子(atomic inline-level box)、块盒子(block box);

③ 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位;

④ 文档树中的其它元素:即当前盒子的子元素或兄弟元素;

⑤ 视口尺寸与位置;

⑥ 所包含的图片的尺寸;

⑦ 其他的某些外部因素。

每一个元素都是一个“盒子”,“盒子”可以嵌套“盒子”

如上图所示,视觉格式化模型会根据盒子的“包含块(containing block)——包含其他盒子的块称为包含块”的边界来渲染盒子。通常,盒子会创建一个包含其后代元素的“包含块”,但是盒子并不由“包含块”所限制,当盒子的布局跑到”包含块“的外面时称为溢出(overflow)。

上图中,section 的包含块是 body ,deader、article、footer 的包含块是 section。

⚠️小总结:“盒子模型”是处理盒子本身的内部属性——边距、边框等,而“视觉格式化模型”是用来处理这些盒子的摆放。

三、关于“盒子”我们一定需要知道的——基本视觉格式化

1. “盒子”的生成:

盒子的生成是 CSS 视觉格式化模型的一部分,用于从文档元素生成盒子。

盒子有不同的类型,盒子的类型取决于 CSS 的 display 属性——元素“角色”的改变:

① “块级元素”和“块级盒子”

设置元素的 display 为block、list-item或table时,该元素将成为“块级元素”。

这些元素在正常流中时,会在其框之前和之后生成“换行”,所以处于正常流中的块级元素会垂直摆放。

(“正常流”是指:西方语言文本从左向右、从上向下显示的方向,这也是我们熟悉的传统HTML文档的文本布局方向。注意,在非西方语言中,流方向可能不同。)

但,元素是否是“块级元素”仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。

一个“块级元素”会被格式化成一个块(例如文章的一个段落),且默认按照垂直方向依次排列。

一个“块级元素”都会至少生成一个“块级盒子”,也有可能生成多个(例如列表项元素)。而“块级盒子”才会参与“块格式化上下文(block formatting context)”的创建。

② “行内级元素”和“行内盒子”

当元素的 display 属性为inline、inline-block或inline-table时,该元素将成为“行内级元素”。

这些元素不会在之前或之后生成“行分隔符”,它们是块级元素的后代。

显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。

同理,“行内级元素”会生成“行内级盒子”,该盒子同时会参与“行内格式化上下文(inline formatting context)”的创建。

⚠️小总结:相对更详细的“盒子”细分:

⚠️注意:一定要记得的是,display 之所以得名,是因为它影响的是元素如何“显示”,而不影响他本质上是何种元素,也就不能乱玩“嵌套关系”!一个极端的反例就是:你不能让一个“链接”来包围一个“段落”。

(对于生成不同类型“盒子”在实际项目中的运用,我们将在后续文章详细讨论。例如:怎样给“链接”加样式——生成导航栏、怎样给“表单”加样式等。)

2. 不同类型“盒子”在格式化方式上也有所不同:

本篇我们主要探讨 “块盒子”格式化,下篇文章讨论“行内盒子”格式化。

块盒子

-- 水平格式化

正常流中,“块盒子”的水平部分 = 其父元素的 width =7 个属性之和——(margin-left➕margin-right) ➕ (padding-left➕padding-right)➕(border-left➕border-right)➕内容区自身 width 。

在这 7 个属性中只有 3 个的值可以设置为 auto:width、margin-left、margin-right。其余的要不必须是确定的值,要不就是默认值 0。

可详细分为以下 5 种组合:

3 个都不是 auto:按 CSS 的术语来讲,这叫“格式化属性过分受限”,此时总会把 margin-right 强制为 auto 来适应父元素的宽度;

2个不是 auto:是 auto 的将自动调整到适应父级元素的宽度;

margin-left、margin-right 是 auto:他们会自动设置为相等的长度,导致此元素在其父级元素中居中;

一个 margin 和 width 是auto:auto 的 margin 会减为0,width 自动填充其包含块;

3 个都是 auto:两个外边距减为 0,width 会尽可能的宽(自动充满)。

⚠️注意:由于水平 margin 不会合并,父元素的 padding、边框、margin 可能会对子元素带来“偏移”的影响。

-- 垂直格式化

垂直格式化的另一个重要方面是垂直相邻 margin 的合并。

这种合并行为只应用于 margin,如果元素有 padding 和边框,padding 和边框是不会合并的。当两个或更多垂直 margin 相遇时,他们将形成唯一一个 margin,这个 margin 的高度等于两个发生叠加的 margin 的高度中的较大者。

⚠️注意:当一个元素包含在另一个元素中时,彼此相邻的 top 和 bottom margin 也会发生叠加,取较大者。

-- 负 margin

提问:水平或垂直方向各自 7 大属性相加要等于父元素的 width 或 height,那 margin 为负值会造成什么结果?

水平方向:

html

css

-- 类型①

-- 类型②

-- 类型③

垂直方向:

-- 类型 ①:负 margin-top

html

css

把段落1的 margin-top 设为“负”,它就被向上“拉”了 20 像素,且紧挨它的段落2也相应向上拉了 20 像素。

css

-- 类型 ③:正负 margin 合并

"块盒子“重叠的时候,如果垂直 margin 都为负值,浏览器会取两个 margin 绝对值的最大值;如果一个正 margin 与一个负 margin 合并,则会从正 margin 减去这个负 margin 的绝对值。

html

css

ul 和 p 重叠的 margin 都为“负”,则取绝对这较大者(-18px)

当上边的较大者(-18px)增加到 li 的最大正 margin 上(20px)时,就得到了 20px - 18px =2px

后记:这篇我们学习了“块盒子”的格式化方式,下一篇我们接着这篇继续探讨“行内盒子”的格式化方式。在“行内盒子”格式化方式中,我们会谈到很多细小的基础知识,和本篇的学习方式一样,让我们尽可能的用代码、用图片来攻克它们。

欢迎继续关注下文 :

(8)CSS 基本视觉格式化——② “行内盒子”格式化

(本文版权归 “公号 | Oli的前端一万小时” 所有,转载需说明来源)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180609G1MEC800?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券