做前端的这些年,我发现自己陷入过一个循环:新框架出来就追,组件库换了一茬又一茬,可真到某个晚上要写一个不带任何框架的纯页面时,反而被 HTML 和 CSS 的基础细节卡住了。尤其是<!doctype html>、<html lang="zh-cn">这种每天都会见到的代码片段,背都背过,可被问到“为什么必须这么写”时,我竟然一时讲不清楚。
于是我把 HTML 和 CSS 认认真真复习了一遍。这篇内容不是官方文档的搬运,也不是什么速成指南,而是我从自身踩坑角度整理出来的复习笔记。里面涉及文档结构、CSS定义与引用、盒模型、字体样式、居中方案、鼠标移入事件、动画效果、表格与段落分割线这些高频知识点,也包含了很多搜遍全网都很少有人讲透的细节。无论你是刚学完基础准备进场的新人,还是已经写了两年业务代码想要查漏补缺的老人,这篇文章都值得耐心看完。
1. 复习HTML时,建议先从文档头结构看起
1.1 到处都是那段样板代码,但你真的理解了吗
现在在搜索引擎里输入“html”,出来最多的一串代码就是<!doctype html> <html lang="zh-cn"> <head> <meta charset="utf-8"> ...。我最初看到这股搜索热象时还挺意外,因为这段代码太基础了,基础到很多编辑器都在自动补全。后来我才明白,大家搜它不是因为不会写,而是因为想搞懂每一行的含义。
<!doctype html>是 HTML5 的文档类型声明。它的作用是告诉浏览器“请用标准模式来解析这个页面”,而不是老旧的怪异模式(quirks mode)。在怪异模式下,IE 时代的盒模型规则会被启用,同样的 CSS 在不同浏览器里渲染结果可能完全不一样。所以这行声明不是给 SEO 看的,也不是给人看的,是给浏览器底层的解析器看的。少了它,页面往往会给你一个措手不及的惊喜。
<html lang="zh-cn">里的lang属性,很多人以为只是标注语言方便翻译插件使用,其实它更重要的价值是让屏幕阅读器等辅助工具能正确读出页面文字。对于中文网页来说,写成zh-cn和zh-CN都可以,主要看项目面向的地区习惯;如果是面向简体中文用户,显然没必要写en。
<meta charset="utf-8">是字符编码声明,它管的是浏览器以什么编码去解码 HTML 文件。如果文件本身是 UTF-8 编码,但这里漏写了,浏览器就会按照默认编码去猜,结果中文全部变成乱码。这种情况我在老项目里见过太多次了,修复方式也只是补一行代码而已,但排查起来会让人极度崩溃。复习到这里的时候,我特意提醒自己:文档头里的每一行,都不是“别人都这么写所以我也写”,而是背后有明确的原因。
1.2 常见标签的块级、行内、替换元素分类
另一个值得复习的点是元素分类。HTML 标签表面看起来就是一堆名字,实际上它们默认的显示方式决定了 CSS 样式能不能生效。块级元素像<div>、<p>、<h1>这类,默认独占一行,宽度默认填满父容器,上下 margin 可以正常设置;行内元素像<span>、<a>、<strong>这类,默认在同一行排列,宽度由内容撑开,而且上下 margin、width、height 这些属性对它们无效。
这里有个很容易踩的坑:行内元素设置padding和border的时候,视觉上能看到,但它们不会影响周围元素的位置。打个比方,一个<span>加了上下 padding,视觉上文字周围有了一片背景区域,可上面的文字并不会因此被推下去,这就会造成一部分内容被遮挡或者重叠。解决思路很简单——要么把它变成行内块元素,用display: inline-block,要么直接改成块级元素display: block。
还有一类替换元素,比如<img>、<input>、<iframe>。它们比较特殊,因为内容来自外部资源,所以它们本身具有内在尺寸,可以被设置宽高。复习的时候把这些元素分类整理一遍,对后面理解 CSS 的居中、布局都特别有帮助。
1.3 HTML到底是不是编程语言,这不重要,重要的是语义化
复习的时候必须聊一下语义化。这个问题在很多新手群里吵得不可开交,有人坚持说“HTML是标记语言,不算编程”,其实无所谓。你要关心的是:用<div>一把梭写出来的页面,和用<header>、<nav>、main>、<article>、<footer>搭出来的页面,代码可读性和 SEO 表现会有明显差距。
语义化标签最大的好处是“自己会说话”。<nav>一看就是导航,<article>一看就是文章主体。这样做既方便团队协作时同事快速理解页面结构,也能帮助搜索引擎抓取重要内容。复习的时候我给自己定了一个标准:能不写<div>就不写<div>,除非这个区域确实没有更贴切的语义化标签可选。
另外,很多开发者会忽略<label>标签在表单中的价值。不只是点击文字能聚焦对应的输入框这么简单,它还是无障碍访问的基础。复习 HTML 选择框的时候,<select>、<option>、<optgroup>这三个标签也需要理清楚。<optgroup>可以给选项分组,这在做商品分类、地区选择这类长列表时很实用。
2. CSS定义与引用,以及最重要的选择器优先级
2.1 三种CSS引入方式的取舍
CSS 定义与引用是一个老生常谈的问题,但我发现很多刚接触前端的人对三种方式的适用场景是模糊的。第一种是行内样式,直接写在元素的style属性里。这种方式优先级最高,除了!important谁也压不住它,但它让结构和样式高度耦合,维护成本极高。第二种是内嵌样式,写在<head>里的<style>标签中。适合单页面、小型的项目,或者某些只需要在特定页面生效的样式。第三种是外部样式表,用<link>引入.css文件,这是实际项目里最推荐的方式,因为可以复用、缓存,也符合关注点分离的原则。
我在复习的时候给自己列了一个决策表:
表格:CSS引入方式对比
| 引入方式 | 写法位置 | 优先级 | 适用场景 |
|---|---|---|---|
| 行内样式 | 元素 style 属性 | 最高 | 动态数据驱动的临时样式、邮件模板 |
| 内嵌样式 | head 内 style 标签 | 较高 | 单页应用入口、首屏关键样式 |
| 外部样式 | link 引入 css 文件 | 正常 | 多页面项目、组件库、长期维护 |
2.2 选择器优先级:别再背什么“1000、100、10、1”了
很多人复习 CSS 选择器的时候,喜欢背一个权重公式:内联样式算 1000,ID 选择器算 100,类选择器、属性选择器、伪类算 10,标签选择器和伪元素算 1。这个公式用来应付面试确实够,但实际开发中,我更习惯用“比较规则”来理解。
看优先级的时候,先看有没有!important,有的话它最大;没有!important的话,再看选择器里 ID 的个数;ID 个数相同,看类、属性、伪类的个数;再相同,看标签名和伪元素的个数。如果这些都一样,那就看谁在样式表里出现的顺序更靠后,后者覆盖前者。这样理解比死记数字更可靠,遇到复杂选择器时也能快速判断到底谁会生效。
通配符*也要单独说。好多参考书告诉我们“*可以选中所有元素”,于是新手喜欢写* { margin: 0; padding: 0; }。这个写法确实能清掉浏览器默认边距,方便起步,但它的缺点也不能忽视。第一,*会给页面里所有元素都加上声明,包括未来动态插入的元素,这在性能上并不是最优解,虽然现代浏览器的处理速度已经很快了,但在很大型的页面上仍然会造成没必要的开销。第二,它破坏了浏览器默认样式的一致性,比如<p>和<ul>本来有合理的上下 margin,一条通配清除让所有元素全靠你自己重新定义间距,这在开发后期很容易出现“这个元素怎么没有间隙”的疑问。
我现在的建议是:像 reset 这类需求,尽量用更精确的body, h1, h2, h3, p, ul, ol, li { ... }这样的分组选择器,或者直接引入成熟的 reset 方案。在复习 CSS 的时候,你能理解*的优缺点,比单纯复制一段 reset 代码要重要得多。
2.3 原子性CSS的新视角
“原子性CSS”这个词在热搜里也很常见。它到底是什么呢?简单说,把 CSS 属性按最小粒度拆分成独立的类,比如.text-center { text-align: center; }、.mt-10 { margin-top: 10px; },然后 HTML 里通过组合这些类来搭出想要的样式。
这种风格之前被很多人吐槽“回到了行内样式时代”,但真实开发中它的逻辑并不是让你到处堆类,而是面向高频复用的属性做统一管理。我在复习的时候重新思考了原子性 CSS 的优势,它特别适合组件化开发。组件内多种状态切换时,通过动态切换 class 比写一大段样式覆盖要干净得多;同时重复样式被打包成原子类后,代码体积也会明显下降。
不过原子性 CSS 也有缺点——类名晦涩、复用组合导致可读性下降,以及 HTML 结构里会出现一堆看起来“无意义”的类名。所以它并不是银弹,更像是一种在特定项目里选择的风格。
3. 盒模型、字体和文本样式,细节决定质感
3.1 盒模型复习:从 content-box 到 border-box
盒模型是整个 CSS 的基石。复习的时候千万别只看一张带 content、padding、border、margin 四层结构的图就完了,你要重点理解box-sizing的影响。
标准盒模型content-box下,一个元素的宽度等于 content 的宽度,而 padding 和 border 会向外扩展。这意味着你设width: 200px,再设padding: 20px、border: 5px,元素实际占用的宽度是 200 + 202 + 52 = 250px。这在栅格布局里非常容易导致计算错乱。
怪异盒模型border-box下,宽度是 content、padding、border 的总和。你设width: 200px,无论 padding 和 border 怎么改,元素的总宽度都是 200px,只是内容区会被压缩。现代项目几乎清一色都在全局开启border-box,就是因为它更符合直觉,也更好管控。
我建议复习完这个概念后用浏览器控制台亲手改一次box-sizing,感受一下元素的占位变化,这比盯着文档看来的效果好得多。盒模型不是只在面试题里出现的概念,它在日常布局中几乎每天都在起作用。
3.2 CSS字体相关:删除线、字体渐变、外描边
CSS 字体相关的样式也是复习重点。先说最容易理解的text-decoration: line-through,这就是删除线。做商品原价显示、任务列表的完成态标记时,用它比画一条背景线要干净。如果你想控制删除线的颜色和粗细,可以写成text-decoration: line-through 2px red,这是简短写法,也支持分开写。
字体渐变是个被低估的技巧。通常我们提到渐变就想到背景background-image: linear-gradient(...),但要让文字本身有渐变效果,需要配合background-clip: text和color: transparent。思路是先给文字元素加背景渐变,再把背景裁切到文字区域,最后把字体的默认颜色变成透明,渐变就露出来了。兼容性在现代浏览器里已经完全没问题,老掉牙的 IE 就忽略好了。
字体外描边实现方式有很多,最常见的是用-webkit-text-stroke,直接给文字描边。但要注意它会从文字中心线向外扩张一半,导致字看起来偏细。如果不想影响字面,可以用text-shadow的四个方向各描一遍,来模拟外描边。比如text-shadow: 1px 0 0 #000, -1px 0 0 #000, 0 1px 0 #000, 0 -1px 0 #000。这套写法虽然朴素,但兼容面广,在控制字体粗细场景下很实用。
另外还需要复习一下font-family。不同操作系统默认字体不同,所以中文网页通常写一长串回退字体列表,比如font-family: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif。系统字体是什么,就按顺序优先匹配。这个知识点看似简单,实际影响整个页面的观感和性能。
3.3 文本溢出省略:单行与多行的正确姿势
文本溢出是高频需求,也是大家抄代码经常抄出问题的点。单行省略的标准三件套是:white-space: nowrap(强制不换行)、overflow: hidden(隐藏溢出部分)、text-overflow: ellipsis(显示省略号)。这三样缺一不可,少一个效果都可能出不来。
两行省略就需要用-webkit-line-clamp了。它本身是一个非标准属性,但现代浏览器都支持。典型写法是:
.ellipsis-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }这里的关键是display: -webkit-box配合-webkit-box-orient: vertical,让容器内部以垂直方向排列子元素,然后-webkit-line-clamp限制显示行数。如果你把容器改成display: flex,这个方案就失效了,因为布局模式已经改变。所以复习的时候,更重要的不是复制这一段代码,而是理解-webkit-box和flex各自的工作机制。
3.4 段落分割线:hr还是border
“CSS实现段落分割线”是热搜里的高频词。做法通常两种。第一种是直接用<hr>标签,它自带语义“故事转折或主题切换”,默认样式是水平线,你可以通过 CSS 调整颜色、粗细和虚线效果。第二种是用元素的底边框,比如给段落加border-bottom: 1px solid #e5e5e5。这两种方案的语义完全不一样。如果分割线只是想做一个视觉上的分隔,用border-bottom更灵活,不会额外增加 DOM 节点;如果分割线代表内容层面的主题变化,<hr>更符合 HTML 语义化要求。复习的时候我建议把这两种做法都掌握,根据场景选择。
4. 让人头疼的居中问题,一次理清楚
4.1 容器里的文本位置,怎么调才合理
“怎么调整css容器里的文本位置”这个搜索词,本质是在问文本的对齐方式。水平方向有text-align: left/center/right,垂直方向则要分情况。如果容器是单行文本,直接设置容器的line-height等于容器高度,就能实现垂直居中;如果容器的文本可能换行,line-height这种方案就不行了,你应该用display: flex; align-items: center或者padding来让文本在垂直方向上有合理的间距。
这里很容易犯的错是,拿设置line-height的方式去处理多行文本。比如一个容器高度 60px,里面有三行文本,每行行高 20px,你把line-height设成 60px 后三行文本就全重叠了,因为它会让每一行都独占 60px 的高度。多行文本的正确做法是设置适中的line-height,再用padding或者 flex 去调整整体位置。
4.2 块级元素水平垂直居中的几种方案
居中问题绝对是 CSS 里的重灾区。我把常用方案整理成了一张表,每次忘记的时候直接翻:
表格:块级元素居中方案对比
| 方案 | 核心代码 | 优点 | 限制 |
|---|---|---|---|
| margin auto | margin: 0 auto | 简单直接 | 仅水平居中,需定宽 |
| text-align | text-align: center | 适合行内元素 | 不适合块级元素宽度 |
| flex | display: flex; justify-content: center; align-items: center | 最推荐 | 父容器需要确定的宽高或由内容撑开 |
| grid | display: grid; place-items: center | 代码最短 | 需要理解 grid 布局 |
| 绝对定位+transform | position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) | 兼容性好 | 需要父容器相对定位 |
开发里我用的最多的就是 flex 和 grid。flex 适用于大多数常规场景,grid 适合二维布局时顺便做居中。绝对定位加 transform 适合弹窗、悬浮层这类需要脱离文档流的元素。
4.3 input居中和body居中为什么总出问题
“css中怎么把input居中”是另一个高频搜索。如果你把<input>当成普通块级元素处理,只给父容器加text-align: center,输入框并不会居中,因为表单控件在浏览器里默认带有内联块特性,但宽度和 margin 行为比较特殊。想让 input 居中,一种方式是把 input 设为块级元素并给一个宽度,然后用margin: 0 auto;另一种是父容器用 flex 布局,justify-content: center,这样无论 input 宽度如何都能居中。
“css body居中”的说法也经常出现。很多人问的是“怎么让整个页面的主体内容居中”,这时候你要区分到底是让 body 的背景和内容一起居中,还是让 body 里某一层容器居中。通常做法是给最外层容器设置一个最大宽度,比如max-width: 1200px,再配合margin: 0 auto。如果你直接给 body 设置text-align: center,那只是把所有文本和行内元素居中,块级元素根本不鸟这个设置,这也是很多人疑惑的根源。
4.4 让table水平居中
还有一个历史悠久的问题:<table>怎么居中。很多人在 table 上设置margin: 0 auto,结果没有生效。原因是 table 的默认显示方式是display: table,它的宽度是由内容决定的,如果没有设置 width,它在某些情况下的确可以自动收缩,但这取决于 table 的宽度是否小于父容器,以及父容器的布局模式。
更稳妥的做法是把 table 的display改成block或者用父容器控制。如果你希望表格保持语义化且不破坏表结构,最简单的方案是给 table 设置margin-left: auto; margin-right: auto,同时确保 table 的 width 小于父容器宽度。如果 table 的 width 是 100%,那它本身就占满了父容器,根本没有居中的余地。
顺便说一句,在移动端布局里,table 居中反而是次要问题,优先考虑的是如何让表格在窄屏上不溢出。这里有个常用技巧是把 table 包在一个拥有overflow-x: auto的容器里,让宽表格可以横向滚动。
5. 从hover到涟漪光圈:交互效果的复习路线
5.1 鼠标移入事件在CSS里其实就是这两件事
“css 鼠标移入事件”这个搜索词,说到底是两个东西::hover伪类和与之搭配的transition。很多人以为鼠标移入就要写 JavaScript,其实纯 CSS 就能处理大量交互状态。
:hover的作用是当鼠标指针悬停在元素上时,应用一组新的样式。常见用法是改变背景色、边框、阴影、透明度,或者让元素产生位移。但这里有一个细节:如果 hover 状态变化得太突然,用户会觉得页面很生硬。所以通常要配合transition属性,让这些样式的变化过程平滑发生。transition可以拆成transition-property、transition-duration、transition-timing-function和transition-delay四个子属性。实际开发里我习惯简写:transition: all 0.3s ease,不过用all会让所有可过渡属性都参与动画,性能上不如指定transition: background-color 0.3s ease, transform 0.3s ease这么精准。
:hover 并不是唯一与鼠标有关的伪类。比如:active是鼠标按下到触发之间的状态,常用于按钮点击效果;:focus用于表单元素或可聚焦元素获取焦点时,对键盘用户和无障碍支持至关重要。
5.2 CSS动画基础与涟漪光圈扩散效果
提到 CSS 动画,很多人会直接联想到@keyframes。复习的时候,核心要理解animation属性的构成:动画名称、时长、速度曲线、延迟、播放次数和方向。典型写法:
@keyframes ripple { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(4); opacity: 0; } } .ripple-effect { animation: ripple 0.6s ease-out forwards; }这段代码里,forwards表示动画结束后保持最后一帧的状态。如果不写这个关键字,动画结束后元素会立刻回到初始状态,这是新手最容易疑惑的点。
涟漪光圈扩散效果是很多设计稿里的常客。实现思路通常是:一个相对定位的父元素,里面放一个绝对定位的圆形子元素,初始尺寸很小、透明度较高;动画让它逐渐放大,同时透明度降到 0。这样看起来就像水面上的涟漪逐渐向外扩散消失。如果你想要多个光圈依次扩散,可以复制多个子元素,分别设置不同的动画延迟时间,让它们交错出现。
我实际测试下来,这种特效对性能有一定要求,所以不要让涟漪元素的个数太多。同时记得给执行动画的元素加上will-change: transform; opacity,这能告诉浏览器提前做好优化准备。不过will-change也不要滥用,它本身会占用浏览器资源。
5.3 最酷的css tab控件,其实原理没那么神秘
“最酷的css tab控件”也出现在热搜里。很多 tab 切换效果看起来复杂,本质就是radio加label的巧妙组合。用<input type="radio">的选中状态配合:checked选择器,可以实现纯 CSS 的选项卡切换。
基本结构是:一组 label 对应一组 radio,内容面板通过兄弟选择器或者相邻选择器来展示。当某个 radio 被选中时,对应的内容面板显示,其他面板隐藏。这套方案的优点是不需要一行 JavaScript,缺点是 radio 一旦选中就无法取消,所以它更适合“必选其一”的场景。如果真的需要可切换但也可取消的场景,还是用 JS 更方便。
如果你想要更流畅的切换动画,可以在内容面板上使用 opacity 和 transform 的组合。比如选中时面板透明度从 0 变到 1,同时位移一点点,视觉上会更柔和。
5.4 transition 和 animation 怎么选
复习到动画这里,很多人会纠结同一个效果用transition还是animation。我的经验是:如果你的交互只有两个状态,比如默认状态和 hover 状态,用transition就够了;如果交互中间有多个关键帧,比如做了三个阶段的变形,那用@keyframes的animation更合适。transition还经常用来定义“从 A 到 B”的过渡,animation则更适合“A → B → C → D”这样更复杂的路径。二者不冲突,实际项目里常混用。
6. 一些零散但特别实用的HTML和CSS技巧
6.1 一键返回顶部,结构与滚动的配合
“html一键返回顶部算法”这个词其实不涉及什么高深算法,它更像是一个交互组件的设计。返回顶部按钮一般采用position: fixed定位在页面右下角,点击后让页面滚动回顶部。
HTML 结构可以是:
<a href="#top" class="back-to-top">返回顶部</a>这种方式利用了锚点定位,点击后页面跳到 id 为 top 的元素位置,但地址栏的 URL 会出现#top后缀。如果你不想改变 URL,可以用 JavaScript:
document.querySelector('.back-to-top').addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); });behavior: 'smooth'可以产生平滑滚动效果。如果只写window.scrollTo(0, 0)则是瞬间跳回,体验偏硬。另外,这个按钮最好在用户向下滚动超过一定距离后才显示,避免一进页面就看到一个无用的按钮。这个显示逻辑可以监听window.onscroll判断window.scrollY是否大于某个阈值。
6.2 关于html转为md、pyqt5显示html,以及邮件模板
搜热词里还有几个也很有意思。html转为md的问题,本质上是想要把网页内容转换成易于编辑和版本管理的 Markdown 格式。服务端可以用现成的解析库,比如把 HTML 字符串转成 AST,再序列化成 Markdown。前端浏览器环境里,也可以直接对用户选中的内容或者整个页面进行转换。这个需求常见于博客编辑器、运营后台、知识库系统。
pyqt5显示html是桌面开发里的常见需求。PyQt5 的QTextBrowser或QWebEngineView可以直接渲染 HTML,但要注意它们的 CSS 支持程度和浏览器不一样。做桌面应用内嵌页面的时候,样式表尽量保持简单,避免使用一些较新的 CSS 特性,否则渲染出来会跟预期差很远。这里也提醒了我:HTML 和 CSS 不只是浏览器的专利,很多桌面框架也用它做界面描述语言,但兼容性差异是绕不开的坑。
邮件模板则是另一个特殊场景。写 HTML 邮件的时候,很多人直接套用网页里那套布局方式,结果在 Outlook 里直接翻车。邮件客户端对 CSS 的支持极其有限,很多还停留在 IE 时代的渲染引擎。因此做邮件模板时要用 table 布局、行内样式,图片要写清楚宽高。这跟我们平时做网页的思维完全相反,复习的时候如果要兼顾这块业务,必须单独拎出来专门整理。
6.3 打包多个html、商品详情页、网页制作的整体思路
搜热词里还有html css js商品详情、html简单网页代码、打包多个html,这些其实都指向同一个问题:你的项目应该如何组织和发布。
商品详情页是典型的多区域页面,通常包含商品图片、标题、价格、规格、详情介绍、评价等模块。纯手写时,我会先把这些区域用语义化标签搭好骨架,再逐步完善样式。这里的核心不是复制代码,而是形成“内容优先、结构次之、样式最后”的开发顺序。先把页面里的所有信息列出来,确定主次关系,再写与之匹配的 HTML 结构,最后用 CSS 美化。这套流程听起来慢,实际上是最稳的。
打包多个html一般是构建工具的问题。如果你是纯静态页面,多个 html 之间直接通过相对路径互相跳转就行;如果用打包工具,比如 Vite 或 Webpack,则要考虑多页面入口的配置。没有专门的插件,直接按pages目录下每个 html 配一个入口文件即可。对于新项目,我更推荐直接在浏览器里确认好页面结构和样式,再决定是否引入构建工具,避免无谓的复杂度。
6.4 原子性的日常应用、选择框、input和表单样式
回到日常开发里,html输入框、html选择框这类表单元素才是最让人头疼的。表单控件在不同浏览器下的默认样式差异非常大,尤其是<select>的下拉箭头,Chrome 和 Firefox 画得都不一样;<input type="checkbox">和<input type="radio">在 Windows 和 macOS 下面更是两种审美。
想要统一这些控件的样式,需要先清除默认外观,使用appearance: none,再绘制自己的样式。比如自定义 checkbox 的常见做法是:隐藏原生 input,再用::before画一个方框,把勾选图标用伪元素加上去。复习这一块时,一定要多浏览器测试,因为表单控件是最容易出现兼容性差异的地方。
还有 input 的各种类型,尤其是type="email"、type="number"、type="tel",它们虽然能触发移动端的对应键盘,但也带来了额外的校验逻辑。比如type="number"在 Safari 上表现跟 Chrome 不同,处理不好反而给用户添麻烦。复习到这里,我最大的感受是:表单控件的样式统一,比很多花哨的交互效果更考验 CSS 基础功。
7. 复习完以后,我的实际体会和一个小技巧
这次复习 HTML 和 CSS,我最大的体会是:很多问题层出不穷,不是因为知识有多难,而是因为我们太依赖编辑器自动补全和组件库封装了。真正把这些基础重新过一遍后,我发现许多以前需要搜来搜去的问题,变成了潜意识里的肌肉记忆。
最后分享一个我在复习过程中发现的实用小技巧。写 CSS 的时候尽量少用!important,但如果某个第三方组件的样式确实覆盖不掉,可以用!important做最坏打算。真正让样式覆盖可控的办法是提升选择器的具体程度,比如给目标容器加一个父级类名,写成.my-component .target-class { ... },这比!important可维护得多。
另一个小技巧是学会利用浏览器的开发者工具。打开 DevTools,选中元素后可以在 Styles 面板里直接看到所有匹配的规则,按优先级排序,被划掉的样式就是没生效的。排查 CSS 问题时,先看这个面板,往往比瞎猜快得多。复习完基础后,再配合观察工具去理解每个属性带来的影响,效果会非常明显。希望这篇复习笔记,也能帮你把那些浮在表面的前端知识重新沉淀下来。