CSS语法与规则 — 重学CSS

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我是"},{"type":"text","marks":[{"type":"strong"}],"text":"三钻"},{"type":"text","text":",一个在"},{"type":"text","marks":[{"type":"strong"}],"text":"《技术银河》"},{"type":"text","text":"中等你们一起来终生漂泊学习。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"点赞是力量,关注是认可,评论是关爱!下期再见 👋"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"进入重学 CSS 的第一步,首先需要找到一些线索。我们在前面的课程中讲学习方法的部分也讲过,要想建立知识体系骨架,我们需要一个完备性更权威,更全的线索。但是 CSS 现在标准的状态非常复杂,所以我们没有办法找到一份像 JavaScript 或者 HTML 中比较完备的现形标准,能把 CSS 的一切都浓缩在内。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不过这种情况也是我们平时学习知识的一种常态,知识并不是有人给我们总结好一本书,或者能有一个地方包含了所有的知识。一般来说知识都会分布在各种不同的文档当中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根据 Winter 老师比较喜欢学习一个线索,凡是对于编程语言,都会先从它的语法去了解它。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 CSS 也不例外,它也有自己的一套语法体系。但是 CSS 标准是分散开的,我们想找到它完整的语法非常的不容易的。所以我们这里先从 CSS 2.1 语法标准开始。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS 2.1 语法标准"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CSS 2.1 确实是一个比较老的版本了,但是它有一个好处,在 2.1 的版本的时候建立了一个 Snapshot,也就是说没有其他版本去替代它。所以 CSS 2.1 的 Grammar Summary 部分是当时一个比较完整的一份语法列表。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当然现在我们已经大量的引入了 CSS3 了,所以这里面会有一些语法差异和不全。但是总体来讲是一个不错的起点,让我们可以先开始认识 CSS 的语法基础。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里的语法是使用 “"},{"type":"text","marks":[{"type":"strong"}],"text":"产生式"},{"type":"text","text":"” 来表达的。但是这里会有一些 CSS 中特别的表达方式和标准:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"[ ]"}]},{"type":"text","text":" —— 方括号代表组的概念"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"?"}]},{"type":"text","text":" —— 问号代表可以存在和不存在"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"|"}]},{"type":"text","text":" —— 单竖线代表 “或” 的意思"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"*"}]},{"type":"text","text":" —— 星号代表 0 个或 多个"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"CSS 总体结构"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"@charset"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"@import"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"rules —— 多个规则,这里面的规则没有顺序要求"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + @media"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + @page"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + rule —— 这里基本上就是我们平时写的 CSS 样式规则部分"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们平时写都是在写普通的 CSS 规则,"},{"type":"codeinline","content":[{"type":"text","text":"charset"}]},{"type":"text","text":" 我们基本都不会用,一般我们都会用 "},{"type":"codeinline","content":[{"type":"text","text":"UTF-8"}]},{"type":"text","text":"。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里讲到的是 CSS 2.1 的 CSS 结构,在 CSS3 中我们有更多的 "},{"type":"codeinline","content":[{"type":"text","text":"@"}]},{"type":"text","text":" 规则 和 CSS 规则,我们首先要在 CSS3 中找到这两块的所有内容,然后补充道这个总体结构中,那么我们就可以形成 CSS 的总体结构。这时候我们对 CSS 的语法认识就有完备性了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS @ 规则研究"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@charset"}]},{"type":"text","text":": https://www.w3.org/TR/css-syntax-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 CSS syntax 3 中在 CSS 2.1 中做了一个重新的定义"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是相对 CSS 2.1 基本没有什么变化"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@import"}]},{"type":"text","text":": https://www.w3.org/TR/css-cascade-4/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后 import 就在 css cascade 4 的规范里面"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因为 CSS 的全称就是 Cascade Style Sheet(级联表)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 import 属于级联规则之一"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@media"}]},{"type":"text","text":": https://www.w3.org/TR/css3-conditional/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Media 不是在我们的 media query 标准里"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它在 CSS3 的 conditional 标准里"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是在 media 的 conditional 标准中又去引用了 media query,规定了 media 后面的一部分的查询规则"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我们常常去讲 media query 是一个新特性,其实它并不是,它是类似一个预置好的函数的一个规范"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"真正把 Media 特性真正引入到 CSS3 当中,是通过 CSS3 中的 conditional 标准"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那么 Conditional,就是 “有条件的”,顾名思义就是用来控制一些规则在有效条件下才会生效"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" @page"}]},{"type":"text","text":": https://www.w3.org/TR/css-page-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"page 是有一份单独的 CSS3 标准来表述它"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"就是 css page 3 它主要是给我们需要打印的页面所使用的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"理论上这个叫做分页媒体,其实主要的分页媒体就是打印机"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们的页面是不会有分页的"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@counter-style"}]},{"type":"text","text":": https://www.w3.org/TR/css-counter-styles-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们平时写列表的时候会有一个 counter"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是列表最前面的那个 “小黑点” 或者是 “小数字”"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"@keyframes"}]},{"type":"text","text":": https://www.w3.org/TR/css-animations-1/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"keyframes 是用于我们的动画效果定义的"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@fontface"}]},{"type":"text","text":": https://www.w3.org/TR/css-fonts-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"fontface 就是我们使用 web font 功能时候用到的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它可以用来定义一切字体"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由此延伸出一个技巧叫 Icon font"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@supports"}]},{"type":"text","text":": https://www.w3.org/TR/css3-conditional/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个同样是来自于 conditional 的标准"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是用来检查某些 CSS 的功能是否存在的"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"supports 是一个比较尴尬的存在,自己就是隶属于 CSS3,所以它本身是有兼容性问题的导致没办法用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以现在基本上不推荐使用 support 来检查 CSS 兼容性"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因为我们检查的那个属性,比我们 support 这个规则兼容性要更好,所以根本检查不了"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"估计可能 4~5年后,CSS 新出来的新特性我们再用 support 来检查会更好一点"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"@namespace"}]},{"type":"text","text":": https://www.w3.org/TR/css-namespaces-3/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在 HTML 里面除了 HTML 命名空间,还引入了 SVG、MathML 等这样的其他的命名空间的标记和标签"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 CSS 里面有了对应的设施,其实主要是 一个完备性的考量,并不是一个特别重要的规则"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里不是完整的列表,还有 3 个规则,因为 它们本身状态太年轻在讨论状态,要不就是已经没有浏览器支持了,或者是已经被废弃了。分别有 "},{"type":"codeinline","content":[{"type":"text","text":"document"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"color-profile"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"font-feature"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"然后最常用的有三种:"},{"type":"codeinline","content":[{"type":"text","text":"@media"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"@keyframes"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"@fontface"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"CSS 规则结构"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里我们选中了 HTML 所有的 DIV 并且给予它们一个 "},{"type":"codeinline","content":[{"type":"text","text":"blue"}]},{"type":"text","text":" 的背景颜色。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"css"},"content":[{"type":"text","text":"div {\n background-color: blue;\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过以上代码示例,我们看到一段 CSS 代码是有分为 "},{"type":"codeinline","content":[{"type":"text","text":"选择器"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"声明"}]},{"type":"text","text":" 两部分的。在我们《实战中理解浏览器原理》的文章中,我们编写我们的 "},{"type":"codeinline","content":[{"type":"text","text":"CSS parsor"}]},{"type":"text","text":" 的时候,就是把 CSS parse 成 selector 部分和 declaration 部分。我们这里也会按照这个方法来理解 CSS 规则。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"选择器 —— selector ("},{"type":"codeinline","content":[{"type":"text","text":"div"}]},{"type":"text","text":")"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"声明 —— declaration"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Key —— 键 ("},{"type":"codeinline","content":[{"type":"text","text":"background-color"}]},{"type":"text","text":")"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Value —— 值 ("},{"type":"codeinline","content":[{"type":"text","text":"blue"}]},{"type":"text","text":")"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"CSS 规则标准"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Selector 选择器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Level 3"},{"type":"text","text":" —— https://www.w3.org/TR/selectors-3/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Selectors_group —— 选择器组:用逗号分隔"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Selector —— 选择器:需要用 combinator (组合器) 把多个简单选择器拼在一起的"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Combinator —— 组合器:"},{"type":"codeinline","content":[{"type":"text","text":"+"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":">"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"~"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"空格"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Simple"},{"type":"text","marks":[{"type":"italic"}],"text":"selector"},{"type":"text","text":"sequence —— 简单选择器:"},{"type":"codeinline","content":[{"type":"text","text":"类型选择器"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"*"}]},{"type":"text","text":" 一定会在最前面,然后可以是 "},{"type":"codeinline","content":[{"type":"text","text":"ID"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"class"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"attr"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"pseudo"}]},{"type":"text","text":"等选择器"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Level 4"},{"type":"text","text":" —— https://www.w3.org/TR/selectors-4/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Level 4 和 Level 3 是非常的相似的,但是它的选择器更复杂"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 增加了很多的伪类选择器、“或” 和 “与” 的关系"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 而且它的 NOT 也更强大"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + Level 4 的话我们看一看拓展思路就可以了,因为从 2018年12月 开始也没有再更新了"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 所以目测是遇到问题了,处于比较难推动的阶段,所以投入使用还有很漫长的路要走"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Key"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Properties|性质"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Variables|CSS 变量—— https://www.w3.org/TR/css-variables/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 可以声明一个双减号开头的变量:"},{"type":"codeinline","content":[{"type":"text","text":"--main-color: #06c"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 然后我们可以在子元素中使用这些 CSS 变量了 "},{"type":"codeinline","content":[{"type":"text","text":"color: var(--main-color)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 可以跟其他的函数进行嵌套:"},{"type":"codeinline","content":[{"type":"text","text":"--accent-background: linear-gradient(to top, var(--main-color), white);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 使用 "},{"type":"codeinline","content":[{"type":"text","text":"var()"}]},{"type":"text","text":" 函数的时候是可以给默认值的,传入第二个参数就是默认值:"},{"type":"codeinline","content":[{"type":"text","text":"var(--main-color, black)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + CSS 变量处理可以用作 value,还可以用作 key:先声明了"},{"type":"codeinline","content":[{"type":"text","text":"--side: margin-top"}]},{"type":"text","text":" 然后就可以这样使用 "},{"type":"codeinline","content":[{"type":"text","text":"var(--side): 20px"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Value"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Level 4 —— https://www.w3.org/TR/css-values-4/"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 它也是 working draft (工作草稿) 状态,但是实现状态非常的好"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 而且这个版本一直有保持更新,最后一次更新是 2019年1月份"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 数字类型有:"},{"type":"codeinline","content":[{"type":"text","text":"整型"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"百分比"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"浮点型"}]},{"type":"text","text":"还有"},{"type":"codeinline","content":[{"type":"text","text":"带维度 (Dimensions)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 长度单位有:"},{"type":"codeinline","content":[{"type":"text","text":"相对单位 (em, ex, cap, ch ... )"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"视口单位 (vw, vh, vi, vb, vmin, vmax)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"绝对单位 (cm, mm, Q, in, pt, pc px)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 其他单位:"},{"type":"codeinline","content":[{"type":"text","text":"弧度单位 (deg, grad, rad, turn)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"时间单位 (s, ms)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"频率单位 (Hz, kHz)"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"分辨率单位 (dpi, dpcm, dppx)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 数据类型:"},{"type":"codeinline","content":[{"type":"text","text":"颜色 "}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"图片 "}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"2D 位置 "}]},{"type":"text","text":" 等类型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" + 函数:"},{"type":"codeinline","content":[{"type":"text","text":"计算 cal()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"最小值 min()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"最大值 max()"}]},{"type":"text","text":" 、"},{"type":"codeinline","content":[{"type":"text","text":"范围剪切 clamp()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"切换value toogle()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"属性引用 attr()"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"使用爬虫收集整套 CSS 标准"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过上面讲到的几个部分,我们已经了解了整个 CSS 的架构。但是我们发现整个的 CSS 标准是散落在几份标准当中的,为了我们更好的阅读标准,我们想拿到一份比较完整的标准列表是需要我们做一些工作的。很多时候我们都是需要在零散的标准里面,去搜集一些共性的内容。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下来我们来做一个小实验,通过类似爬虫的方法,在 W3C 网站上抓取标准的内容。然后我们对他进行一些处理,方便我们后续的一些工作。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我们打开 W3C 的标准和草稿的列表页:https://www.w3.org/TR/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里我们可以看到所有的 W3C 的标准和草稿,但是这里我们只需要 CSS 部分的。如果我们检查元素中查看,我们可以看到其实所有的数据都已经挂载在 DOM 上了,只是前端做了筛选分页而已。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我们就可以用一段代码,直接复制到浏览器的 "},{"type":"codeinline","content":[{"type":"text","text":"console"}]},{"type":"text","text":" 中运行就可以筛选出所有 CSS 相关的文章列表了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"// 获取 CSS 相关的标准列表\nJSON.stringify(\n Array.prototype.slice\n .call(document.querySelector('#container').children)\n .filter(e => e.getAttribute('data-tag').match(/css/)) // 找到有 CSS tag 的\n .map(e => ({ name: e.children[1].innerText, url: e.children[1].children[0].href })) // 只获取标题名字和链接\n);"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最终输入的内容如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6f/6f09cb26270a1e6b317337241ac92f3c.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后我们点击下方的 \""},{"type":"codeinline","content":[{"type":"text","text":"Copy"}]},{"type":"text","text":"\" 即可复制,把这个 JSON 内容保存在一个 JavaScript 文件里面,并且赋予一个变量叫 "},{"type":"codeinline","content":[{"type":"text","text":"standards"}]},{"type":"text","text":"。在我们后面的爬虫代码中需要用到。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 这里我们用一个简单的方法来获取爬取信息,就是在 W3C 原本的页面上开启一个 "},{"type":"codeinline","content":[{"type":"text","text":"iframe"}]},{"type":"text","text":",这样我们就可以忽略掉跨域的问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"let standards = [...] // 这里面的内容就是我们刚刚从 W3C 网页中爬取到的内容\n \nlet iframe = document.createElement('iframe');\ndocument.body.innerHtml = '';\ndocument.body.appendChild(iframe);\n\nfunction happen(element, event) {\n return new Promise(function (resolve) {\n let handler = () => {\n resolve();\n element.removeEventListener(event, handler);\n };\n element.addEventListener(event, handler);\n });\n}\n\nvoid (async function () {\n for (let standard of standards) {\n iframe.src = standard.url; // 让 Iframe 跳转到每个 standards 中的详情页面\n console.log(standard.name); \n await happen(iframe, 'load'); // 等待 iframe 中的页面打开完毕\n }\n})();"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后我们需要的信息就是属性表格中的内容:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/df/df54bdfd5e69cdccc018c344200127a4.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我们看一下这个 table 的 HTML 代码,我们会发现这个 table 都是有一个 class 名叫 "},{"type":"codeinline","content":[{"type":"text","text":"propdef"}]},{"type":"text","text":" 的。我们就可以用这个特性来获取这个表格中的内容了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以我们就可以在 "},{"type":"codeinline","content":[{"type":"text","text":"await happen(iframe, 'load')"}]},{"type":"text","text":",后面添加一行代码来答应这个表格的 DOM 元素来看一下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"let iframe = document.createElement('iframe');\ndocument.body.innerHTML = '';\ndocument.body.appendChild(iframe);\n\nfunction happen(element, event) {\n return new Promise(function (resolve) {\n let handler = () => {\n resolve();\n element.removeEventListener(event, handler);\n };\n element.addEventListener(event, handler);\n });\n}\n\nvoid (async function () {\n for (let standard of standards) {\n iframe.src = standard.url;\n console.log(standard.name);\n await happen(iframe, 'load');\n console.log(iframe.contentDocument.querySelectorAll('.propdef')); // 这里答应出表格的内容\n }\n})();"}]},{"type":"heading","attrs":{"align":null,"level":1}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b34c995f506fd74ab4d6e4adb20b4706.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d0/d06f14bbb80ef4c8388a1e33bb8cd840.gif","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章