把样式交给浏览器的三条路

本页本身就是「方式二」的例子,所以你现在看到的所有排版都来自它自己内部那份 <style>。

三种写法

<!-- ① 外链样式表:正式项目的唯一正确做法 -->
<link rel="stylesheet" href="/css/main.css">

<!-- ② 页面内 style 标签:单页 demo、邮件模板、关键 CSS 内联 -->
<style> body { max-width: 700px; margin: 0 auto; } </style>

<!-- ③ @import:写在 CSS 文件顶部,会串行加载 -->
<style> @import url("/css/reset.css"); </style>

<!-- ④(补充)元素上的 style 属性:权重最高,只用于必须动态计算的值 -->
<div style="width: 42%">…</div>
方式优点代价
link 外链多页共享、可被浏览器长期缓存、可与 HTML 并行下载多一次请求
<style> 内联块零请求、适合首屏关键 CSS不随页面缓存复用,改一次要动 HTML
@import语法上像「CSS 的 include」,组织起来方便被引入的文件要等主 CSS 下载完才开始下载,等于串行;也不便于工具做作用域分析。生产环境几乎总该换成 link
style="" 元素属性优先级最高,能被 JS 单点修改无法复用、无法用伪类、难以维护

层叠的起点:谁赢

下面这一行文字被三条规则同时命中,最终显示成红色,因为 id + class 的权重(110)压过了 元素 + class(11)和 class(10):

这一行是什么颜色,由层叠顺序决定,而不是由谁写在最后决定。

.demo-text        { color: #57606a; }   /* 0,1,0 */
p.demo-text       { color: #8250df; }   /* 0,1,1 */
#only-one.demo-text { color: #cf222e; } /* 1,1,0 ← 生效 */

完整顺序是:是否 !important → 来源与层(@layer)→ 权重 → 书写顺序。前三步比不出结果时才看谁写在后面,所以「后写的覆盖先写的」只在权重相同的前提下成立。第四章把这条链路展开。

一个立刻能用的最小结构

/* 选择器 */        命中谁
h1, h2 {           /* 分组:两个都命中 */
  color: #24292f;  /* 声明:属性 + 值 */
  line-height: 1.3;
}

花括号内每条形如「属性: 值;」叫一条声明,整个花括号叫声明块;缺分号会导致下一条声明被吞掉,是新手最难自查的语法错误之一(第二、三节会演示)。