首页  |  学习总览  |  ← 返回学习总览 阶段一 · 第 1 章,共 10 章
阶段一 · 预计 60 小时

HTML 与 CSS —— 网页的骨骼与皮肤

本章从「网页到底是什么」讲起,手把手带你掌握语义化 HTML、盒模型、Flexbox、Grid、响应式设计与动画。学完本章,你能独立把任何原型图还原成静态页面。

1网页是怎么工作的

先建立全局认知:网页从哪来,浏览器又做了什么。

1.1 三个角色:浏览器、服务器、你

你在浏览器输入网址,本质上是做了一次「请求-响应」的往返:

// 你(客户端)                                  // 服务器
你输入网址 → 浏览器把网址解析为请求 → 发给服务器
                                          → 服务器返回 HTML 文件(+CSS+JS)
浏览器拿到 HTML → 解析 → 渲染成你看到的页面

关键认知:网页的「原材料」是一段文本(HTML 代码),浏览器负责把它翻译成可视化的页面。服务器上存的是代码文件,你看到的是渲染结果。

1.2 网址(URL)的结构

https://www.example.com:443/path/page.html?name=zhangsan#top 为例:

部分示例含义
协议https://怎么通信(还有 http://、file://)
域名www.example.com服务器是谁(人话地址)
端口:443服务器的哪个门(https 默认 443,可省略)
路径/path/page.html服务器上的哪个文件
查询参数?name=zhangsan传给页面的数据(键=值)
锚点#top页面内定位到 id 为 top 的元素

1.3 HTML、CSS、JavaScript 的分工

语言类比职责
HTML骨骼定义结构:页面上有哪些内容块(标题、段落、按钮…)
CSS皮肤定义样式:每个内容块长什么样(颜色、大小、位置…)
JavaScript肌肉定义行为:点击按钮后发生什么、数据怎么变化
💡 一个经典比喻帮你记 盖房子:HTML 是钢筋水泥(结构),CSS 是装修设计(外观),JavaScript 是水电智能系统(功能)。三者缺一不可。

1.4 创建你的第一个网页

打开任意编辑器(推荐 VS Code),新建文件 index.html,输入:

<!-- index.html -->
<!DOCTYPE html>                 <!-- 告诉浏览器:这是现代 HTML5 文档 -->
<html lang="zh-CN">              <!-- 根元素,lang 声明页面语言 -->
<head>                          <!-- 头部:放页面的「元信息」,不显示在页面上 -->
  <meta charset="UTF-8">        <!-- 字符编码,中文不乱码的关键 -->
  <title>我的第一个页面</title>  <!-- 浏览器标签页上的标题 -->
</head>
<body>                          <!-- 主体:所有用户能看到的内容都在这 -->
  <h1>你好,世界!</h1>
  <p>这是我用 HTML 写的第一个页面。</p>
</body>
</html>

保存后用浏览器打开这个文件(双击即可),你就能看到「你好,世界!」。恭喜,你已经有第一个网页了。

✅ 动手必做 从现在开始,每个示例都要亲手敲一遍,再关掉文档重写一遍。这一步决定了你三年后的水平。
2HTML 基础

掌握标签语法、文档结构、常用标签与语义化。

2.1 标签、元素、属性

HTML 由「元素」组成,元素用「标签」标记,标签可以带「属性」:

<!-- 开始标签  属性     内容     结束标签 -->
<a href="https://x.com" target="_blank"> 点我 </a>
    ↑      ↑                 ↑
  标签名   属性(名="值")   内容
  • 双标签:成对出现(如上),大多数标签是这样。
  • 单标签:自闭合,如 <img><br><hr>
  • 嵌套:元素可以套元素,但必须正确嵌套(先开的后关):<div><p>对</p></div>

2.2 常用文本标签

标签作用示例效果
<h1>~<h6>标题(1 最大,6 最小)大标题 → 小标题
<p>段落一段文字
<a>超链接链接
<img>图片(单标签)🖼️
<ul>/<li>无序列表• 条目
<ol>/<li>有序列表1. 条目
<strong>加粗(语义:重要)重要
<em>斜体(语义:强调)强调
<br>换行(单标签)
<hr>水平分割线(单标签)————
⚠️ 常见坑:空格与换行 HTML 里连续多个空格只会显示一个,换行也被当成一个空格。想保留格式用 <pre>,想强制空格用 &nbsp;

2.3 图片与链接的细节

<!-- 图片:src 是来源,alt 是图片加载失败时显示的文字(无障碍必需) -->
<img src="images/logo.png" alt="公司 logo" width="120">

<!-- 链接:href 目标;target="_blank" 新标签页打开 -->
<a href="https://example.com" target="_blank" rel="noopener">外部链接</a>
<a href="mailto:me@x.com">发邮件</a>
<a href="#s3">跳到本页 s3 区域</a>   <!-- 锚点链接:目标元素的 id -->
🚨 必须记住 外链加 target="_blank" 时必须加 rel="noopener",否则有被钓鱼攻击(反向 tabnabbing)的安全风险。这是面试也爱考的点。

2.4 表格

<table>
  <thead>                            <!-- 表头区 -->
    <tr>                              <!-- 行 -->
      <th>姓名</th><th>年龄</th>      <!-- th:表头单元格 -->
    </tr>
  </thead>
  <tbody>                            <!-- 数据区 -->
    <tr><td>张三</td><td>25</td></tr>  <!-- td:普通单元格 -->
  </tbody>
</table>

合并单元格:colspan="2" 横向合并、rowspan="2" 纵向合并。

2.5 语义化:为什么老手都强调它

「语义化」= 用含义正确的标签表达内容,而不是用一堆 <div> 包一切。看一个对比:

<!-- ❌ 反面:全是 div -->
<div class="header">网站标题</div>
<div class="nav">导航链接</div>
<div class="main">正文内容</div>
<div class="footer">版权信息</div>

<!-- ✅ 正面:语义化 -->
<header>网站标题</header>
<nav>导航链接</nav>
<main>正文内容</main>
<footer>版权信息</footer>
  • 利于 SEO:搜索引擎能识别页面的重点结构。
  • 利于无障碍:读屏软件能正确朗读结构,盲人用户才能正常使用。
  • 利于团队协作:别人看代码就知道每个区域的职责。
标签含义
<header>页眉/区域头部
<nav>导航
<main>页面主体(一个页面只有一个)
<section>一个章节(通常带标题)
<article>独立成篇的内容(可脱离页面单独理解)
<aside>侧边栏/补充内容
<footer>页脚
<figure>+<figcaption>配图及说明文字
<time>时间

2.6 表单:收集用户输入

<form action="/submit" method="post">
  <!-- label 的 for 与 input 的 id 绑定:点文字也能聚焦输入框 -->
  <label for="username">用户名</label>
  <input type="text" id="username" name="username" placeholder="请输入" required>

  <label for="pwd">密码</label>
  <input type="password" id="pwd" name="pwd">

  <!-- 单选框:同 name 的 radio 互斥 -->
  <input type="radio" name="gender" value="male" id="m"><label for="m">男</label>
  <input type="radio" name="gender" value="female" id="f"><label for="f">女</label>

  <!-- 下拉框 -->
  <select name="city">
    <option value="beijing">北京</option>
    <option value="shanghai">上海</option>
  </select>

  <button type="submit">提交</button>
</form>
input 类型作用注意
text单行文本最常用
password密码(打码显示)仅显示掩码,不加密传输
email / number / url带格式校验的输入手机端会弹出对应键盘
checkbox复选框(可多选)同 name 成组
radio单选框(互斥)同 name 才互斥
file文件选择配合 enctype="multipart/form-data"
date / color / range日期/颜色/滑块浏览器原生控件
hidden隐藏字段用户不可见但随表单提交
⚠️ 必会知识点:块级元素 vs 行内元素 块级元素(div、p、h1~6、ul、table、form…)独占一行,宽高可设;行内元素(span、a、strong、em、img…)不换行,多个并排,宽高由内容决定。这个区别是理解 CSS 布局的地基。
3CSS 基础

选择器、层叠与优先级、单位、颜色。

3.1 CSS 怎么引入

<!-- ① 外部样式表(推荐,复用+缓存) -->
<link rel="stylesheet" href="style.css">

<!-- ② 页面内 style 标签(单页面小项目可用) -->
<style> p { color: red; } </style>

<!-- ③ 行内样式(不推荐,难维护、优先级最高要小心) -->
<p style="color: red;">文本</p>

基本语法:选择器 { 属性: 值; 属性: 值; },每条声明以分号结尾。

3.2 选择器全家桶(必须全部掌握)

选择器写法选中什么
标签p所有 <p>
.card所有 class="card"(可复用)
ID#navid="nav"(一个页面只能有一个)
属性[type="text"]type 属性为 text 的元素
后代div pdiv 内部所有 p(不限层级)
子代div > pdiv 的直接子级 p
相邻兄弟h1 + p紧跟在 h1 后面的第一个 p
通用兄弟h1 ~ ph1 后面的所有 p
伪类:hover / :focus / :first-child / :nth-child(2n)状态或位置
伪元素::before / ::after / ::first-line元素的局部/虚拟元素
通配*所有元素(重置样式常用)
组合.card.active同时有 card 和 active 两个类
/* 伪类 vs 伪元素的本质区别 */
/* 伪类:一个冒号,描述元素的状态/位置 —— 元素本身就存在 */
a:hover { color: red; }
li:nth-child(2n) { background: #f0f0f0; }

/* 伪元素:两个冒号,创建 DOM 中不存在的虚拟元素 */
.card::before { content: "★ "; }          /* 在 card 内容前插入星星 */
.card::after  { content: ""; display: block; } /* 清除浮动常用技巧 */

3.3 优先级与层叠(最容易被问懵的点)

同一个元素被多条规则命中时,谁生效?规则是:先比权重,权重相同比谁在后面

/* 权重(从高到低): */
// 1. 行内样式 style=""        权值最高
// 2. ID 选择器 #nav           记 100 分
// 3. 类/伪类/属性 .card :hover [type]  记 10 分
// 4. 标签/伪元素 p ::before   记 1 分
// 5. * 通配符                 0 分

/* 例:下面两条都作用于同一个 p,谁生效? */
#content p { color: blue; }   /* 100 + 1 = 101 分 */
.card p { color: red; }       /* 10 + 1 = 11 分  → 蓝色生效 */
  • !important:加在声明后(color: red !important;)直接提到最高优先级。用它是「最后手段」,滥用会让调试变成地狱,面试官听到你用 !important 都会皱眉。
  • 继承:部分属性(color、font-*)会从父级继承,布局类属性(margin、padding、border、width)不继承。
  • 实用技巧:写样式时尽量用类选择器,保持权重扁平(都 10 分),后续覆盖时好控制。

3.4 单位与颜色

单位含义典型用法
px物理像素(固定)边框、小尺寸
em相对父级的字体大小1em = 父元素 font-size
rem相对根元素(html)的字体大小全局字号,改 html 字号整体缩放
vw / vh视口宽/高的 1%全屏背景 100vh
%相对父元素的对应属性宽度 50%
fr(Grid)网格剩余空间分配1fr 1fr = 两等分
/* 颜色的四种写法 */
color: red;                        /* 关键字 */
color: #ff0000;                    /* 十六进制(常用) */
color: rgb(255, 0, 0);             /* 红绿蓝 0-255 */
color: rgba(255, 0, 0, 0.5);       /* 加透明度 0-1 */
color: hsl(0, 100%, 50%);          /* 色相/饱和度/明度 */
✅ 单位选择建议 字号用 rem(响应式友好)、元素尺寸用 px 或 %、弹性布局交给 flex/grid 自身、全屏元素用 vw/vh。别乱混。
4盒模型 —— 一切布局的地基

CSS 里每个元素都是一个「盒子」,理解盒子是理解布局的第一步。

4.1 盒子的四个部分

从外到内:margin(外边距)→ border(边框)→ padding(内边距)→ content(内容)

/* 一个盒子 = 内容区 + padding + border + margin */
.box {
  width: 200px;      /* 默认只指 content 的宽 */
  padding: 20px;     /* 内容与边框的距离 */
  border: 2px solid #333;  /* 边框:粗细 样式 颜色 */
  margin: 10px;      /* 盒子与外面元素的距离 */
}
/* 这个盒子实际占据宽度 = 200 + 20*2 + 2*2 + 10*2 = 264px */
🚨 高频坑:box-sizing 默认情况下 width 只算 content,导致「设了 200px 宽,实际占了 244px」,很难算。现代开发一律重置:
* { box-sizing: border-box; }
这样 width 就是「border + padding + content」的总宽,所见即所得。

4.2 margin 塌陷(经典坑,面试必考)

两个兄弟盒子垂直方向的外边距会合并(取较大值),而不是相加:

/* 上面盒子 margin-bottom: 30px,下面盒子 margin-top: 20px */
/* 实际间距 = 30px(取大者),不是 50px —— 这叫外边距塌陷 */
.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
// 垂直方向才会塌陷,水平方向不会。BFC 可以阻止塌陷(见下节)

还有父子塌陷:子元素设置 margin-top 有时会「带跑」父元素。规避方案:父元素用 padding 代替、加 overflow 或开启 flex/grid 布局(flex/grid 容器内不会塌陷)。

4.3 BFC(块级格式化上下文)

BFC 是一个「独立结界」:结界内部的布局不影响外部。触发 BFC 的常见方式:overflow: hiddendisplay: flow-rootdisplay: flex/gridposition: absolute/fixed

  • BFC 内不会发生外边距塌陷(垂直方向)
  • BFC 可以包含浮动元素(清除浮动的手段之一)
  • BFC 不会与浮动元素重叠(经典两栏布局的基石)
5布局基础:文档流、浮动、定位

理解元素默认怎么排,才能知道怎么让它「不按默认排」。

5.1 文档流(Normal Flow)

不设置任何定位时,元素按 HTML 顺序排列:块级元素从上往下堆行内元素从左往右排(一行放不下自动换行)。这就是文档流,是布局的「默认状态」。

5.2 浮动 float —— 了解即可,很少再用

float: left/right 让元素「漂」到一侧,后续内容环绕它。它曾是布局主流,但缺陷多(高度塌陷、清除浮动麻烦),现在布局请用 Flexbox / Grid,浮动只在特殊场景(如图文环绕)使用

/* 图文环绕:图片左浮动,文字环绕其右侧 */
img.avatar { float: left; margin-right: 16px; }

5.3 定位 position —— 五种值必须滚瓜烂熟

相对于谁定位是否脱离文档流用途
static默认,无定位默认
relative自己原来的位置否(占位保留)微调位置、作为 absolute 的锚点
absolute最近的「已定位祖先」(relative/absolute/fixed),没有则到 body弹层、角标、图标定位
fixed视口(屏幕),滚动不动吸顶导航、悬浮按钮
sticky滚动到阈值前是相对定位,到阈值后像 fixed 粘住混合表格吸顶表头、侧边栏跟随
/* 经典用法:父 relative + 子 absolute,把角标定位到右上角 */
.badge-wrap { position: relative; }          /* 锚点 */
.badge {
  position: absolute;
  top: -6px; right: -6px;                    /* 相对锚点偏移 */
}
/* 子元素配合 left/top/right/bottom 指定位置,或 50%+transform 居中 */
.center {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);          /* 经典水平垂直居中 */
}
⚠️ 脱离文档流 = 不占位 absolute/fixed 的元素从文档流中「抽走」,后面的元素会顶上来占据它的位置。布局「不见了」十有八九是这个原因。

5.4 z-index 与层叠上下文

脱离文档流的元素可以叠放,叠放顺序由 z-index 决定(数值越大越靠上)。但注意:z-index 只在同一层叠上下文内比较。开启层叠上下文的常见方式:position + z-index、transform、opacity、filter。

/* 陷阱:父元素 A 的 z-index 比 B 小,A 里的子元素 z-index 再大也盖不住 B */
.a { position: relative; z-index: 1; }
.b { position: relative; z-index: 2; }
.a .child { position: relative; z-index: 999; }  /* 999 也盖不过 .b,因为 .a 整体在下面 */
6Flexbox —— 一维布局之王

Flexbox 解决「一行/一列内如何排列」的问题,是 90% 布局场景的答案。

6.1 核心概念:容器与项目、主轴与交叉轴

/* 给父元素加 display:flex,它就变成弹性容器 */
.container {
  display: flex;
  /* flex-direction 决定主轴方向: */
  flex-direction: row;            // 默认:水平排列(主轴=水平,交叉轴=垂直)
  // flex-direction: column;    // 垂直排列(主轴=垂直)
  // flex-direction: row-reverse / column-reverse  // 反向
}
/* 容器里的直接子元素自动变成「弹性项目」 */

掌握这张概念图,Flexbox 就懂了一半:主轴方向由 flex-direction 决定,交叉轴永远垂直于主轴。所有对齐属性都是围绕这两条轴说的。

6.2 容器上的 6 个关键属性

属性作用常用值
flex-direction主轴方向row / column / row-reverse / column-reverse
justify-content主轴方向对齐flex-start / center / space-between / space-around / space-evenly
align-items交叉轴方向对齐stretch(默认拉伸) / flex-start / center / flex-end / baseline
flex-wrap是否换行nowrap(默认不换) / wrap
align-content多行时的整体对齐(只有 wrap 才有效果)同 justify-content
gap项目间距(也可单独 gap-row / gap-column)gap: 16px
/* 一行代码实现水平垂直居中 —— 最常用的布局 */
.center-box {
  display: flex;
  justify-content: center;   /* 主轴居中 */
  align-items: center;       /* 交叉轴居中 */
}

/* 导航栏经典布局:左 logo,中间菜单,右按钮 */
.nav {
  display: flex;
  justify-content: space-between;  /* 两端撑开 */
  align-items: center;             /* 垂直居中 */
}

6.3 项目上的 3 个关键属性(flex 三件套)

/* flex-grow(放大比例) flex-shrink(缩小比例) flex-basis(基础宽度) */
.item1 { flex: 1; }              /* 等价于 1 1 0%:占满剩余空间的 1 份 */
.item2 { flex: 2; }              /* 占 2 份 → 经典等分布局 */

/* 常见取值速查: */
// flex: 1        → 均分剩余空间(自适应)
// flex: none     → 0 0 auto 不伸缩,按内容宽 */
// flex: auto     → 1 1 auto 按内容伸缩 */
// flex-basis: 200px → 初始宽度 200px,空间多余再分配 */
  • align-self:单个项目覆盖容器的 align-items。
  • order:改变项目的排列顺序(不改变 DOM 顺序,对无障碍友好)。
🚨 高频坑:flex 子项宽度不受控 给 flex 容器里的子元素设 width 常常「不听话」,因为默认 flex-shrink: 1 允许压缩。想让子项固定宽:加 flex-shrink: 0 或直接写 flex: none
7Grid —— 二维布局神器

Flex 管一维(一行或一列),Grid 管二维(行和列同时控制)。

7.1 先建网格轨道

.grid {
  display: grid;
  /* 定义 3 列:第一列 200px 固定,其余两列平分剩余空间 */
  grid-template-columns: 200px 1fr 1fr;
  /* 定义行高 */
  grid-template-rows: 100px auto;
  gap: 16px;               /* 行列间距 */
}
  • fr:分数单位,表示剩余空间的份额(1fr 1fr = 两等分)。
  • repeat(3, 1fr):重复 3 份 1fr,等价 1fr 1fr 1fr
  • auto:按内容大小。
  • minmax(200px, 1fr):最小 200px,最多 1fr——响应式神器。

7.2 项目的放置:网格线、跨度、区域

.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }

/* 让某个项目跨两列(网格线编号从 1 开始) */
.item-wide { grid-column: 1 / 3; }   /* 从第 1 条线到第 3 条线 → 占 2 列 */
/* 等价写法 */
.item-wide { grid-column: span 2; }  /* 跨 2 列 */

/* 显式指定行列位置 */
.item-special {
  grid-column: 2 / 4;    /* 第 2 到第 4 条线 */
  grid-row: 1 / 2;       /* 第一行 */
}

更高级的用法是 grid-template-areas 用「画图」的方式布局,适合整体页面骨架:

.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

7.3 隐式网格与对齐

  • 隐式网格:项目比定义的轨道多时,浏览器自动创建「隐形」的行/列,默认尺寸 auto,可用 grid-auto-rows: 100px 控制。
  • 对齐justify-items/justify-content 管水平,align-items/align-content 管垂直(用法和 Flex 类似)。
  • place-items: center:同时设置两个方向,一行代码居中。
✅ Flex 还是 Grid?一句话判断 只排「一行」或「一列」→ Flex;需要同时控制「行和列」→ Grid;整页骨架 → Grid(areas);组件内部元素排列 → Flex。
8响应式设计

一套代码,在手机、平板、电脑上都好看。

8.1 先加 viewport(不做这一步手机端必崩)

<!-- 告诉手机浏览器:按设备真实宽度渲染,初始缩放 1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

没有这行,手机浏览器会按 980px 的宽度渲染再缩小,字小得看不清。这是移动端第一课。

8.2 媒体查询 @media

/* 默认样式(移动优先写法:先写手机版) */
.card { display: flex; flex-direction: column; }

/* 屏幕宽度 ≥ 768px 时(平板) */
@media (min-width: 768px) {
  .card { flex-direction: row; }
}

/* 屏幕宽度 ≥ 1200px 时(桌面) */
@media (min-width: 1200px) {
  .card { padding: 32px; }
}
  • 移动优先:先写移动端样式,再用 min-width 逐级增强,代码更少更清晰。
  • 断点不是固定的,按内容需要定(常见:480 / 768 / 1024 / 1200)。

8.3 流式布局与弹性图片

/* 宽度用 % 或 fr,随视口伸缩 */
.container { width: 90%; max-width: 1200px; margin: 0 auto; }

/* 图片最大不超过父容器 */
img { max-width: 100%; height: auto; }

/* 现代方案:容器查询(container query),按组件自身宽度响应 */
.card-list { container-type: inline-size; }
@container (min-width: 400px) {
  .card { flex-direction: row; }
}
✅ 现代响应式三件套 弹性单位(rem/%/fr)+ 媒体查询(全局断点)+ 容器查询(组件级响应)。三者配合,任何设备都能自适应。
9CSS 进阶:变量、动画、层叠上下文、BEM

从「会写」到「写好」,这些能力是分水岭。

9.1 CSS 变量(自定义属性)—— 设计系统的地基

/* 定义:在 :root 上定义全局变量 */
:root {
  --color-primary: #2563eb;
  --space-md: 16px;
  --radius: 8px;
}
/* 使用:var() 引用,还支持带默认值 */
.button {
  background: var(--color-primary, #333);  /* 找不到时用 #333 */
  padding: var(--space-md);
  border-radius: var(--radius);
}
/* 主题切换:改一个变量,全站变色 */
[data-theme="dark"] { --color-primary: #60a5fa; }

CSS 变量是设计系统(Design Token)的基石:颜色、间距、圆角全部收敛成变量,改一处全局生效,主题切换轻松实现。这是资深工程师的标配写法。

9.2 过渡与动画

/* 过渡:属性值变化时平滑过渡,而不是瞬间跳变 */
.button {
  background: #2563eb;
  transition: background 0.3s ease, transform 0.2s ease;
}
.button:hover {
  background: #1d4ed8;
  transform: translateY(-2px);   /* 悬停上浮 2px */
}

/* 动画:keyframes 定义关键帧,animation 引用 */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.fade-in { animation: fadeIn 0.5s ease forwards; }
// animation: 名称 时长 缓动 是否保持结束状态;forwards 保持最后一帧
⚠️ 性能注意 动画尽量只用 transformopacity,这两个属性由 GPU 合成,不触发回流重绘;不要动画 width/height/margin/top,会每帧触发布局计算,卡顿。

9.3 transform 变换

.el {
  transform: translate(10px, 20px);   /* 平移 */
  transform: scale(1.2);              /* 缩放 */
  transform: rotate(45deg);           /* 旋转 */
  transform: skew(10deg);             /* 斜切 */
  transform-origin: center;           /* 变换原点,默认中心 */
}

9.4 BEM 命名规范 —— 团队协作的默契

BEM = 块(Block)+ 元素(Element)+ 修饰符(Modifier),命名格式:block__element--modifier

/* 块:独立组件 */
/* 元素:块内部的一部分,用 __ 连接 */
/* 修饰符:状态变体,用 -- 连接 */
.card { }                      /* 块 */
.card__title { }               /* 元素:标题 */
.card__button--primary { }     /* 修饰符:主按钮变体 */
// HTML: <div class="card"><h3 class="card__title">...</h3>...</div>

好处:样式不会互相污染(天然「作用域」)、可读性高、团队协作零沟通成本。

10阶段一常见坑清单

把最容易翻车的点集中在一起,写代码时对照自查。

现象解决
没加 viewport meta手机上看字小得看不清head 里加 viewport 标签
中文乱码页面显示「锟斤拷」加 <meta charset="UTF-8">,文件保存用 UTF-8
没有 box-sizing: border-box设了宽度却比预期宽全局重置 * { box-sizing: border-box }
外边距塌陷两个盒子距离比预期的窄父级加 overflow:hidden 或改 flex/grid
absolute 定位乱跑子元素定位到了页面角落父元素加 position: relative 作为锚点
flex 子项宽度失控设置了 width 却变了加 flex-shrink: 0 或 flex: none
选择器权重混乱样式「不生效」层级用类选择器,保持权重扁平
动画卡顿动画掉帧只用 transform/opacity 做动画
图片变形图片被拉伸img { max-width:100%; height:auto } 或 object-fit: cover
文字溢出省略标题过长换行难看单行省略三件套(见下)
/* 单行文字省略(背下来,高频) */
.ellipsis {
  overflow: hidden;          /* 隐藏溢出 */
  white-space: nowrap;       /* 不换行 */
  text-overflow: ellipsis;   /* 显示省略号 */
}
/* 多行省略(-webkit- 前缀) */
.ellipsis-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;     /* 显示 2 行 */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
11实战项目(通关必做)

两个项目都独立完成,阶段一才算通关。

项目一:响应式个人主页

要求:

  • 顶部导航(logo + 菜单,手机端可折叠或简化)
  • Hero 区(大标题 + 副标题 + 按钮,垂直水平居中)
  • 三张技能卡片(桌面三列,平板两列,手机一列)→ 练 Grid + 媒体查询
  • 作品区:图片网格,hover 有上浮效果 → 练 Flex + 过渡
  • 页脚:版权 + 链接
  • 全站使用 CSS 变量管理颜色间距 → 练 Token
  • 语义化标签 + 完整的表单(练表单)

验收:手机、平板、电脑三个宽度下都布局正常;打开 DevTools 移动模拟无横向滚动条。

项目二:仿知名网页静态还原

选一个你常用的网站(比如新闻门户、产品官网),用 HTML + CSS 还原它的首页静态结构。不要求一模一样,但要求:

  • 整体布局结构一致(顶部/导航/主体分区/页脚)
  • 使用 Grid 实现页面骨架,Flex 实现组件内排列
  • 至少一处吸顶导航(sticky)和一处悬浮元素(fixed)
  • 还原一套配色方案(用 CSS 变量)

这个项目会逼你把本章所有知识点串起来,做完你会发现自己突然「会布局了」。

12通关自检题

用「讲给别人听」的方式回答。卡住的题,回炉对应小节。

1. 描述从输入网址到看到页面的过程(用你自己的话)

提示:浏览器发请求 → 服务器返回 HTML → 浏览器解析渲染。不需要讲网络细节(那是阶段三)。

2. 块级元素和行内元素有什么区别?给 3 个例子

3. 为什么强调语义化?说出至少 3 个好处

4. 选择器优先级怎么算?#header .nav a 的权重是多少?

答案:ID 100 + 类 10 + 标签 1 = 111 分。

5. 盒模型由哪四部分组成?box-sizing: border-box 改变了什么?

6. 什么是外边距塌陷?举一个父子塌陷的例子和解决方案

7. position 的 5 个值分别相对谁定位?哪个会脱离文档流?

8. justify-content 和 align-items 分别控制哪个轴?flex-direction: column 时它们的作用互换吗?

答案:justify 管主轴、align 管交叉轴。column 时主轴变成垂直,所以 justify-content 变成控制垂直方向。

9. flex: 1 的含义是什么?写出等价形式

答案:flex-grow:1 flex-shrink:1 flex-basis:0%,即占满剩余空间。

10. Grid 中 1fr 和 100px 有什么区别?minmax(200px, 1fr) 是什么意思?

11. 移动优先的媒体查询写法是什么?为什么推荐移动优先?

12. 为什么动画推荐只用 transform 和 opacity?

答案:它们不触发回流重绘,由合成器在 GPU 上处理,性能最好。

13. BEM 命名规范是什么?写一个「搜索框组件」的 BEM 类名示例

14. 什么是层叠上下文?为什么子元素 z-index: 999 还是盖不住别人?

✅ 全部答对?进入下一阶段 打开《阶段二 · JavaScript 核心》开始学习。学 JS 时如果发现需要操作页面(DOM),你会感激自己在阶段一打下的基础。