3.1 HTML 和 CSS 的关系


3.1 HTML 和 CSS 的关系

本节摘要:CSS 是 HTML 的表现层搭档:选择器定位文档树上的元素,声明块描述外观,层叠与继承两套机制裁决冲突。本节讲样式挂载的三条通道与优先级体系、层叠的排序规则、继承的边界,以及"结构与表现分离"这条原则在真实工程里的含义与代价。

学习目标

阅读完本节,你应当能够:

  1. 比较内联、内嵌、外链三种样式通道的适用场景;
  2. 说出层叠排序的四个层级:来源与重要性、特异性、书写顺序;
  3. 区分可继承与不可继承属性,并知道继承来的值随时可被覆盖;
  4. 用"三问排查法"定位任何样式不生效的问题;
  5. 说明结构与表现分离原则的价值与边界。

一个古老的问题:样式写在哪

CSS 诞生前,样式信息直接写在 HTML 标签里——字体、颜色全是元素属性。页面一多,灾难降临:换个配色要改几百个标签,一份内容想换三套外观更是不可能。CSS 的解法是一次解耦:内容与结构留在 HTML,外观规则集中成样式表,靠选择器连接两者。要理解这对搭档,先看样式进入页面的三条通道。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>三条样式通道</title> <!-- 通道一:内嵌 —— 写在当前文档里 --> <style> .intro { color: #2c3e50; } </style> <!-- 通道二:外链 —— 独立样式表文件,可被全站复用 --> <link rel="stylesheet" href="site.css"> </head> <body> <!-- 通道三:内联 —— 直接写在元素上 --> <p class="intro" style="color: #c0392b;">我到底听谁的?</p> </body> </html>

三通道的工程定位差异很大。外链是生产默认:样式集中、可缓存复用(第二个页面起样式零下载)、可被工具压缩与审计。内嵌适合单页场景或关键首屏样式(减少一次请求换取首屏速度,第 5 章性能节详述)。内联是第 1 章讲过的高危工具——优先级极高、无法复用、无法响应媒体查询,正当场景只剩一次性覆写、脚本动态计算值、邮件模板。

通道之外还有第四种"来源":浏览器默认样式(每个元素未加任何样式时的长相)与用户自定义样式。它们与作者样式一起参与下面的层叠裁决。

层叠:同名规则的裁决法庭

CSS 名字里的第一个 C 就是层叠——多条规则命中同一元素的同一属性时,谁说了算。裁决按四级排序,逐级分胜负:

第一级:来源与重要性。 样式来源分浏览器默认、用户、作者(页面开发者)三档,正常情况下作者 > 用户 > 默认;但标了 important 的声明越级压过一切普通声明,同 important 再比来源(作者 important 仍胜)。这就是为什么 !important 一出,后面的覆盖全要靠另一个 important——它是裁决法庭的最后通牒,也是样式失控的开端。

第二级:特异性。 都不 important 时比选择器的"分量"。速算规则:id 记一个百位、类/属性/伪类记十位、元素/伪元素记个位。#nav .item(一百一十)胜过 .list .item(二十),后者又胜过 ul li(二)。特异性相等才进第三级。

第三级:书写顺序。 特异性也相同,后写的赢。这就是"同一文件里重复定义一个类的样式,后面的覆盖前面的"的原因。

第四级:都不命中,看继承与默认值。 属性从父元素继承来,或落到浏览器默认值。

03-01-fig01

裁决顺序就是调试顺序。样式不生效时按"三问"排查:规则选中它了吗(开发者工具里看规则列表有没有灰掉)、是不是被打败了(命中的规则里该属性有没有被划横线)、值是不是继承来的(面板里"继承自"分支)。三问走完,答案必现。

继承:家族的默认手艺

继承是 CSS 的省力机制:一部分属性会自动从父元素传给后代,最常见的可继承族是文字类——颜色、字号、字体、行高、字重,以及光标、可见性等。不可继承的大头是盒模型与布局类——宽度、边距、边框、背景。设计的道理是:文字气质适合全家统一,盒子尺寸各自为政。

两个配套关键词要会用。inherit 强制继承一个默认不继承的属性(比如让子元素边框颜色跟随父元素);initial 打回浏览器默认值。日常工程里继承最大的价值是"在 body 上设一次字体字号,全页受益",以及理解一个经典现象:给容器设了颜色,链接没变色——因为链接有浏览器默认的紫色专属样式,特异性压过了继承来的值,要改得直接选中链接本身。

<style> body { font-family: sans-serif; color: #333; } .box { color: #2980b9; } /* 文字颜色可继承 */ .box { border: 1px solid #ccc; } /* 边框不继承,只属于 .box */ </style> <body> <div class="box"> 我和我的文字子孙都是蓝色。 <span>继承让我省了一行规则。</span> </div> </body>

结构与表现分离:原则及其代价

前三章反复出现的这条原则,现在可以给出完整表述:HTML 表达"内容是什么",CSS 表达"内容长什么样",两者不越界。越界的反面教材两头都有:HTML 里用 b、font 标签和内联样式堆外观(表现入侵结构),或者用类名编码外观信息(类名叫"红色大字",改版时类名与实际样式一起撒谎——这就是 BEM 等方法论坚持"类名描述是什么而非长什么样"的原因)。

分离的红利在前文都出现过:换肤不动结构、样式表全站复用、语义结构保持干净。但也要诚实交代它的边界:完全的分离是理想态,真实项目里总有少量"组件级耦合"(某个结构的样式只为它而生)与关键内联(首屏性能)。工程的答案是"分离为主、例外有据"——例外出现时,注释一行原因,让后来者知道这是决策不是疏忽。

层叠之外:值的一个特殊关键字

有一个关键字不属于四级裁决却在日常工程反复出现——currentColor。它表示"取当前元素的文字颜色",最常见的用法是让边框、图标描边自动跟随文字颜色:按钮文字换色时边框与内嵌 SVG 图标同步变,不用多处改。它体现了 CSS 设计的一个巧思:颜色继承的管道被开放成了可引用的变量。正式的变量机制则是自定义属性——以双连字符开头声明、用 var 函数取用,可以在根元素上定义全站色板:

:root { --brand: #2980b9; --ink: #2c3e50; } .button { background: var(--brand); color: #fff; } .title { color: var(--ink); border-bottom: 2px solid var(--brand); }

换肤功能(暗色模式)就是在根元素上整组替换变量值,全站颜色一次切换。变量机制把"主题"从几百条规则的重写变成了几十个值的替换,是现代样式架构的地基。本节立个坐标,第 5 章与实战章会用它组织完整样式体系。

高频疑问三则

问:样式表放在 head 还是 body 末尾?
样式表放 head,且越早越好。浏览器渲染页面需要样式信息,样式表放底部会出现"先裸奔后穿衣服"的闪烁——用户看到无样式内容再突然跳变。脚本恰恰相反(放 body 末尾或加 defer),因为它可能阻塞解析,这是第 5 章性能节的主题。记口诀:样式前置、脚本后置。

问:为什么改了样式不生效,重启浏览器也没用?
八成是缓存。开发者工具的网络面板勾选禁用缓存再刷新,立刻分辨是"没生效"还是"没下载到新文件"。层叠三问查的是逻辑,缓存查的是物流,物流问题比逻辑问题更常见。

问:继承和层叠谁先谁后?
继承是兜底不是裁决:只有当没有任何声明命中该元素的这个属性时,继承值才生效;任何直接命中(哪怕特异性最低)都压过继承。所以"继承来的样式改不动"的感觉,其实是没有选中元素本身——给目标元素加一条低特异性规则就能覆盖。

分层视角回顾

把本章放进全册的分层图里再定位一次:浏览器把网页拆成结构、表现、行为三层,CSS 承担表现层,但它与另外两层都有标准化的接口。向结构层,接口是文档树与选择器——样式只能挂在树上,改结构就会影响样式命中;向行为层,接口是脚本可以读写元素的样式与类名——脚本改类不改内联样式,是行为层与表现层协作的推荐姿势(样式定义在样式表里,脚本只切换类名开关,两层仍然各司其职)。理解这两个接口,三层之间的"谁影响谁"就再无玄学:结构决定选择器命中,样式不回改结构,脚本通过类名操纵表现。第 5 章讲交互时会用这个模型解释"状态类"模式,综合实战章则会让它落地成代码。

动手实验:亲眼看一次层叠裁决

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>层叠实验</title> <style> p { color: #7f8c8d; } /* 特异性 0-0-1 */ .note { color: #2980b9; } /* 特异性 0-1-0 */ #special { color: #27ae60; } /* 特异性 1-0-0 */ .note { color: #e67e22 !important; } /* important 越级 */ </style> </head> <body> <p class="note" id="special" style="color:#8e44ad"> 我身上有五条颜色规则,最终是橙色(important 胜出)。 </p> <p class="note">我是蓝色:同为类选择器,后写的 .note 胜了元素选择器。</p> <p>我只是灰色:元素选择器孤家寡人。</p> </body> </html>

打开后用开发者工具选中第一个 p:五条规则全部列出,四条被划掉,胜出者标注了 important。再把 important 那行删掉刷新——胜者变成紫色内联(通道层面内联特异性最高)。每删一层刷新一次,四级裁决逐级现形。这个十分钟的实验比背十遍规则记得牢。

⚠️ 常见坑:用 important"修"样式。important 治标不治本——它把特异性竞赛升级成军备竞赛,下一个要覆盖它的人只能再堆 important。正确动作是回头降低规则特异性或调整选择器,important 只留给确实需要压过一切的极少数场景(如覆盖第三方组件库的内联样式)。

本节要点回顾

(层叠与继承是全章推理的地基,实验做完若仍有模糊,把四级裁决那张图默画一遍,画得出就是真懂了。)

(自定义属性那一段可以先混个脸熟,第 5 章实战节会用它搭完整色板体系,届时回看正好。)

(回顾前补一句方法:若对层叠裁决还没手感,把本章的层叠实验再做一遍——逐条删除胜出规则再刷新,删规则的顺序就是四级裁决的倒放,做完手感就有了。)

  • 三通道定位:外链是生产默认(缓存与复用),内嵌管单页与首屏,内联是高危工具。
  • 层叠四级裁决:important 与来源 → 特异性(id 百位、类十位、元素个位)→ 书写顺序 → 继承与默认值。
  • 继承只传气质不传尺寸:文字类可继承,盒模型不可;链接的默认样式能压过继承。
  • 三问排查法:选中了吗、被打败了吗、值哪来的——开发者工具一次全答。
  • 分离为主、例外有据:结构与表现解耦是默认答案,偏离时留痕。

给初学者一个忠告:这一节的概念密度是全章最高的,层叠与继承又是后续两节的推理基础。如果读一遍记不住裁决顺序,别背——回头把层叠实验做完,四级裁决会在你眼前逐级现形一次,比文字记忆牢固得多。概念筑基的学法从来不是背诵条目,而是让每条规则至少在浏览器里发生过一次。

样式怎么挂、冲突怎么裁都清楚了,下一节讲挂载的前提——规则凭什么落到这个元素上:选择器的寻址系统与工程用法。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U