元数据

深入解析CSS

  •  深入解析CSS|200
  • 书名: 深入解析CSS
  • 作者: 基思·J.格兰特
  • 简介: 作者对前端和后端的工作都十分了解,并拥有十余年CSS实战经验。在就职过的每一家公司,他都是非常重要的CSS导师。对于想要精通CSS的人而言,这本书是一张宝贵的“地图”,覆盖了CSS世界的大部分“疆土”,从CSS基础知识开始(如层叠、优先级、继承、相对单位、盒模型等),到多种布局(如浮动布局、Flexbox、网格布局、响应式设计等),再到大型应用程序中的CSS(如模块化CSS和模式库),最后是关于CSS的高级话题(如背景、阴影和混合模式,对比、颜色和间距,以及排版、过渡、变换、动画等)。
  • 出版时间 2020-04-09 00:00:00
  • ISBN: 9787115533760
  • 分类: 计算机-计算机综合
  • 出版社: 人民邮电出版社
  • PC地址:https://weread.qq.com/web/reader/7d53223071e219457d53617

高亮划线

📌 就像黑白棋一样,学会CSS的规则并不难。你只需要写一个选择器尝试匹配元素,然后写一些键/值对给元素添加样式即可。即使是新手也能轻松理解该基础语法。但要精通 CSS,难在需要知道在何时做何事。 ⏱ 2020-12-10 23:43:01

关于本书

📌 本书的源码放在git仓库(http://github.com/CSSInDepth/css-in-depth)以及Manning出版社网站(http://manning.com/books/css-in-depth)中。 ⏱ 2020-12-10 23:43:40

第1章 层叠、优先级和继承

📌 它不是编程语言,却要求抽象思维。它不是纯粹的设计工具,却要求创造力 ⏱ 2020-12-10 23:45:47

📌 在CSS中,却很难将问题提炼成一句话。即使可以,答案一般也是“这得看情况”。最好的解决办法通常取决于具体场景,以及你希望以多大粒度处理各种边缘情况。 ⏱ 2022-07-06 21:07:47

1.1 层叠

📌 在CSS里实现一个效果通常有好几种方式。当HTML结构变化,或者将同一份样式表应用到不同的网页时,不同的实现方式会产生不同的结果。CSS开发很重要的一点就是以可预测的方式书写规则。 ⏱ 2020-12-10 23:46:56

📌 如果你发现有一条规则没有按照预期生效,可能是因为另一条规则跟它冲突了。要想预测规则最终的效果,就需要理解CSS里的层叠。 ⏱ 2020-12-10 23:47:10

📌 它包含三个规则集,每一个给网页标题指定了不同的字体样式。 ⏱ 2020-12-10 23:48:15

📌 层叠指的就是这一系列规则。它决定了如何解 ⏱ 2020-12-10 23:48:46

📌 当声明冲突时,层叠会依据三种条件解决冲突。 (1) 样式表的来源:样式是从哪里来的,包括你的样式和浏览器默认样式等。 (2) 选择器优先级:哪些选择器比另一些选择器更重要。 (3) 源码顺序:样式在样式表里的声明顺序。 ⏱ 2020-12-10 23:48:58

📌 选择器和声明块一起组成了规则集(ruleset)。一个规则集也简称一个规则, ⏱ 2020-12-10 23:54:34

📌 @规则(at-rules)是指用“@”符号开头的语法。比如@import规则或者@media查询。 ⏱ 2020-12-10 23:54:44

📌 你的样式表属于作者样式表,除此之外还有用户代理样式表 ⏱ 2020-12-10 23:56:01

📌 浏览器应用了用户代理样式后才会应用你的样式表,即作者样式表。你指定的声明会覆盖用户代理样式表里的样式。如果你在HTML里面链接了多个样式表,那么它们的来源都相同,即作者 ⏱ 2020-12-10 23:57:52

📌 你可能注意到我用了ID选择器,但应该避免使用这种选择器,稍后会做出解释。 ⏱ 2020-12-10 23:58:37

📌 样式来源规则有一个例外:标记为重要(important)的声明。 ⏱ 2020-12-10 23:58:49

📌 标记了!important的声明会被当作更高优先级的来源 ⏱ 2020-12-10 23:58:53

📌 如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级 ⏱ 2020-12-10 23:59:22

📌 浏览器将优先级分为两部分:HTML的行内样式和选择器的样式。 ⏱ 2022-08-01 10:13:45

📌 行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者

📌 为了在样式表里覆盖行内声明,需要为声明添加!important,这样能将它提升到一个更高优先级的来源 ⏱ 2020-12-11 00:03:27

📌 有两个类名的选择器比只有一个类名的选择器优先级更高 ⏱ 2020-12-11 00:03:55

📌 ID选择器的优先级比拥有任意多个类的选择器都高。同理,类选择器的优先级比标签选择器(也称类型选择器) ⏱ 2020-12-11 00:04:37

📌 ❑ 如果选择器的ID数量更多,则它会胜出(即它更明确)。 ❑ 如果ID数量一致,那么拥有最多类的选择器胜出。 ❑ 如果以上两次比较都一致,那么拥有最多标签名的选择器胜出。 ⏱ 2020-12-11 00:04:56

📌 伪类选择器(如:hover)和属性选择器(如[type=“input”])与一个类选择器的优先级相同。通用选择器(*)和组合器(>、+、~)对优先级没有影响。 ⏱ 2020-12-11 00:05:30

📌 比如,“1,2,2”表示选择器由1个ID、2个类、2个标签组成。优先级最高的ID列为第一位,紧接着是类,最后是标签。 ⏱ 2020-12-11 00:05:59

📌 代表一个声明是否是用行内样式添加的。此时,行内样式的优先级为“1,0,0,0”。 ⏱ 2020-12-11 00:06:42

📌 通过这些例子可以发现,优先级容易发展为一种“军备竞赛”。在大型项目中这一点尤为突出。通常最好让优先级尽可能低,这样当需要覆盖一些样式时,才能有选择空间。 ⏱ 2020-12-11 00:09:00

📌 如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。 ⏱ 2020-12-11 00:09:07

📌 也就是说,可以通过控制源码顺序,来给特殊链接添加样式。如果两个冲突选择器的优先级相同,则出现得较晚的那个胜出。 ⏱ 2020-12-11 00:09:23

📌 面对一个样式问题时,我经常分两个步骤来解决它。首先确定哪些声明可以实现效果。其次,思考可以用哪些选择器结构,然后选择最符合需求的那个。 ⏱ 2020-12-11 00:14:01

📌 优先级相同时,后出现的样式会覆盖先出现的样式。 ⏱ 2020-12-11 00:15:38

📌 如果一个元素同时处于两个或者更多状态,最后一个状态就能覆盖其他状态。 ⏱ 2020-12-11 00:15:49

📌 这个顺序的记忆口诀是“LoVe/HAte”(“爱/恨”),即link(链接)、visited(访问)、hover(悬停)、active(激活) ⏱ 2020-12-11 00:16:10

📌 浏览器遵循三个步骤,即来源、优先级、源码顺序,来解析网页上每个元素的每个属性 ⏱ 2020-12-11 10:16:48

📌 如果CSS为同一个属性指定了不同的值,层叠最终会选择一个值来渲染元素,这就是层叠值。 ⏱ 2020-12-11 10:17:13

📌 当创建一个用于分发的JavaScript模块(比如NPM包)时,强烈建议尽量不要在JavaScript里使用行内样式。如果这样做了,就是在强迫使用该包的开发人员要么全盘接受包里的样式,要么给每个想修改的属性加上!important。 ⏱ 2020-12-21 14:43:39

1.2 继承

📌 如果一个元素的某个属性没有层叠值,则可能会继承某个祖先元素的值 ⏱ 2020-12-11 10:18:53

📌 但不是所有的属性都能被继承。默认情况下,只有特定的一些属性能被继承,通常是我们希望被继承的那些。它们主要是跟文本相关的属性:color、font、font-family、font-size、font-weight、font-variant、font-style、line-height、letter-spacing、text-align、text-indent、text-transform、white-space以及word-spacing。 ⏱ 2020-12-11 10:19:10

📌 靠近顶部的样式会覆盖下面的样式。被覆盖的样式上划了删除线。 ⏱ 2020-12-11 10:21:45

1.3 特殊值

📌 有两个特殊值可以赋给任意属性,用于控制层叠:inherit和initial。我们来看看这两个特殊值。 ⏱ 2020-12-11 10:32:08

📌 有时,我们想用继承代替一个层叠值。这时候可以用inherit关键字。可以用它来覆盖另一个值,这样该元素就会继承其父元素的值。 ⏱ 2020-12-11 10:22:42

📌 有时,你需要撤销作用于某个元素的样式。这可以用initial关键字来实现。每一个CSS属性都有初始(默认)值。如果将initial值赋给某个属性,那么就会有效地将其重置为默认值,这种操作相当于硬复位了该值。图1-11展示了给页脚链接赋以initial而不是inherit时的效果。 ⏱ 2020-12-11 10:33:52

📌 实际上,用width: auto是一样的,因为width的默认值就是auto。 ⏱ 2020-12-11 10:34:17

📌 但是要注意,auto不是所有属性的默认值,对很多属性来说甚至不是合法的值。比如border-width: auto和padding: auto是非法的,因此不会生效。可以花点时间研究一下这些属性的初始值,不过使用initial更简单。 ⏱ 2020-12-11 10:34:23

📌 声明display: initial等价于display: inline。不管应用于哪种类型的元素,它都不会等于display: block。这是因为initial重置为属性的初始值,而不是元素的初始值。inline才是display属性的初始值。 ⏱ 2020-12-11 10:35:39

1.4 简写属性

📌 这样做仍然会设置省略的值,即它们会被隐式地设置为初始值。这会默默覆盖在其他地方定义的样式。比如,如果给网页标题使用简写属性font时,省略font-weight,那么字体粗细就会被设置为normal ⏱ 2020-12-11 10:42:37

📌 在所有的简写属性里,font的问题最严重,因为它设置的属性值太多了。因此,要避免在元素的通用样式以外使用font。 ⏱ 2020-12-11 10:43:08

📌 简写属性会尽量包容指定的属性值的顺序。可以设置border: 1px solid black或者border: black 1px solid,两者都会生效。这是因为浏览器知道宽度、颜色、边框样式分别对应什么类型的值。但是有很多属性的值很模糊。在这种情况下,值的顺序很关键。理解这些简写属性的顺序很重要 ⏱ 2020-12-11 10:45:16

📌 这种模式下的属性值还可以缩写。如果声明结束时四个属性值还剩一个没指定,没有指定的一边会取其对边的值。指定三个值时,左边和右边都会使用第二个值。指定两个值时,上边和下边会使用第一个值。如果只指定一个值,那么四个方向都会使用这个值。 ⏱ 2020-12-11 10:47:29

📌 这些属性包括background-position、box-shadow、text-shadow(虽然严格来讲它们并不是简写属性)。 ⏱ 2020-12-11 10:48:48

📌 而background-position: 25% 75%则先指定水平方向的右/左属性值,然后才是垂直方向的上/下属性值。 ⏱ 2020-12-11 10:48:51

📌 如果属性需要指定从一个点出发的两个方向的值,就想想“笛卡儿网格”。如果属性需要指定一个元素四个方向的值,就想想“时钟”。 ⏱ 2020-12-11 10:49:27

第2章 相对单位

📌 说起给属性指定值,CSS提供了很多选项。人们最熟悉同时也最简单的应该是像素单位(px)。它是绝对单位,即5px放在哪里都一样大。而其他单位,如em和rem,就不是绝对单位,而是相对单位。相对单位的值会根据外部因素发生变化。 ⏱ 2020-12-11 10:54:38

2.1 相对值的好处

📌 我们无法根据理想的条件给元素添加样式,而是要设置无论元素处于任意条件,都能够生效的规则。 ⏱ 2020-12-11 10:56:02

📌 相对单位就是CSS用来解决这种抽象的一种工具。我们可以基于窗口大小来等比例地缩放字号,而不是固定为14px,或者将网页上的任何元素的大小都相对于基础字号来设置,然后只用改一行代码就能缩放整个网页。下面来看看CSS是如何实现这些功能的 ⏱ 2020-12-11 10:57:15

📌 设计师经常用点作为单位 ⏱ 2020-12-11 10:57:49

2.2 em和rem

📌 在CSS中,1em等于当前元素的字号,其准确值取决于作用的元素 ⏱ 2020-12-11 10:58:13

📌 这里设置内边距的值为1em。浏览器将其乘以字号,最终渲染为16px。这一点很重要:浏览器会根据相对单位的值计算出绝对值,称作计算值(computed value ⏱ 2020-12-11 10:58:41

📌 当设置padding、height、width、border-radius等属性时,使用em会很方便。这是因为当元素继承了不同的字号,或者用户改变了字体设置时,这些属性会跟着元素均匀地缩放。 ⏱ 2020-12-11 10:59:02

📌 这个font-size是根据继承的字号来计算的 ⏱ 2020-12-11 11:03:30

📌 如果知道字号的像素值,但是想用em声明,可以用一个简单的公式换算:用想要的像素大小除以父级(继承)的像素字号。 ⏱ 2020-12-11 11:04:20

📌 现在你已经用em定义了字号(基于继承的字号),而且也用em定义了其他属性,比如padding和border-radius(基于当前元素的字号)。em的复杂之处在于同时用它指定一个元素的字号和其他属性。这时,浏览器必须先计算字号,然后使用这个计算值去算出其余的属性值。这两类属性可以拥有一样的声明值,但是计算值不一样。 ⏱ 2020-12-11 11:09:35

📌 当列表多级嵌套并且给每一级使用em定义字号时,就会发生文字缩小的现象。代码清单2-7和代码清单2-8的例子里,设置无序列表的字号为0.8em。选择器选中了网页上每个

    元素,因此当这些列表从其他列表继承字号时,em就会逐渐缩小字号。 ⏱ 2020-12-11 11:10:35 ^31594821-20-6289-6413

📌 当浏览器解析HTML文档时,会在内存里将页面的所有元素表示为DOM(文档对象模型)。 ⏱ 2020-12-11 11:13:40

📌 根节点有一个伪类选择器(:root),可以用来选中它自己 ⏱ 2020-12-11 11:13:59

📌 rem是root em的缩写。rem不是相对于当前元素,而是相对于根元素的单位 ⏱ 2020-12-11 11:17:02

📌 在这个例子里,根元素的字号为浏览器默认的字号16px(根元素上的em是相对于浏览器默认值的) ⏱ 2020-12-11 11:17:16

📌 在CSS里,答案通常是“看情况”。 ⏱ 2020-12-11 11:15:01

📌 我一般会用rem设置字号,用px设置边框,用em设置其他大部分属性,尤其是内边距、外边距和圆角(不过我有时用百分比设置容器宽度)。 ⏱ 2020-12-11 11:15:28

📌 用rem设置字号,用px设置边框,用em设置其他大部分属性。 ⏱ 2020-12-11 11:15:52

2.3 停止像素思维

📌 1.2em到底是多少像素并不重要,重点是它比继承的字号要稍微大一点。如果在屏幕上的效果不理想,就调整它的值,反复试验。这种方式同样适用于像素值 ⏱ 2020-12-11 11:20:01

📌 相反,我建议先适应使用em。如果已经习惯了像素,那么使用em可能需要反复练习,但这一切是值得的。 ⏱ 2020-12-11 11:20:12

📌 更进一步地说,我们甚至可以根据屏幕尺寸,用媒体查询改变根元素的字号 ⏱ 2020-12-11 11:36:18

📌 媒体查询,即@media规则,可以指定某种屏幕尺寸或者媒体类型(比如,打印机或者屏幕)下的样式。这是响应式设计的关键部分。 ⏱ 2020-12-11 11:36:36

2.4 视口的相对单位

📌 前面介绍的em和rem都是相对于font-size定义的,但CSS里不止有这一种相对单位。还有相对于浏览器视口定义长度的视口的相对单位。 ⏱ 2020-12-11 11:53:44

📌 ❑ vh:视口高度的1/100。❑ vw:视口宽度的1/100。❑ vmin:视口宽、高中较小的一方的1/100(IE9中叫vm,而不是vmin)。❑ vmax:视口宽、高中较大的一方的1/100(本书写作时IE和Edge均不支持vmax)[插图]。 ⏱ 2020-12-11 11:55:35

📌 如果能够保留这种缩放的能力,但是让极端情况缓和一些就更棒了。CSS的calc()函数可以提供帮助。 ⏱ 2020-12-11 11:58:39

📌 这段代码保证基础字号从iPhone 6里的11.75px一直过渡到1200px的浏览器窗口里的20px。 ⏱ 2020-12-11 12:01:52

📌 我们不用媒体查询就实现了大部分的响应式策略。省掉三四个硬编码的断点,网页上的内容也能根据视口流畅地缩放。 ⏱ 2020-12-11 12:01:55

2.5 无单位的数值和行高

📌 有些属性允许无单位的值(即一个不指定单位的数)。支持这种值的属性包括line-height、z-index、font-weight(700等于bold,400等于normal,等等)。任何长度单位(如px、em、rem)都可以用无单位的值0, ⏱ 2020-12-11 12:02:50

📌 一个无单位的0只能用于长度值和百分比,比如内边距、边框和宽度等,而不能用于角度值,比如度,或者时间相关的值,比如秒。 ⏱ 2020-12-11 12:03:03

📌 line-height属性比较特殊,它的值既可以有单位也可以无单位。通常我们应该使用无单位的数值,因为它们继承的方式不一样。我们在网页中加上一些文字,看看无单位的行高会如何影响样式。 ⏱ 2020-12-11 12:04:00

📌 如果用有单位的值定义行高,可能会产生意想不到的结果 ⏱ 2020-12-11 14:15:37

📌 使用无单位的数值时,继承的是声明值,即在每个继承子元素上会重新算它的计算值。 ⏱ 2020-12-11 14:18:24

2.6 自定义属性(即CSS变量)

📌 变量名前面必须有两个连字符(—),用来跟CSS属性区分,剩下的部分可以随意命名。 ⏱ 2020-12-11 14:21:32

📌 使用JavaScript改变自定义属性 ⏱ 2020-12-11 14:34:36

第3章 盒模型

📌 在此之前我们要打好基础,深刻理解浏览器是如何设置元素的大小和位置的。高级的布局话题基于文档流和盒模型等概念,这些是决定网页元素的大小和位置的基本规则。 ⏱ 2020-12-11 14:53:59

📌 我们会处理盒模型的一些边缘情况,我也会分享一些有关设置元素大小和对齐方式的经验。另外本章还会处理CSS中最让人头疼的两个问题:垂直居中和等高列。 ⏱ 2020-12-11 14:54:14

3.1 元素宽度的问题

📌 因为IE有一个bug,它会默认将

元素渲染成行内元素,而不是块级元素,所以代码中我们用声明display: block来纠正。 ⏱ 2020-12-11 15:00:22 ^31594821-27-2040-2114

📌 当给一个元素设置宽或高的时候,指定的是内容的宽或高,所有内边距、边框、外边距都是追加到该宽度上的。 ⏱ 2020-12-11 15:12:25

📌 如果这些值使用不同的单位,情况就会更复杂。 ⏱ 2020-12-11 15:10:42

📌 26%是一个魔术数值(magicnumber)。它不是一个理想的值,而是通过改样式试出来的值。 ⏱ 2020-12-11 15:14:18

📌 在编程中不推荐魔术数值,因为往往难以解释一个魔术数值生效的原因。如果不理解这个数值是怎么来的,就不会知道在不同的情况下会产生什么样的结果。 ⏱ 2020-12-11 15:14:23

📌 虽然CSS中有时确实需要反复试验,但目的是为了得到更好的样式,而不是为了强行将一个元素填入一个位置。 ⏱ 2020-12-11 15:14:28

📌 刚才遇到的问题说明默认的盒模型并不符合需求。相反,我们需要让指定的宽度包含内边距和边框。在CSS中可以使用box-sizing属性调整盒模型的行为。 ⏱ 2020-12-11 15:24:30

📌 box-sizing的默认值为content-box,这意味任何指定的宽或高都只会设置内容盒子的大小。将box-sizing设置为border-box后,height和width属性会设置内容、内边距以及边框的大小总和,这刚好符合示例的要求。 ⏱ 2020-12-11 15:24:42

📌 。代码清单3-5用通用选择器(*)选中了页面上所有元素,并用两个选择器选中了网页的所有伪元素。 ⏱ 2020-12-11 15:25:27

📌 。如下述代码所示,可以在必要时选中第三方组件的顶级容器,将其恢复为content-box。这样组件的内部元素会继承该盒模型。 ⏱ 2020-12-11 15:36:13

📌 如果想用其他单位指定间距呢?(我更想用em指定间距,因为em单位的一致性更好。)可以用calc()来实现。 ⏱ 2020-12-11 15:47:27

3.2 元素高度的问题

📌 普通文档流是为限定的宽度和无限的高度设计的。 ⏱ 2020-12-11 15:49:51

📌 容器的高度由内容天然地决定,而不是容器自己决定。 ⏱ 2020-12-11 15:49:39

📌 auto——只有内容溢出时容器才会出现滚动条。 ⏱ 2020-12-11 15:50:50

📌 用百分比指定高度存在问题。百分比参考的是元素容器块的大小,但是容器的高度通常是由子元素的高度决定的。这样会造成死循环,浏览器处理不了,因此它会忽略这个声明。要想让百分比高度生效,必须给父元素明确定义一个高度。 ⏱ 2020-12-11 15:54:18

📌 人们使用百分比高度是想让一个容器填满屏幕。不过更好的方式是用视口的相对单位vh, ⏱ 2020-12-11 15:58:37

📌 最好的办法是让它们自己决定高度,然后扩展较矮的列,让它的高度等于较高的列。 ⏱ 2020-12-11 16:56:52

📌 不像block的元素,默认情况下,显示为table的元素宽度不会扩展到100%,因此需要明确指定宽度❶ ⏱ 2020-12-11 16:31:24

📌 这是因为外边距❷并不会作用于table-cell元素 ⏱ 2020-12-11 16:31:35

📌 接下来介绍的两个是很有用的属性:min-height和max-height。你可以用这两个属性指定最小或最大值,而不是明确定义高度,这样元素就可以在这些界限内自动决定高度。 ⏱ 2020-12-11 17:57:14

📌 垂直居中内容 ⏱ 2020-12-14 09:46:40

📌 vertical-align声明只会影响行内元素或者table-cell元素。对于行内元素,它控制着该元素跟同一行内其他元素之间的对齐关系。比如,可以用它控制一个行内的图片跟相邻的文字对齐。 ⏱ 2020-12-14 10:06:17

📌 vertical-align控制了内容在单元格内的对齐 ⏱ 2020-12-14 10:06:44

📌 CSS中最简单的垂直居中方法是给容器相等的上下内边距,让容器和内容自行决定自己的高度(如图3-14所示), ⏱ 2020-12-14 10:07:35

📌 因为想让容器内另一个子元素靠近容器的顶部或者底部。 ⏱ 2020-12-14 10:08:06

📌 做出判断前,先逐个询问自己以下几个问题,直到找到合适的解决办法 ⏱ 2020-12-14 10:08:24

📌 设置一个大的行高,让它等于理想的容器高度。这样会让容器高度扩展到能够容纳行高。如果内容不是行内元素,可以设置为inline-block。 ⏱ 2020-12-14 11:10:00

📌 将内容绝对定位 ⏱ 2020-12-14 10:08:55

3.3 负外边距

📌 比如让元素重叠或者拉伸到比容器还宽。 ⏱ 2020-12-14 10:09:53

📌 给元素底部加上负外边距并不等同于给它下面的元素顶部加上负外边距。 ⏱ 2020-12-14 10:10:23

📌 如果元素被别的元素遮挡,利用负外边距让元素重叠的做法可能导致元素不可点击。 ⏱ 2020-12-14 10:10:53

3.4 外边距折叠

📌 当顶部和/或底部的外边距相邻时,就会重叠,产生单个外边距。这种现象被称作折叠。 ⏱ 2020-12-14 10:11:24

📌 外边距折叠的主要原因与包含文字的块之间的间隔相关。段落(

)默认有1em的上外边距和1em的下外边距。这是用户代理的样式表添加的,但当前后叠放两个段落时,它们的外边距不会相加产生一个2em的间距,而会折叠,只产生1em的间隔。 ⏱ 2020-12-14 10:12:25

📌 折叠外边距的大小等于相邻外边距中的最大值。 ⏱ 2020-12-14 10:12:41

📌 所有的外边距都会折叠到一起。 ⏱ 2020-12-14 10:14:38

📌 说明只有上下外边距会产生折叠,左右外边距不会折叠。 ⏱ 2020-12-14 10:14:47

📌 导致

下方出现了21.44px的外边距。 ⏱ 2020-12-14 10:15:56 ^31594821-30-3218-3251

📌 我们希望

的外边距留在
中,但是外边距不一定在理想的地方折叠。 ⏱ 2020-12-14 10:15:50 ^31594821-30-3314-3367

📌 这是因为弹性子元素的外边距不会折叠,而这一块刚好用了Flexbox布局。 ⏱ 2020-12-14 10:17:49

📌 给头部添加上下内边距,外边距就不会在容器外部折叠。现在将头部的样式更新, ⏱ 2020-12-14 10:18:06

📌 对容器使用overflow: auto(或者非visible的值) ⏱ 2020-12-14 10:20:58

📌 在两个外边距之间加上边框或者内边距,防止它们折叠。 ⏱ 2020-12-14 10:20:42

📌 如果容器为浮动元素、内联块、绝对定位或固定定位时,外边距不会在它外面折叠。 ⏱ 2020-12-14 10:20:45

📌 当使用Flexbox布局时,弹性布局内的元素之间不会发生外边距折叠 ⏱ 2020-12-14 10:20:49

3.5 容器内的元素间距

📌 它使用相邻的兄弟组合器(+)选中同一个父元素下紧跟在其他button-link后面的button-link元素。 ⏱ 2020-12-14 10:28:17

📌 每一次改变HTML,都需要考虑这些外边距的问题。你得确保每个元素之间有间距,但是容器的顶部(或底部)没有多余的间距。 ⏱ 2020-12-14 10:38:06

📌 不要给网页当前的内容固定外边距,而是应该采取更通用的方式,不管网页结构如何变化都能够生效。这就是Heydon Pickering所说的迟钝的猫头鹰选择器(lobotomizedowl selector)(以下简称猫头鹰选择器),因为它长这样:* + * ⏱ 2020-12-14 10:38:24

📌 它会选中页面上有着相同父级的非第一个子元素。 ⏱ 2020-12-14 10:41:35

📌 因为侧边栏是主列的相邻兄弟元素,所以它也会有顶部外边距 ⏱ 2020-12-14 10:46:11

3.6 总结

📌 使用现代的布局技术,比如display: table或者Flexbox实现列等高或者垂直居中内容。 ⏱ 2020-12-14 10:49:36

第4章 理解浮动

📌 第一部分在最后介绍了元素大小和间距的一些基本概念。第二部分会基于这些概念,更详细地介绍页面布局的主要方法。我们将介绍最重要的三种改变文档流的方式:浮动、Flexbox和网格布局。 ⏱ 2020-12-14 10:55:23

📌 本章还将展示两种常见的网页布局模式:双容器模式和媒体对象 ⏱ 2020-12-14 10:55:52

4.1 浮动的设计初衷

📌 浮动能将一个元素(通常是一张图片)拉到其容器的一侧,这样文档流就能够包围它(如图4-1所示)。这种布局在报纸和杂志中很常见,因此CSS增加了浮动来实现这种效果。 ⏱ 2020-12-14 11:11:04

📌 通常,最简单的方式是先将网页的大块区域布局好,再逐级布局内部的小元素。 ⏱ 2020-12-14 11:21:18

📌 让它在外层容器中居中(如图4-5所示)。Web开发人员Brad Westfall把这种布局方式叫作双容器模式(double container pattern) ⏱ 2020-12-14 11:28:43

📌 如果你在支持旧代码库,它很可能用到了浮动布局。为了维护旧代码,也需要了解浮动的工作原理 ⏱ 2020-12-14 11:33:40

📌 要实现将图片移动到网页一侧,并且让文字围绕图片的效果,浮动仍然是唯一的方法。 ⏱ 2020-12-14 11:33:50

4.2 容器折叠和清除浮动

📌 这是因为浮动元素不同于普通文档流的元素,它们的高度不会加到父元素上。这可能看起来很奇怪,但是恰好体现了浮动的设计初衷 ⏱ 2020-12-14 11:36:12

📌 浮动是为了实现文字围绕浮动元素排列的效果。在段落里浮动图片时,段落的高度并不会增长到能够容纳该图片。也就是说,如果图片比段落文字高,下一段会直接从上一段的文字下面开始,两段文字都会围绕浮动的图片排列, ⏱ 2020-12-14 11:36:31

📌 在主元素里,除了页面标题,其他元素都设置了浮动,所以容器的高度只包含页面标题的高度, ⏱ 2020-12-14 11:39:08

📌 一个解决办法是使用跟浮动配套的clear属性。将一个元素放在主容器的末尾,并对它使用clear,这会让容器扩展到浮动元素下面 ⏱ 2020-12-14 11:41:03

📌 clear: both声明让该元素移动到浮动元素的下面,而不是侧面。clear的值还可以设置为left或者right,这样只会相应地清除向左或者向右浮动的元素。因为空div本身没有浮动,所以容器就会扩展,直到包含它,因此也会包含该div上面的浮动元素 ⏱ 2020-12-14 11:41:18

📌 这种方法的确能实现预期的行为,但是不雅。要在HTML里添加不必要的标记,才能实现本应该由CSS实现的效果。因此我们要删掉上面的空div标签,用纯CSS方案来实现相同的效果。 ⏱ 2020-12-14 11:41:25

📌 使用::after伪元素选择器,就可以快速地在DOM中在容器末尾添加一个元素,而不用在HTML里添加标记。 ⏱ 2020-12-14 11:42:08

📌 代码清单4-6所示的是解决包含浮动问题的一种常见做法,叫作清除浮动(clearfix)。有些开发人员将其简称为cf,正好还能表示“包含浮动”(containfloat)。将代码清单4-6添加到你的样式表中。[插图] ⏱ 2020-12-14 14:13:41

📌 要给包含浮动的元素清除浮动, ⏱ 2020-12-14 11:46:09

📌 这个清除浮动还有个一致性问题没有解决:浮动元素的外边距不会折叠到清除浮动容器的外部,非浮动元素的外边距则会正常折叠。 ⏱ 2020-12-14 11:46:50

📌 这个版本使用display: table而不是display: block。给::before和::after伪元素都加上这一属性,所有子元素的外边距都会包含在容器的顶部和底部之间 ⏱ 2020-12-14 11:48:55

📌 当我们不想要外边距折叠时,这个版本的清除浮动非常有用。 ⏱ 2020-12-14 11:50:09

📌 也就在元素内隐式创建了一个表格行和一个单元格。因为外边距无法通过单元格元素折叠(参见第3章),所以也无法通过设置了display: table的伪元素折叠。 ⏱ 2020-12-14 14:15:27

4.3 出乎意料的“浮动陷阱”

📌 这是因为浏览器会将浮动元素尽可能地放在靠上的地方, ⏱ 2020-12-14 14:18:30

📌 这种行为本质上取决于每个浮动块的高度。即使高度相差1px,也会导致这个问题。 ⏱ 2020-12-14 14:18:56

📌 更通用的做法是,清除每行的第一个元素上面的浮动。 ⏱ 2020-12-14 14:20:08

📌 上面这种清除每行浮动的技术要求知道每行有几个元素。如果宽度不是通过百分比来定义的,那么随着视口宽度的改变,每行的元素个数可能会变化。这种情况下,最好使用别的布局方案,比如Flexbox或者inline-block元素。 ⏱ 2020-12-14 14:28:16

4.4 媒体对象和BFC

📌 图4-12 媒体对象模式:图片在左边,一段描述内容在右边 ⏱ 2020-12-14 14:32:06

📌 首先将图片浮动到左边。 ⏱ 2020-12-14 14:32:32

📌 为了实现右边这种布局,需要为正文建立一个块级格式化上下文(blockformatting context, BFC)。BFC是网页的一块区域,元素基于这块区域布局 ⏱ 2020-12-14 14:35:01

📌 (1) 包含了内部所有元素的上下外边距。它们不会跟BFC外面的元素产生外边距折叠。(2) 包含了内部所有的浮动元素。(3) 不会跟BFC外面的浮动元素重叠。 ⏱ 2020-12-14 14:35:08

📌 给元素添加以下的任意属性值都会创建BFC。❑ float: left或right,不为none即可。❑ overflow:hidden、auto或scroll,不为visible即可。❑ display:inline-block、table-cell、table-caption、flex、inline-flex、grid或inline-grid。拥有这些属性的元素称为块级容器(block container)。❑ position:absolute或position: fixed。说明网页的根元素也创建了一个顶级的BFC。 ⏱ 2020-12-14 14:35:39

📌 通常是给元素设置overflow值——hidden或者auto。 ⏱ 2020-12-14 14:36:02

📌 使用overflow: auto通常是创建BFC最简单的一种方式 ⏱ 2020-12-14 14:36:36

📌 使用浮动或者inline-block方式创建BFC的元素宽度会变成100%,因此需要限制一下元素的宽度,防止因为过宽而换行,导致内容移动到浮动图片的下面。相反,使用table-cell方式显示的元素,其宽度只会刚好容纳其中的内容,因此需要设置一个较大的宽度,强制使其填满剩余空间。 ⏱ 2020-12-14 14:36:51

4.5 网格系统

📌 一种比较普遍的做法是借助网格系统提高代码的可复用性。网格系统提供了一系列的类名,可添加到标记中,将网页的一部分构造成行和列。 ⏱ 2020-12-14 15:06:48

📌 通常网格系统的每行被划分为特定数量的列,一般是12个 ⏱ 2020-12-14 15:07:16

📌 选取12作为列数是因为它能够被2、3、4、6整除,组合起来足够灵活 ⏱ 2020-12-14 15:07:24

📌 以上代码仅仅实现了清除浮动。这样写是为了避免每添加一个行元素就要给它加一个clearfix类 ⏱ 2020-12-14 15:09:54

📌 它能写出更复杂的匹配规则。*=比较符可以匹配任意包含指定字符串的值 ⏱ 2020-12-14 15:10:27

📌 最好的方式是从现在起将类名里的“column”作为保留字,这样就不会跟以上样式规则冲突了。 ⏱ 2020-12-14 15:11:55

4.6 总结

📌 BFC有3个好处:包含浮动元素,防止外边距折叠,防止文档流围绕浮动元素排列。 ⏱ 2020-12-14 15:27:10

5.1 Flexbox的原则

📌 弹性子元素默认是在同一行按照从左到右的顺序并排排列 ⏱ 2020-12-14 15:29:26

📌 弹性子元素高度相等,该高度由它们的内容决定。 ⏱ 2020-12-14 15:29:40

📌 它会跟其他行内元素一起流式排列 ⏱ 2020-12-14 15:32:57

📌 之前提到的display值,比如inline、inline-block等,只会影响到应用了该样式的元素,而Flexbox则不一样。一个弹性容器能控制内部元素的布局 ⏱ 2020-12-14 15:34:11

📌 要实现这个菜单,需要考虑让哪个元素做弹性容器,这个元素的子元素便会成为弹性子元素。 ⏱ 2020-12-14 15:35:40

📌 这是因为旧版浏览器要求给Flexbox属性加上浏览器前缀。在标准稳定前,浏览器一般是这样来支持CSS新特性的 ⏱ 2020-12-14 15:46:42

📌 如果希望菜单项等间距,那么justify-content属性会是更好的方式。稍后会介绍这个属性。 ⏱ 2020-12-14 15:56:13

5.2 弹性子元素的大小

📌 flex属性是三个不同大小属性的简写:flex-grow、flex-shrink和flex-basis。在代码清单5-7里,只提供了flex-grow的值,剩下的两个属性是默认值(分别是1和0%),因此flex: 2等价于flex: 210%。通常首选简写属性,但也可以分别声明三个属性。

  • 💭 flex-basis默认为auto,但是在赋flex单值(number)的时候flex-basis:0,“a <number>: In this case it is interpreted as flex: <number> 1 0; the <flex-shrink> value is assumed to be 1 and the <flex-basis> value is assumed to be 0.” (mdn英文文档中写了,中文的没写) - ⏱ 2020-12-14 16:18:01

📌 元素是否设置了width属性值。如果有,则使用width的值作为flex-basis的值;如果没有,则用元素内容自身的大小。 ⏱ 2020-12-14 16:11:43

📌 每个弹性子元素的初始主尺寸确定后,它们可能需要在主轴方向扩大或者缩小来适应(或者填充)弹性容器的大小。 ⏱ 2020-12-14 16:15:08

📌 每个弹性子元素的flex-basis值计算出来后,它们(加上子元素之间的外边距)加起来会占据一定的宽度。加起来的宽度不一定正好填满弹性容器的宽度,可能会有留白(如图5-8所示)。 ⏱ 2020-12-14 16:16:16

📌 多出来的留白(或剩余宽度)会按照flex-grow(增长因子)的值分配给每个弹性子元素,flex-grow的值为非负整数。如果一个弹性子元素的flex-grow值为0,那么它的宽度不会超过flex-basis的值;如果某个弹性子元素的增长因子非0,那么这些元素会增长到所有的剩余空间被分配完,也就意味着弹性子元素会填满容器的宽度(如图5-9所示)。 ⏱ 2020-12-14 16:16:49

📌 简写声明flex: 2和flex: 1设置了一个弹性基准值为0%,因此容器宽度的100%都是剩余宽度(减去两列之间1.5em的外边距)。剩余宽度会分配给两列:第一列得到2/3的宽度,第二列得到1/3的宽度(如图5-11所示)。 ⏱ 2020-12-14 16:18:34

📌 推荐使用简写属性flex,而不是分别声明flex-grow、flex-shrink、flex-basis ⏱ 2020-12-14 17:52:57

📌 相反,如果某个子属性被省略,那么flex简写属性会给出有用的默认值:flex-grow为1、flex-shrink为1、flex-basis为0%。 ⏱ 2020-12-14 17:54:04

📌 每个子元素的flex-shrink值代表了它是否应该收缩以防止溢出。如果某个子元素为flex-shrink: 0,则不会收缩;如果值大于0,则会收缩至不再溢出。按照flex-shrink值的比例,值越大的元素收缩得越多。 ⏱ 2020-12-14 17:57:06

📌 其中第3个例子展示的是“圣杯”布局。众所周知,用CSS实现这种布局非常困难。该布局中,两个侧边栏宽度固定,而中间的列是“流动的”, ⏱ 2020-12-14 18:00:19

5.3 弹性方向

📌 Flexbox的另一个重要功能是能够切换主副轴方向,用弹性容器的flex-direction属性控制。如前面的例子所示,它的初始值(row)控制子元素按从左到右的方向排列;指定flex-direction: column能控制弹性子元素沿垂直方向排列(从上到下)。 ⏱ 2020-12-14 18:24:48

📌 其实左右两个弹性子元素是等高的。问题是右边栏内部的两个板块没有扩展到填满右边栏区域。 ⏱ 2020-12-14 18:36:17

📌 上述场景的真正需求是让两列扩展到填满容器的高度。因此要将右边栏(column-sidebar)改为弹性容器,并设置flex-direction: column。然后给里面的两个板块设置非0的flex-grow值。 ⏱ 2020-12-14 19:12:38

📌 内部的弹性盒子的弹性方向为column,因此主轴发生了旋转,现在变成了从上到下(副轴变成了从左到右)。也就是对于弹性子元素而言,flex-basis、flex-grow和flex-shrink现在作用于元素的高度而不是宽度。由于指定了flex: 1,因此在必要的时候子元素的高度会扩展到填满容器 ⏱ 2020-12-15 11:02:26

📌 在CSS中处理高度的方式与处理宽度的方式在本质上不一样。弹性容器会占据100%的可用宽度,而高度则由自身的内容来决定 ⏱ 2020-12-15 11:02:47

📌 弹性容器的高度由弹性子元素决定,它们会正好填满容器 ⏱ 2020-12-15 11:02:59

📌 在本章的网页里,“外力”就是从外层弹性盒子计算出来的高度。 ⏱ 2020-12-15 11:03:59

📌 这是一个黑名单方式:把不想选中的元素排除掉。你也可以采用白名单方式:使用多个属性选择器将想要选中的所有类型都列出来,但这样一来代码就很长了。 ⏱ 2020-12-15 11:37:49

📌 虽然该网页的表单只使用了文本和密码输入框,但是我们需要考虑到这段CSS在未来可能影响的其他标记,并尽量照顾到那些标记。 ⏱ 2020-12-15 11:37:54

📌 让它们单独占据一行,还要将其宽度设置为100%。通常情况下,块级元素会自动填满可用宽度,但是比较特殊,其宽度由size属性决定,而它表示不出滚动条的情况下大致能容纳的字符数量。如果不指定的话,该属性就会恢复为默认值 ⏱ 2020-12-15 11:40:06

5.4 对齐、间距等细节

📌 这些选项大多数跟弹性容器内弹性子元素的对齐或者间距相关。还有一些选项可以设置换行、重新给子元素单独排序。 ⏱ 2020-12-15 14:57:31

📌 子元素不再根据flex-shrink值收缩,任何超过弹性容器的子元素都会换行显示。 ⏱ 2020-12-15 15:13:10

📌 justify-content属性控制子元素沿主轴方向的间距。它的值包括几个关键字:flex-start、flex-end、center、space-between以及space-around。 ⏱ 2020-12-15 15:15:43

📌 间距是在元素的外边距之后进行计算的,而且flex-grow的值要考虑进来 ⏱ 2020-12-15 15:17:20

📌 justify-content控制子元素在主轴方向的对齐方式,align-items则控制子元素在副轴方向的对齐方式。 ⏱ 2020-12-15 15:18:53

📌 因此它能实现等高列。 ⏱ 2020-12-15 15:19:17

📌 其他的值让弹性子元素可以保留自身的大小,而不是填充容器的大小。(类似的概念有vertical-align属性。) ⏱ 2020-12-15 15:23:15

📌 baseline让元素根据每个弹性子元素的第一行文字的基线对齐。 ⏱ 2020-12-15 15:23:21

📌 但是它能单独给弹性子元素设定不同的对齐方式。 ⏱ 2020-12-15 15:27:27

5.5 值得注意的地方

📌 与其花费时间讨论你可能或者永远不会遇到的bug,我更愿意推荐一个特别棒的资源,叫Flexbugs。它的GitHub页面维护了所有已知的Flexbox的浏览器bug(本书写作时总共有14个),解释了哪些环境下会导致这些bug,并大部分情况下给出了解决方案。 ⏱ 2020-12-15 16:10:44

📌 他写过一篇文章Don’t useflexbox for overall page layout讨论这个问题。你可以在这篇文章里看到前面所说的情况。他给出的一个建议是对整页布局的时候使用网格布局(第6章会介绍) ⏱ 2020-12-15 16:15:33

第6章 网格布局

📌 它既可以实现基础布局,也提供了强大的功能用于实现复杂布局,但是后者需要掌握额外的新属性和关键字。 ⏱ 2020-12-15 16:18:05

6.1 网页布局开启新纪元

📌 主流浏览器摒弃了过去那种漫长的开发迭代方式,几乎一夜间推出了功能齐全的、成熟的网格布局。2017年3月,各大厂商启用了网格布局特性。 ⏱ 2020-12-15 16:37:33

📌 首先,使用display: grid定义一个网格容器。容器会表现得像一个块级元素,100%填充可用宽度 ⏱ 2020-12-15 16:45:55

📌 接下来是新属性:grid-template-columns和grid-template-rows。这两个属性定义了网格每行每列的大小。本例使用了一种新单位fr,代表每一列(或每一行)的分数单位(fraction unit)。这个单位跟Flexbox中flex-grow因子的表现一样。grid-template-columns:1fr 1fr 1fr表示三列等宽。 ⏱ 2020-12-15 16:46:04

📌 后面跟着一个会填满剩余可用空间的列。2fr的列宽是1fr的两倍。 ⏱ 2020-12-15 17:02:37

📌 也可以用两个值分别指定垂直和水平方向的间距(比如grid-gap: 0.5em 1em)。 ⏱ 2020-12-15 17:20:33

6.2 网格剖析

📌 比如声明grid-template-columns: 1fr 1fr1fr就会定义三个等宽且垂直的网格轨道,同时还定义了四条垂直的网格线:一条在网格最左边,两条在每个网格轨道之间,还有一条在最右边。 ⏱ 2020-12-15 17:37:55

📌 。如果想要一个网格元素在垂直方向上跨越1号网格线到3号网格线,就需要给元素设置grid-column: 1 / 3。或者设置grid-row: 3 / 5让元素在水平方向上跨越3号网格线到5号网格线。 ⏱ 2020-12-15 17:41:11

📌 Flexbox是以内容为切入点由内向外工作的,而网格是以布局为切入点从外向内工作的。 ⏱ 2020-12-15 17:41:43

📌 Flexbox让你在一行或一列中安排一系列元素,但是它们的大小不需要明确指定,每个元素占据的大小根据自身的内容决定。 ⏱ 2020-12-15 17:42:05

📌 而在网格中,首先要描述布局,然后将元素放在布局结构中去。虽然每个网格元素的内容都能影响其网格轨道的大小,但是这同时也会影响整个轨道的大小,进而影响这个轨道里的其他网格元素的大小。 ⏱ 2020-12-15 17:42:09

6.3 替代语法

📌 将网格线命名为left-start和left-end,就定义了一个叫作left的区域,这个区域覆盖两个网格线之间的区域。-start和-end后缀作为关键字,定义了两者之间的区域。如果给元素设置grid-column: left,它就会跨越从left-start到left-end的区域。 ⏱ 2020-12-16 10:05:16

📌 于是每条水平网格线被命名为row(除了最后一条)。这看起来很不可思议,但是重复使用同一个名称完全合法。然后将main元素放在从row 3(第三个叫row的网格线)开始的地方,并跨越两个网格轨道。 ⏱ 2020-12-16 10:06:56

📌 col 2 / span 2 ⏱ 2020-12-16 10:07:12

6.4 显式和隐式网格

📌 。当处理大量的网格元素时,挨个指定元素的位置未免太不方便。当元素是从数据库获取时,元素的个数可能是未知的。在这些情况下,以一种宽松的方式定义网格可能更合理,剩下的交给布局算法来放置网格元素。 ⏱ 2020-12-16 10:18:30

📌 隐式网格轨道默认大小为auto,也就是它们会扩展到能容纳网格元素内容。可以给网格容器设置grid-auto-columns和grid-auto-rows,为隐式网格轨道指定一个大小(比如,grid-auto-columns: 1fr)。 ⏱ 2020-12-16 10:18:19

📌 网格布局模块规范提供了另一个属性grid-auto-flow,它可以控制布局算法的行为。它的初始值是row,上一段描述的就是这个值的行为。如果值为column,它就会将元素优先放在网格列中,只有当一列填满了,才会移动到下一行。 ⏱ 2020-12-16 10:25:49

📌 还可以额外加一个关键字dense(比如,grid-auto-flow: column dense)。它让算法紧凑地填满网格里的空白,尽管这会改变某些网格元素的顺序。加上这个关键字,小元素就会“回填”大元素造成的空白区域。效果如图6-15所示。 ⏱ 2020-12-16 10:25:56

📌 小网格元素会回填网格的空白区域 ⏱ 2020-12-16 10:30:47

📌 每个网格元素都会扩展并填满整个网格区域 ⏱ 2020-12-16 10:37:56

📌 好在CSS为控制这一行为提供了一个特殊属性object-fit。默认情况下,一个的object-fit属性值为fill,也就是说整个图片会缩放,以填满元素。你也可以设置其他值改变默认行为。 ⏱ 2020-12-16 10:32:28

📌 因为用flex-grow属性拉伸了图片,所以应该给它加上object-fit: cover防止渲染的图片变形。 ⏱ 2020-12-16 10:33:09

6.5 特性查询

📌 @supports规则后面跟着一个小括号包围的声明。如果浏览器理解这个声明(在本例中,浏览器支持网格),它就会使用大括号里面的所有样式规则。如果它不理解小括号里的声明,就不会使用这些样式规则。 ⏱ 2020-12-16 10:34:53

第7章 定位和层叠上下文

📌 表格显示、Flexbox以及浮动 ⏱ 2020-12-17 17:15:58

📌 position属性的初始值是static。前面的章节里用的都是这个静态定位。如果把它改成其他值,我们就说元素就被定位了。而如果元素使用了静态定位,那么就说它未被定位。 ⏱ 2020-12-17 17:16:59

📌 前面几章介绍的布局方法是用各种操作来控制文档流的行为。定位则不同:它将元素彻底从文档流中移走。它允许你将元素放在屏幕的任意位置。还可以将一个元素放在另一个元素的前面或后面,彼此重叠。 ⏱ 2020-12-17 17:17:33

7.1 固定定位

📌 固定定位不如其他定位类型用得普遍,但它是最好理解的一种定位类型,因此我先从它开始介绍。给一个元素设置position: fixed就能将元素放在视口的任意位置。这需要搭配四种属性一起使用:top、right、bottom和left。这些属性的值决定了固定定位的元素与浏览器视口边缘的距离。比如,top: 3em表示元素的上边缘距离视口顶部3em。 ⏱ 2020-12-17 17:17:47

📌 设置这四个值还隐式地定义了元素的宽高。比如指定left: 2em; right: 2em表示元素的左边缘距离视口左边2em,右边缘距离视口右边2em。因此元素的宽度等于视口总宽度减去4em。top、bottom和视口高度也是这样的关系。 ⏱ 2020-12-17 17:19:03

📌 虽然可以随意滚动网页,但是背景和模态框主体都不会动。 ⏱ 2020-12-17 18:15:02

📌 定位一个元素时,不要求指定四个方向的值,可以只指定需要的方向值,然后用width和/或height来决定它的大小,也可以让元素本身来决定大小。 ⏱ 2020-12-18 20:53:59

📌 宽度为视口宽度的20% ⏱ 2020-12-18 01:02:13

7.2 绝对定位

📌 。绝对定位不是相对视口,而是相对最近的祖先定位元素。跟固定元素一样,属性top、right、bottom和left决定了元素的边缘在包含块里的位置。 ⏱ 2020-12-18 21:09:25

📌 因为它的父元素modal-body是固定定位的,所以会成为Close按钮的包含块 ⏱ 2020-12-19 19:27:04

📌 如果父元素未被定位,那么浏览器会沿着DOM树往上找它的祖父、曾祖父,直到找到一个定位元素,用它作为包含块。 ⏱ 2020-12-19 19:36:00

📌 辅助的屏幕阅读器会读按钮里的文字。 ⏱ 2020-12-19 19:46:58

📌 你可以用CSS隐藏close,并显示x。 ⏱ 2020-12-18 21:22:20

7.3 相对定位

📌 不能用top、right、bottom和left改变相对定位元素的大小。 ⏱ 2020-12-20 15:00:23

📌 更常见的用法是使用position: relative给它里面的绝对定位元素创建一个包含块。 ⏱ 2020-12-20 15:03:19

7.4 层叠上下文和z-index

📌 浏览器将HTML解析为DOM的同时还创建了另一个树形结构,叫作渲染树(rendertree)。它代表了每个元素的视觉样式和位置。同时还决定浏览器绘制元素的顺序。顺序很重要,因为如果元素刚好重叠,后绘制的元素就会出现在先绘制的元素前面。 ⏱ 2020-12-20 15:10:18

📌 定位元素时,这种行为会改变。浏览器会先绘制所有非定位的元素,然后绘制定位元素 ⏱ 2020-12-20 15:24:11

📌 所有的定位元素会出现在非定位元素前面。 ⏱ 2020-12-20 15:24:21

📌 也就是说在上述网页里,模态框和下拉菜单都会出现在静态内容之前(符合预期),但是源码里后出现的元素会绘制在先出现的元素之前 ⏱ 2020-12-20 15:28:24

📌 通常情况下,模态框要放在网页内容的最后,关闭标签之前。大多数构建模态框的JavaScript库会自动这样做。因为模态框使用固定定位,所以不必关心它的标记出现在哪里,它会一直定位到屏幕中间。 ⏱ 2020-12-20 15:28:05

📌 拥有较高z-index的元素出现在拥有较低z-index的元素前面。拥有负数z-index的元素出现在静态元素后面。 ⏱ 2020-12-20 16:32:22

📌 第一,z-index只在定位元素上生效,不能用它控制静态元素。第二,给一个定位元素加上z-index可以创建层叠上下文。 ⏱ 2020-12-20 16:32:53

📌 有些开发人员会忍不住给页面的大量元素使用定位。一定要克制这种冲动。定位用得越多,网页就越复杂,也就越难调试。 ⏱ 2020-12-21 09:44:01

📌 如果能够依靠文档流,而不是靠明确指定定位的方式实现布局,那么浏览器会帮我们处理好很多边缘情况 ⏱ 2020-12-21 09:44:08

7.5 粘性定位

📌 现在浏览器还提供了一种新的定位类型:粘性定位(sticky positioning)。它是相对定位和固定定位的结合体:正常情况下,元素会随着页面滚动,当到达屏幕的特定位置时,如果用户继续滚动,它就会“锁定”在这个位置。最常见的用例是侧边栏导航。 ⏱ 2020-12-21 09:44:49

📌 只有当父元素的高度大于粘性元素时才会让粘性元素固定,因此这里我特意给弹性容器加上min-height ⏱ 2020-12-21 09:55:53

第8章 响应式设计

📌 移动优先。这意味着在实现桌面布局之前先构建移动版的布局。 ⏱ 2020-12-21 10:11:58

8.1 移动优先

📌 这个HTML标签告诉移动设备,你已经特意将网页适配了小屏设备。如果不加这个标签,移动浏览器会假定网页不是响应式的,并且会尝试模拟桌面浏览器,那之前的移动端设计就白做了。 ⏱ 2020-12-28 20:54:42

📌 此外content属性还有第三个选项user-scalable=no,阻止用户在移动设备上用两个手指缩放。通常这个设置在实践中并不友好,不推荐使用。当链接太小不好点击,或者用户想要把某个图片看得更清楚时,这个设置会阻止他们缩放页面。 ⏱ 2020-12-21 10:29:26

8.2 媒体查询

📌 不要总想着设备。市面上有成百上千中设备和屏幕分辨率,无法逐一测试。相反,应该选择适合设计的断点,这样不管在什么设备上,都能有很好的表现。 ⏱ 2020-12-21 10:56:05

8.3 流式布局

📌 流式布局,有时被称作液体布局(liquid layout),指的是使用的容器随视口宽度而变化。 ⏱ 2020-12-21 11:00:43

📌 在主容器中,任何列都用百分比来定义宽度(比如,主列宽70%,侧边栏宽30%)。这样无论屏幕宽度是多少都能放得下主容器。用Flexbox布局也可以,设置弹性元素的flex-grow和flex-shrink(更重要),让元素能够始终填满屏幕。要习惯将容器宽度设置为百分比,而不是任何固定的值。 ⏱ 2020-12-21 11:00:55

8.5 总结

📌 不要忘记给视口添加meta标签。 ⏱ 2020-12-28 20:54:24

第9章 模块化CSS

📌 模块化CSS(Modular CSS)是指把页面分割成不同的组成部分,这些组成部分可以在多种上下文中重复使用,并且互相之间没有依赖关系。最终目的是,当我们修改其中一部分CSS时,不会对其他部分产生意料之外的影响。 ⏱ 2020-12-28 22:30:25

📌 些小件看上去风格一致,组合起来 ⏱ 2020-12-28 22:30:37

9.1 基础样式:打好基础

📌 每个样式表的开头都要写一些给整个页面使用的通用规则,模块化CSS也不例外。这些规则通常被称为基础样式,其他的样式是构建在这些基础样式之上的。基础样式本身并不是模块化的,但它会为后面编写模块化样式打好基础。 ⏱ 2020-12-28 22:38:08

📌 这里推荐一个叫作normalize.css的库,这个小样式表可以协助消除不同的客户端浏览器渲染上的不一致 ⏱ 2020-12-29 11:17:08

📌 基础样式应该是通用的,只添加那些影响页面上大部分或者全部内容的样式 ⏱ 2020-12-29 11:19:31

📌 核心思想是这些基础样式提供了一些默认的渲染效果,但是之后可以很方便地根据需要覆盖基础样式。 ⏱ 2020-12-29 11:19:40

9.2 一个简单的模块

📌 把代码清单9-3添加到样式表中,放在基础样式后面,就可以把这些样式应用到消息模块了。 ⏱ 2020-12-29 11:20:03

📌 通过给元素添加类名,就可以把这些样式复用到很多场景,比如针对表单输入给用户反馈,提供醒目的帮助文字,或者提醒用户注意免责声明条款等。使用相同的组件,就产生了一套风格一致的UI。所有用到组件的地方将看上去一样,不会出现有的地方蓝绿色有色差、有的地方内边距偏大等问题。 ⏱ 2020-12-29 14:52:47

📌 。样式表里多次出现相同的代码,尽管并不是完全的复制。重复是为了获得一致的体验,但是随着时间的推移,不同的按钮之间还是发生了一些不一样的改变。因此,有的按钮内边距稍有不同,有的按钮红得更鲜艳。 ⏱ 2020-12-29 14:52:58

📌 解决办法就是把按钮重构成一个可复用的模块,不受页面位置的限制。创建模块不但可以精简代码(减少重复),还可以保证视觉一致性。这样看上去更专业,不会给人仓促堆砌的感觉。用户在潜意识里也会更容易相信我们的应用程序。 ⏱ 2020-12-29 14:53:05

📌 这可以通过定义修饰符(modifiers)来实现。 ⏱ 2020-12-29 14:55:14

📌 常用的写法是使用两个连字符来表示修饰符,比如message—error。 ⏱ 2020-12-29 14:55:20

📌 如果有个#products-page .sidebar .social-media div:first-child h3这样的选择器,样式集就会和指定页面的指定位置紧紧耦合。 ⏱ 2020-12-29 14:38:51

📌 这些类名以模块名称开头,后跟双下划线,然后是子元素的名称。( ⏱ 2020-12-29 15:12:16

📌 这条规则覆盖了媒体图片之前的float: left ⏱ 2020-12-29 15:10:36

📌 避免在模块选择器中使用通用标签名 ⏱ 2020-12-29 15:10:12

9.3 把模块组合成更大的结构

📌 应该尽量让需要定位的元素关联到同一个模块内的其他元素。只有这样,我们把模块放在另一个有定位的容器里的时候,才不会弄乱样式。 ⏱ 2020-12-29 15:14:33

📌 状态类一般以is-或者has-开头。这样状态类的目的就会比较明显,它们表示模块当前状态下的一些特征或者即将发生的变化 ⏱ 2020-12-29 15:14:45

📌 。这样可以减少浏览器发起的网络请求数,开发者也可以把代码文件拆分成易于维护的大小。 ⏱ 2020-12-29 15:19:34

📌 模块的命名应该有意义,无论使用场景是什么。同时也要避免使用简单地描述视觉效果的名称。 ⏱ 2020-12-29 15:20:54

9.4 工具类

📌 它们分别实现了特定的功能:文字居中、左浮动、清除浮动(包裹浮动)、隐藏元素。 ⏱ 2020-12-29 15:23:46

📌 事实上,工具类应该优先使用它。这样的话,不管在哪里用到工具类,都可以生效。我敢肯定,任何时候为元素添加text-center类,都是想让文本居中,不想让其他样式覆盖它。用了important注释就可以确保这一点。 ⏱ 2020-12-29 15:23:56

第10章 模式库

📌 把模块清单整合成一组文档,在大型项目中已经成为通用做法。这组文档被称为模式库(pattern library)或者样式指南(style guide)。 ⏱ 2020-12-29 16:23:32

10.1 KSS简介

📌 面紧跟一大段HTML代码,用来举例说明模块的用法。KSS把这些HTML转化成模式库,以便读者预览效果。接下来,HTML代码展示为可读性良好的格式,读者可以复制如下代码。 ⏱ 2020-12-29 16:21:01

10.2 改变编写CSS的方式

📌 不要盲目地使用框架,要学习思考框架背后的设计思路 ⏱ 2020-12-29 16:42:25

第11章 背景、阴影和混合模式

📌 在实现了页面里某个组件的布局并写完样式之后,不要急着继续,有意识地训练自己,以挑剔的眼光审视刚刚完成的代码 ⏱ 2020-12-30 10:34:30

📌 它使用了背景渐变和投影两种特效,看上去有了立体感。背景颜色从顶部的中蓝色(#57b)过渡到底部的深蓝色(#148)。 ⏱ 2020-12-30 10:35:29

📌 还有一种非常有意思的特效叫作混合模式(blend modes),可以把多个背景图片和背景颜色以不同方式组合在一起使用。 ⏱ 2020-12-30 10:35:39

11.1 渐变

📌 background-color——指定纯色背景,渲染到背景图片下方。 ⏱ 2020-12-30 10:42:06

📌 而它也可以接受一个渐变函数。 ⏱ 2020-12-30 10:42:19

📌 我们使用了to right,当然也可以使用to top或者to bottom。甚至可以指定某个对角,比如to bottom right,这样的话,渐变会从元素的左上角开始,逐渐过渡到右下角。 ⏱ 2020-12-30 10:43:44

📌 我们可以使用更确切的单位(比如度),更精确地控制角度。值0deg代表垂直向上(相当于to top),更大的值会沿着顺时针变化,因此90deg代表向右渐变,180deg代表向下渐变,360deg又会代表向上渐变。 ⏱ 2020-12-30 10:43:49

11.2 阴影

📌 其中1em代表偏移量,即阴影从元素的位置偏移了多少距离(先水平方向,后垂直方向)。 ⏱ 2020-12-30 11:10:01

📌 我们增加了一个inset关键字,用来替换之前的盒阴影。这样就可以使阴影出现在元素边框的内部,而非之前的外部。同时我们定义了不止一个阴影,用逗号分隔。通过这种方式可以添加多个阴影。 ⏱ 2020-12-30 11:14:32

📌 扁平化设计讲究色彩明快统一、外观简洁明了, ⏱ 2020-12-30 11:16:17

📌 通用的设计方案是介于扁平化设计与拟物化设计之间。 ⏱ 2020-12-30 11:18:17

11.3 混合模式

📌 但某些情况下你可能想要使用两张或者更多的背景图片,CSS是支持这么做的。 ⏱ 2020-12-30 11:26:02

📌 使用多个背景图片时,列表中排在前面的图片会渲染到排序靠后的图片上面 ⏱ 2020-12-30 11:26:12

📌 使用cover值可以调整背景图片的大小,使其填满整个元素,这样会导致图片的边缘被裁切掉一部分;使用contain值可以保证整个背景图片可见,尽管这可能导致元素的一些地方不会被背景图片覆盖(就像“letterboxing”效果[插图]) ⏱ 2020-12-30 11:36:39

📌 通过使用混合模式,我们可以把一张全彩色图片着色成单一色相的图片。 ⏱ 2020-12-30 11:50:38

📌 最终是完全使用背景色图层的颜色,但是明暗程度来自大熊图片。 ⏱ 2020-12-30 14:09:49

📌 CSS支持15种混合模式,每一种都使用不同的计算原理来控制生成最终的混合结果。对每一个像素来说,就是取一个图层上的像素颜色,与其他图层上对应像素的颜色拼合计算,生成一个新的像素颜色,最终生成一张混合图片。 ⏱ 2020-12-30 14:09:31

📌 这些混合模式又可以划分为五类:变暗、变亮、对比、复合和比较。 ⏱ 2020-12-30 14:11:27

📌 这时候就可以使用灰度图为图片手动添加胶片噪点效果或者其他纹理。 ⏱ 2020-12-30 14:13:12

📌 这种类型的效果可以通过对比混合模式overlay、hard-light或soft-light来实现。这个例子中,我们不希望更改图片的色相,因此使用一张灰度图片来提供纹理,这样就保留了原始颜色。 ⏱ 2020-12-30 14:13:22

📌 还有一个属性mix-blend-mode,可以融合多个元素。这样不仅可以混合图片,还可以把元素的文本和边框与容器的背景图片混合在一起。使用融合混合模式,可以把标题显示在图片上方,但遮住的图片部分依然可以显示出来,如图11-17所示。 ⏱ 2020-12-30 14:16:17

📌 这里我们使用了hard-light混合模式和中灰色文字颜色。 ⏱ 2020-12-30 14:23:51

第12章 对比、颜色和间距

📌 使用CSS实现设计师提供的视觉稿,是Web开发中很重要的一个环节。我们做这部分工作时,实际上是把艺术转化为代码。 ⏱ 2020-12-30 14:25:03

📌 相较于单页面的视觉稿,我们的CSS代码应该更具通用性。 ⏱ 2020-12-30 14:25:09

📌 你至少应该有一些设计师的基本思维,从设计师的角度去思考间距、颜色和排版等,这很重要。 ⏱ 2020-12-30 14:25:16

12.1 对比最重要

📌 对比是设计中的一种手段,通过突出某物来达到吸引注意力的目的。我们的眼睛和思维天生对模式比较敏感,一旦某种东西破坏了模式的整体效果,我们就自然而然地注意到了它。 ⏱ 2020-12-30 14:26:53

📌 若要起到对比的效果,页面必须先建立模式,就如同必须先有了规矩才能打破规矩。 ⏱ 2020-12-30 14:27:01

📌 还原了视觉稿只是完成了一部分工作,后续还要添加新特性和新内容,需要始终忠于设计师的愿景。基于此,我们看看做好这份工作需要考虑哪些因素。 ⏱ 2020-12-30 14:30:35

12.2 颜色

📌 从HSL颜色值可以看出,明度值是15%,而不是0%。使用灰色而非纯黑是常见做法。在背光式计算机屏幕上,纯白色背景(#fff)上的纯黑色文本会产生强烈的对比效果,很容易在阅读时造成视觉疲劳,特别是大段的文本。黑色背景上的白色文本也会有同样的问题。 ⏱ 2020-12-30 14:45:04

📌 WCAG同样提供了一个计算对比度的公式,但我从来不操心数学计算,因为使用工具更简单。在线就有很多可用的工具,搜索“CSS颜色对比检查器”(CSS colorcontrast checker)[插图]可以查看。 ⏱ 2020-12-30 14:46:34

12.3 间距

📌 处理间距时,需要知道什么时候应该使用内边距,什么时候应该使用外边距 ⏱ 2020-12-30 14:55:34

📌 标题和正文段落之间的30px,就不是这么简单了。如果你打算在两个元素之间设置30px的外边距,那么实际上这两行文字之间的间隔差不多是36px。 ⏱ 2020-12-30 15:11:15

📌 但是对于段落和标题这样的元素,内容盒子并不是只有显示出来的文字区域,元素的行高决定了内容盒子最终的高度,这要超出字符的顶部和底部 ⏱ 2020-12-30 15:05:22

📌 这样只有一行文字的元素,内容盒子的高度就是1.4em,文字在内部垂直居中。字号是16px,内容盒子的最终高度就是22.4px。额外的6.4px平均分配到文字的上方和下方。 ⏱ 2020-12-31 09:58:09

第13章 排版

📌 我们可以指定非系统字体,比如HelvetiaNeue,但只有那些碰巧安装了这款字体的用户才能正确显示,其他用户只能看到通用的回退方案。 ⏱ 2020-12-31 10:00:05

📌 Web字体使用@font-face规则,告诉浏览器去哪里找到并下载自定义字体,供页面使用。 ⏱ 2020-12-31 10:00:11

13.1 Web字体

📌 通过在线服务使用Web字体是最简单也最普遍的方式。常见的如下所示。❑ Typekit❑ Webtype❑ 谷歌字体 ⏱ 2020-12-31 10:01:35

📌 标题和正文分别使用不同的字体是很常见的。通常,一种字体是serif,另一种是sans-serif,但示例中的两种都是sans-serif。 ⏱ 2020-12-31 10:05:08

13.2 谷歌字体

📌 选择的字体越多,浏览器需要下载的就越多。Web字体是拖慢网页加载时间最大的几个元凶之一,仅排在图片之后。因此应该谨慎一些,只挑选自己需要的字体。 ⏱ 2020-12-31 10:21:25

13.3 如何使用@font-face

📌 @font-face规则定义了浏览器字体,以便在页面的CSS中使用。这里的第一条规则实际上是说,“如果页面需要渲染font-family为Roboto的拉丁字符,这些字符使用了正常的字体样式(非斜体)并且字重为300,那么就使用这个字体文件”。第二条规则类似,定义了一个粗体版本(字重为800)的Sansita字体。 ⏱ 2020-12-31 10:24:45

📌 src:提供了一个逗号分隔的浏览器可以搜索的地址列表,以local(Roboto Light)和local(Roboto-Light)开头,这样的话,如果用户的操作系统中恰好安装了名为Roboto Light或者Roboto-Light的字体,就使用这些字体。否则,就下载使用url()指定的woff2字体文件。 ⏱ 2020-12-31 10:34:46

13.4 调整字距,提升可读性

📌 我们回到页面上。现在Web字体加载好了,我们按照设计稿再调整一下。这里涉及两个属性:line-height和letter-spacing,这两个属性可以控制文本行之间的距离(垂直方向)和字符之间的距离(水平方向)。 ⏱ 2020-12-31 11:00:21

📌 为line-height和letter-spacing找到合适的值是件主观性很强的事情。最好的解决办法通常是多试几个值,如果两个值要么太紧凑要么太松散,那就取它们的中间值。幸运的是,下面介绍的这些经验法则可以为你提供帮助。 ⏱ 2020-12-31 11:09:41

📌 text-transform属性对你来说可能有点陌生。它可以把所有字母改成大写,不管HTML原始文本如何书写 ⏱ 2020-12-31 11:21:59

📌 lowercase是text-transform属性的另一个值,表示把所有字母都小写。还可以设置为capitalize,这样只把每个单词的首字母大写,其余字母保持HTML里的原始状态。 ⏱ 2020-12-31 11:20:52

13.5 恼人的FOUT和FOIT

📌 图13-12 FOUT(无样式文本闪动) ⏱ 2020-12-31 11:39:32

📌 这就是所谓的FOUT,即无样式文本闪动(Flash of Unstyled Text)。 ⏱ 2020-12-31 11:25:00

📌 图13-13 FOIT(不可见文本闪动) ⏱ 2020-12-31 11:39:29

📌 使用JavaScript可以监控字体加载事件,这样就可以更好地控制FOUT与FOIT的发生过程。还可以使用js库来帮助处理,我喜欢用一款名叫Font Face Observer的库。 ⏱ 2020-12-31 11:49:02

📌 polyfill ⏱ 2020-12-31 11:55:13

📌 建议同时勾选Disable Cache(禁用缓存)旁边的复选框,每次加载页面,所有的资源都会重新下载。这样就可以模拟出低网速条件下,网站最初的页面加载时用户会看到的样子。 ⏱ 2020-12-31 11:50:17

📌 font-display ⏱ 2020-12-31 14:39:27

14.1 从这边到那边

📌 transition-property这个属性可以指定哪些属性使用过渡。在示例中,关键字all意味着所有的属性变化都使用过渡。transition-duration属性代表过渡到最终值之前需要多长时间,本例中设置为0.5s,代表0.5s。 ⏱ 2020-12-31 14:41:43

14.2 定时函数

📌 比如linear、ease-in和ease-out ⏱ 2020-12-31 14:47:08

📌 定时函数是基于数学定义的贝塞尔曲线(Bézier curve)。 ⏱ 2020-12-31 14:47:35

📌 曲线的每个末端都有一条短直线——控制柄(handles),直线上有小圆点,称为控制点(control points)。点击并拖动小圆点可以改变曲线的形状,注意控制柄的长度和方向是如何“牵引”曲线的。 ⏱ 2020-12-31 14:47:53

📌 最后在1s的时刻移动到最终位置。 ⏱ 2020-12-31 15:05:22

15.1 旋转、平移、缩放和倾斜

📌 使用变换的时候要注意一件事情,虽然元素可能会被移动到页面上的新位置,但它不会脱离文档流。 ⏱ 2020-12-31 15:47:19

📌 变换元素不会导致其他元素移动,因此可能出现重叠 ⏱ 2020-12-31 15:47:09

📌 transform-origin: right bottom ⏱ 2020-12-31 15:48:09

15.2 在运动中变换

📌 SVG:一种更好的图标解决方案 ⏱ 2020-12-31 16:07:43

📌 很长一段时间里,图标使用的最佳实践是把所有图标放入单个图片文件,称之为精灵图(sprite sheet) ⏱ 2020-12-31 16:08:01

15.3 动画性能

📌 变换在浏览器中的性能要好得多。如果我们要对元素的定位使用动画(比如为left属性添加过渡效果),可以明显感受到性能很差。对复杂元素使用动画或者在页面内一次性对多个元素使用动画,问题尤其明显。这种性能问题在过渡(参见第14章)和动画(第16章将介绍)上都有体现。 ⏱ 2020-12-31 16:13:54

📌 如果我们要实现过渡或动画,无论什么类型,包括定位或大小操作,都应该尽可能考虑使用变换。 ⏱ 2020-12-31 16:13:58

📌 浏览器计算好了页面上哪些样式应用于哪些元素上之后,需要把这些样式转化成屏幕上的像素,这个过程叫作渲染(rending)。渲染可以分为三个阶段:布局、绘制和合成(如图15-12所示)。 ⏱ 2020-12-31 16:14:09

📌 在第一个阶段布局中,浏览器需要计算每个元素将在屏幕上占多大空间。因为文档流的工作方式,所以一个元素的大小和位置可以影响页面上无数其他元素的大小和位置。这个阶段会解决这个问题。 ⏱ 2020-12-31 16:15:39

📌 任何时候改变一个元素的宽度或高度,或者调整位置属性(比如top或者left),元素的布局都会重新计算。如果使用JavaScript在DOM中插入或者移除元素,也会重新计算布局。一旦布局发生改变,浏览器就必须重排(reflow)页面,重新计算所有其他被移动或者缩放的元素的布局。 ⏱ 2020-12-31 16:15:57

📌 这不会真正显示在屏幕上,而是在内存中绘制。页面各部分生成了很多的图层(layers)。 ⏱ 2020-12-31 16:16:14

📌 如果改变某个元素的背景颜色,就必须重新绘制它。但因为更改背景颜色不会影响到页面上任何元素的位置和大小,所以这种变化不需要重新计算布局。改变背景颜色比改变元素大小需要的计算操作要少。 ⏱ 2020-12-31 16:16:22

📌 这样安排是有好处的,因为GPU经过了充分的优化,比较适合做这类计算。 ⏱ 2020-12-31 16:16:52

📌 在合成(composite)阶段,浏览器收集所有绘制完成的图层,并把它们提取为最终显示在屏幕上的图像。合成过程需要按照特定顺序进行,以确保图层出现重叠时,正确的图层显示在其他图层之上。 ⏱ 2020-12-31 16:27:57

📌 当我们修改元素的这两个属性之一时,浏览器就会把元素提升到其自己的绘制图层并使用GPU加速。因为元素存在于自己的图层,所以整个图像变化过程中主图层将不会发生变化,也无须重复的重绘。 ⏱ 2020-12-31 16:28:06

📌 但如果修改的是动画的一部分,屏幕需要在一秒内发生多达几十次的更新,这种情况下渲染速度就很重要了。大部分的屏幕每秒钟会刷新60次。理想情况下,动画中每次变化所需的重新计算也要至少这么快,才能在屏幕上生成最流畅的运动轨迹。浏览器在每次重新计算的时候需要做的事情越多,越难达到这种速度。 ⏱ 2020-12-31 17:02:15

📌 设置了will-change: transform就表示我们将要改变元素的transform属性。 ⏱ 2020-12-31 17:02:35

📌 除非遇到性能问题,否则不要盲目添加该属性到页面,因为它会占用很多的系统资源。 ⏱ 2020-12-31 17:02:39

15.4 三维(3D)变换

📌 可以通过两种方式指定透视距离:使用perspective()变换或者使用perspective属性 ⏱ 2020-12-31 17:11:12

📌 。这个方法可以为单个元素设置透视距离,示例中我们直接为所有盒子做了相同的设置。这样就像为每个元素分别单独拍照,但是拍摄位置相同。 ⏱ 2020-12-31 17:08:54

📌 有时候我们希望多个元素共享同一套透视距离,就仿佛它们处于相同的3D空间中。 ⏱ 2020-12-31 17:15:28

📌 添加透视距离是3D变换中非常重要的部分。如果不设置透视距离,离得远的元素不会显得变小,离得近的元素也不会显得变大。 ⏱ 2020-12-31 17:10:32

📌 rotateY(180deg) ⏱ 2020-12-31 17:26:30

📌 transform-style: preserve-3d ⏱ 2020-12-31 17:28:57

第16章 动画

📌 关键帧(keyframe)是指动画过程中某个特定时刻。我们定义一些关键帧,浏览器负责填充或者插入这些关键帧之间的帧图像 ⏱ 2020-12-31 17:30:28

16.1 关键帧

📌 这些百分比代表每个关键帧发生于动画过程中的哪些时刻:一个在动画的开始(0%),一个在中间(50%),一个在终点(100%)。 ⏱ 2020-12-31 17:30:47

📌 层叠的第一部分是介绍样式表的来源。作者样式优先级高于用户代理样式,因为作者样式有比较高的优先级来源,但动画中应用的声明有更高的优先级来源。为某个属性添加动画的时候,会覆盖样式表中其他地方应用的样式。 ⏱ 2020-12-31 17:35:13

16.3 动画延迟和填充模式

📌 因为transform和opacity属性只应用在了动画执行期间。 ⏱ 2020-12-31 17:39:09

16.5 最后一点建议

📌 它一脚踩在设计领域,另一脚踩在代码世界 ⏱ 2020-12-31 17:43:54

📌 我最后再给你一条建议,就是保持好奇心。我已经向你介绍了CSS工具集里的一大批工具,但这些工具可以组合和匹配的方式是无穷无尽的。当你看到令人赞叹的Web页面的时候,打开浏览器的开发者工具,试着去弄清楚它是如何实现的。 ⏱ 2020-12-31 17:44:02

读书笔记

2.5 无单位的数值和行高

划线评论

📌 将代码清单2-21添加到样式表中。这个段落继承了行高1.2。因为段落字号是32px(2em × 16px,浏览器默认字号),所以此时行高的计算值为38.4px(32px×1.2) ^8292450-7mvSOqlzc - 💭 无单位数字,则行高等于数字*字体大小 - ⏱ 2020-12-11 14:14:44

3.1 元素宽度的问题

划线评论

📌 比如设置侧边栏宽度为calc(30% -3em)就能刚好并排放下两列,但是还有更好的解决办法。 ^8292450-7mvX7S3i3 - 💭 这里写的有问题,calc运算符前后需要保留空格,应该改成calc(30% - 3em) - ⏱ 2020-12-11 15:20:36

3.2 元素高度的问题

划线评论

📌 vertical-align声明只会影响行内元素或者table-cell元素。 ^8292450-7mAbsfcrR - 💭 inline, inline-block, table-cell - ⏱ 2020-12-14 10:06:04

5.2 弹性子元素的大小

划线评论

📌 flex属性是三个不同大小属性的简写:flex-grow、flex-shrink和flex-basis。在代码清单5-7里,只提供了flex-grow的值,剩下的两个属性是默认值(分别是1和0%),因此flex: 2等价于flex: 210%。通常首选简写属性,但也可以分别声明三个属性。 ^8292450-7mAC4s6H9 - 💭 flex-basis默认为auto,但是在赋flex单值(number)的时候flex-basis:0,“a <number>: In this case it is interpreted as flex: <number> 1 0; the <flex-shrink> value is assumed to be 1 and the <flex-basis> value is assumed to be 0.” (mdn英文文档中写了,中文的没写) - ⏱ 2020-12-14 16:52:29

12.3 间距

划线评论

📌 内容盒子的最终高度就是22.4px ^8292450-7mYQ8ZYJk - 💭 16*1.4 - ⏱ 2020-12-30 15:07:26

本书评论

书评 No.1

虽然书里有一些小错误,但是整体读下来收获很多。

⏱ 2020-12-31 17:46:47