CSS核心原理与实战技巧:选择器、盒模型、flex布局一次讲透 做前端三件套系列上一篇我们把 HTML 的结构讲透了这一篇专门干 CSS。CSS 在 HTML、CSS、JS 三兄弟里定位特别清晰HTML 负责骨架CSS 负责长相JS 负责行为和互动。你哪怕把 HTML 标签背得滚瓜烂熟没有 CSS 加持页面就是一份黑底白字的文档连居中都要靠运气。而 CSS 一旦上手整个网页的颜值和质感会立刻不一样。这篇面向的是刚学完 HTML、准备补齐 CSS 这块拼图的同学也适合那些写了几百行样式但老被“样式不生效”“居中又跑偏”折磨的初学者。我会从 CSS 的三种引用方式讲起把定义与引用的关系理清楚再逐个拆解选择器、盒模型、字体样式、布局、跟 JS 配合的实战套路最后放一些我自己踩过的坑和排查技巧。内容基本覆盖了日常写页面 90% 的 CSS 场景看完可以直接上手干活。1. 先把概念捋清CSS 到底在管什么1.1 CSS 和 HTML 的分工逻辑很多人学 CSS 容易犯一个错误把样式直接写在 HTML 标签里觉得省事。比如div stylecolor:red这种写法不是不能用但只要你写过三五次就会发现维护成本高得吓人。一个页面十个按钮都写stylebackground:blue哪天需求改成绿色你得改十个地方漏掉一个就掉链子。这里的关键是理解 CSS 的设计哲学结构和表现分离。HTML 负责告诉浏览器“这里是一个标题”“这里是一个按钮”“这里是一段描述”CSS 负责告诉浏览器“标题是多大字号什么颜色”“按钮是圆角还是直角”“描述要不要加粗”。两者分开页面才能真正做到改样式不动结构改结构不影响样式。这也是为什么现在几乎没有人把 CSS 全写在行内。虽然 HTML 文档开头那一串!doctype htmlhtml langzh-cn...看起来是 HTML 的地盘但页面真正好看不好看决定性因素全在 CSS 这层。后面系列讲 JS 的时候也一样JS 管行为但它操作的对象永远是“被 CSS 布局好的页面”三者边界越清晰代码越好写。1.2 CSS 定义与引用三种引入方式怎么选CSS 和 HTML 结合有三种方式新手阶段必须全掌握因为你会经常看到别人的代码里三种混着用行内样式div stylecolor:red优先级最高但最不推荐维护。内嵌样式写在 HTML 的head里用style标签包起来适合单页面小 demo。外部样式独立.css文件用link relstylesheet hrefstyle.css引入这是正式项目中绝对的主流。外部样式表的好处不用多说一个样式文件可以被多个页面复用浏览器还能缓存它刷新页面加载更快。实际开发里团队规范通常直接禁用行内样式内嵌样式也只在首屏关键的少量代码里出现其余全走外部文件。还有一种情况是动态加载 CSS比如点击按钮切换主题用 JS 往head里插入一个新的link标签。这个做法我后面讲跟 JS 配合的时候再展开。总之记住一条经验能用外部文件就别写行内这是我从被行内样式坑过无数次之后总结出来的血泪教训。1.3 拿到设计稿先别急着写样式我第一次做完整页面的时候拿到设计稿直接开写写到一半发现布局全乱返工重来。后来我养成一个习惯先不看效果先把页面拆成几个大区块想清楚每个区块之间的嵌套关系、排列方向、宽度策略再动手写 CSS。这个过程通常叫“画盒子”。一个商品列表页可以拆成 header、banner、商品卡片区、footer一个卡片又拆成图片区、标题区、价格区。每个盒子用 div 或语义化标签搭好然后给盒子加边框或者背景色确认边界最后再往里面填样式。有人觉得这步多余直接写也没什么但等你做复杂页面的时候不画盒子基本寸步难行。2. 选择器你凭什么能指挥某个元素2.1 基础选择器标签、类、id 三件套CSS 的规则很简单一条规则由一个选择器加一组声明组成。选择器决定“改谁”声明决定“改成什么”。最常用的三类基础选择器标签选择器直接写标签名比如div { margin: 0; }管住页面上所有 div。类选择器写.className管住所有带有这个 class 属性的元素。id 选择器写#idName管住唯一的那一个元素。三者的使用频率差距极大。我在实际项目里类选择器用得最多标签选择器用来做全局 resetid 选择器基本不用来定样式只在 JS 需要定位元素时才用。为什么因为 id 在页面里必须唯一一旦给元素绑了样式后期想复用这个样式就得复制一份而 class 是专门为了重复使用而存在的。新手常见的纠结是“这个样式该用 class 还是 id”我的建议很简单样式一律用 classid 留给 JS 和锚点跳转。2.2 组合选择器和属性选择器精度更高的定位方式单靠标签、类、id 有时候够用但做复杂页面不够精准。比如页面上有十个.item我只想改第一个或者所有input里只想改typetext的那些。这时候就需要组合选择器和属性选择器。组合选择器里最常用的有三个后代选择器.container .title { }中间有空格表示 container 内部所有 title不管嵌套多深。子选择器.container .title { }只认直接子元素比后代选择器更严格。兄弟选择器.title .desc { }表示 title 后面紧挨着的那个 desc。属性选择器则更灵活比如input[typetext]只管文本框a[href^https]只管外链。这类选择器对表单校验、外链图标这类场景非常有用我经常用它给所有外链自动加一个小箭头标识。2.3 优先级计算为什么我写的样式不生效这是 CSS 初学者最崩溃的瞬间明明写了两遍同一个属性页面就是不按你期望的那个来。原因基本都出在优先级上。CSS 优先级有一套计算规则简单记住就是id 数量 class 数量 标签数量同级别数量多者胜。行内样式优先级更高只有在!important面前才低头——但我强烈建议尽量别用!important因为它会把整个优先级体系打乱后期维护就是灾难。举个例子div.title的优先级用一个 class 加一个标签权重是0-1-1.box .title是两个 class权重是0-2-0后者胜出。如果你发现样式不生效先别急着加!important停下来算一下是不是有个选择器权重更高压住了它。这个习惯能省下后面排查的成吨时间。2.4 通配符 * 的优缺点全局 reset 该不该用热搜词里有个很经典的话题CSS 样式表中使用*的优缺点。*是通配选择器写法是* { margin: 0; padding: 0; }作用是清空所有元素的默认内外边距。很多新手都会学这一招。我个人的看法是*适合学习阶段快速消除浏览器默认样式差异但不适合直接用到正式项目里。原因有两个。第一*会对页面里所有元素生效包括那些你可能不需要重置的元素性能上有损耗尤其是页面元素非常多的时候。第二现代浏览器的默认样式已经比较统一你真正需要 reset 的其实没几项直接全清掉反而要把很多样式重新加回来等于多写一遍。更好的做法是选一个成熟的 reset 方案比如 Normalize.css或者只针对body、h1到h6、p、ul等常用标签做少量清零。这样既能抹平差异又不至于误伤所有元素。2.5 伪类鼠标移入事件和表单状态全靠它CSS 伪类不是真的“事件”但能实现很多原本要 JS 才能做的交互效果。最典型的就是热搜词里提到的 CSS 鼠标移入事件实际指的就是:hover。.btn { background: #333; }.btn:hover { background: #555; }鼠标移入按钮背景色变化这个效果纯 CSS 就能完成。除了:hover常用的伪类还有:active按下瞬间、:focus聚焦状态、:disabled禁用状态、:nth-child(n)第 n 个子元素、:not(selector)排除某个选择器。:nth-child可以用来做表格隔行变色li:nth-child(odd)选中奇数行依次类推。这里有个小细节:hover在触屏设备上其实不会真正触发移动端开发如果不做适配会出现“按钮看起来没有反应”的问题。所以我一般把悬停效果做成增强型交互而不是关键交互。关键操作仍然依赖 JS 的点击事件这条经验在移动端项目里非常重要。3. 盒模型CSS 入门的第一个门槛3.1 盒模型的组成内容、内边距、边框、外边距CSS 盒模型是整个 CSS 里最核心的概念没有之一。一个元素在页面上占的空间由四部分组成内容区content、内边距padding、边框border、外边距margin。打个比方内容是一个货物padding 是包装里的缓冲泡沫border 是快递箱子的壁margin 是箱子与箱子之间留的过道。很多初学者会混淆 padding 和 margin这里给一个最直接的判断标准padding 会把背景色撑开margin 不会。如果元素有背景色你设 padding 能看到背景范围变大设 margin 则外延是透明的只是把其他元素挤开。四者的简写规则也可以一起记了padding: 10px四边全是 10 像素padding: 10px 20px上下 10、左右 20padding: 10px 20px 30px上、左右、下padding: 10px 20px 30px 40px按上右下左顺时针。这个规则在 margin 和 border 上通用。3.2 box-sizing我愿称之为最救命的一个属性默认情况下你给元素设置width: 300px这个 300 指的是内容区宽度加上 padding 和 border 之后元素实际占据的宽度会超过 300。比如width: 300px; padding: 20px; border: 1px solid #000实际宽度就是 300 加 40 加 2等于 342px。这在布局里非常容易算懵。解决办法就是把盒模型改成 border-box 模式box-sizing: border-box;此时width: 300px表示的是“边框以内”总宽度padding 和 border 都在这个 300 里面挤怎么加都不会超出。我自己的习惯是全局 reset 里直接写一句*, *::before, *::after { box-sizing: border-box; }很多人纠结通配符性能但这条规则覆盖面广反而是好事能保证所有元素都按同一种方式计算宽度省掉一大堆心算。这个血泪教训值一篇论文我早期写项目用的 content-box 默认模式一个卡片宽度想调成两列布局算了半天最后还是溢出换行换成 border-box 之后所有宽度都能精确控制。3.3 margin 塌陷新手遇上的第一个“玄学”盒模型里隐藏得最深的坑是外边距塌陷。简单说两个垂直排列的块级元素你给第一个设margin-bottom: 50px给第二个设margin-top: 30px它们之间的间距不是 80px而是取二者的较大值 50px。这在 CSS 里叫外边距合并。更坑的是父子嵌套的情况父元素里只有一个子元素你给子元素设margin-top: 20px本来想让子元素往下移结果父元素跟着往下跑了 20px。这是很多新手在页面顶部留白时发现整块内容都下移的原因。解决办法也很直接给父元素加overflow: hidden、padding-top: 1px、border-top: 1px solid transparent或者干脆用 flex/grid 布局来绕开 margin 合并。现在我做布局如果遇到需要精确控制间距的优先用 flex 的gap属性gap 不会发生 margin 合并省心太多了。3.4 display 切换块级、行内、行内块和 flexdisplay属性决定元素在页面上的表现形态。块级元素div、p、h1独占一行可以设置宽高行内元素span、a、em在一行里排设宽高无效margin-top / margin-bottom也无效inline-block介于两者之间既能设宽高又能和其他元素排在同一行。这三种模式之间的切换是最基础的但真正改变我写页面方式的是display: flex和display: grid。flex 解决的是“一行内部怎么排”的问题grid 解决的是“二维网格怎么铺”的问题。我后面专门讲布局这里只要记住以后想居中、想等分、想垂直排列第一时间想到 flex 而别用 margin 硬怼会轻松非常多。4. 文本、字体与常用样式让文字好看有技巧4.1 字体设置、渐变文字、外描边的实现套路CSS 里字体相关的属性看着多其实拆开就几类字体族、字号、字重、颜色、字间距、行高。最常用的写法是body { font-family: PingFang SC, Microsoft YaHei, sans-serif; font-size: 14px; line-height: 1.6; }字体族要写多个候选值是因为不同操作系统可用的字体不一样浏览器会依次找第一个存在的。一般把系统自带字体放前面最后加一个通用类兜底。中文项目里我通常会用PingFang SC和Microsoft YaHei覆盖 Mac 和 Windows再留一个sans-serif。标题想做得好看字体渐变是常见操作。背景渐变再加background-clip: text就能实现文字渐变.title { background: linear-gradient(90deg, #f00, #00f); -webkit-background-clip: text; background-clip: text; color: transparent; }核心就是让背景色只在文字范围内显示然后把文字本身颜色设为透明。字体外描边则可以用text-stroke或者用text-shadow模拟出描边效果。text-stroke的兼容性目前已经不错移动端 Safari 也支持了但旧的 Safari 需要-webkit-前缀。4.2 删除线、下划线和段落分割线别小看线热搜词里专门有 CSS 删除线说明很多人在搜索这个基础效果。给文字加删除线用的是text-decoration: line-through。下划线是underline上划线是overline。这个属性还能配合text-decoration-style和text-decoration-color调成虚线或者改颜色。删除线的经典应用是商品原价和现价并存的效果原价打上删除线看起来就有折扣感。这里有个细节删除线的默认位置是穿过文字的中间偏下如果字体比较特殊线的位置可能不太好看可以加内边距微调或者用一个伪元素自己画一条线控制更精细。再做段落分割线一般用带边框的 div 实现。最简单的写法是border-bottom: 1px solid #eee但更优雅的做法是“线在中间、文字骑在线上的”的效果在标题左右各放一条细线。实现方式可以用 flex ::before和::after给标题元素加左右伪元素设置flex: 1和border-top: 1px solid #ddd文字就自然地待在中间了。4.3 水平垂直居中body 居中、input 居中和文本位置调整“CSS 怎么把元素居中”是我见过被搜索最多的 CSS 问题没有之一。新手通常把居中理解成一个属性其实它得分场景文字水平居中用text-align: center。块级元素水平居中用margin: 0 auto前提是元素有明确宽度。垂直居中以前用line-height等于元素高度这种 hack现在直接用 flex。最省心的通用方案是把父容器设成 flex然后让子元素居中.parent { display: flex; justify-content: center; align-items: center; }这个方案几乎能解决 90% 的居中需求。让 body 居中直接把 body 设成 flex 容器内容就居中展示input 想要在容器里居中同样用 flex 处理。文本位置调整则可以用line-height、padding、text-align组合但遇到不确定的情况先想想是不是能直接用 flex 或 grid别在坑里硬调整。4.4 两行超出省略号前端高频需求的标准答案列表里的标题通常只显示一行或两行多出来的用省略号代替。一行省略很简单.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }两行省略在 WebKit 内核浏览器里用-webkit-line-clamp.clamp-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }第一行省略三个属性缺一不可white-space要设为nowrap强制不换行overflow: hidden把溢出的藏起来text-overflow: ellipsis才显示省略号。两行省略浏览器兼容性不错火狐新版也支持了移动端基本放心用。这个效果做列表、新闻标题、商品名都很常见几乎每次写页面都会用到。5. 布局实战从单列到复杂卡片5.1 布局的本质先想清楚横排还是竖排布局是 CSS 里最考验整体思维的部分。很多新手一上来就堆属性写出来发现元素挤成一团。我建议看到任何布局首先问自己两个问题这个大区块里面元素是按行排的还是按列排的如果是横排是想等分宽度还是根据内容自适应基于这两个问题布局方案可以快速收敛。竖排的用块级元素天然的文档流或者 flex 的flex-direction: column横排的用 flex控制justify-content和align-items如果还要处理多行多列的网格用 grid少写很多重复的 float。关于 float 要提醒一句它原本是图文混排用的过去十几年却被用来做布局导致各种清除浮动的 hack。现在有了 flex 和 grid新的布局代码里尽量别再用 float 了。5.2 flex 布局常用属性一次记牢flex 之所以好用是因为它让父元素容器和子元素项目之间的排列关系变得可预测。容器上常用的是display: flex、flex-direction主轴方向、justify-content主轴对齐方式、align-items交叉轴对齐、flex-wrap是否换行、gap间距。子元素上最常用的是flex这个简写。flex: 1表示这个元素会占据剩余空间多个项目都写flex: 1它们就会等分。比如三个按钮要均分一行父级 flex三个按钮都flex: 1宽度自动分配不用算百分比。还有一个经验justify-content: space-between是“两端对齐”的神器列表最后一行不够时也不乱。做导航栏、卡片排布、表单行布局基本就是 flex 加 gap 换着组合已经能包打天下了。5.3 商品详情页的基础布局思路拿热搜词里提到的商品详情页举个例子。虽然每个商城实现细节不一样但骨架都是固定的顶部导航栏、商品图、标题价格区、参数列表、详情介绍、底部操作栏。用上面讲的布局思路拆解顶部用一个固定高度的 header内部左侧返回按钮、中间标题、右侧分享商品图区是一个宽高比例固定的 div里面放图片object-fit: cover防止变形标题价格区用 flex 排成一列价格红色加粗原价用删除线参数列表用两列网格flex 或 grid 都行左边参数名、右边参数值底部操作栏用 flex 固定定位左侧两个图标按钮右侧加入购物车和立即购买两个等分按钮。把这个结构画出来再逐个写 CSS你会发现根本不需要什么高深技巧全是 flex 和基础盒模型组合。真正花时间的反而是间距、字号、颜色这种细节调优经验越多调节的速度越快。5.4 常见 UI 组件的实现思路tab 控件、涟漪效果和卡片动效热搜词里有个“最酷的 CSS tab 控件”其实 tab 切换底部是交互逻辑但样式骨架完全可以纯 CSS 搭。几个 tab 按钮横排选中的那个底部显示一条高亮横线就是 flex 加border-bottom控制.tab-item.active { color: #1677ff; border-bottom: 2px solid #1677ff; }切换 active class 的事交给 JSCSS 只负责“看到 active 就高亮”。还有“CSS 涟漪光圈扩散”这是按钮点击时水波扩散的效果用伪元素 放大动画可以实现点击时给元素加一个类名伪元素从 scale(0) 放大到 scale(1)同时透明度降到 0视觉上就像涟漪一样。这个效果纯 CSS 就能做但触发时机要 JS 配合比如点击时设置位置和添加类名。卡片上浮动效也是常用组件技巧。默认状态下卡片有一个轻阴影鼠标移入时transform: translateY(-4px)并加深阴影过渡用transition: all 0.3s。用户会明显感觉卡片“浮起来”开发成本几乎为零。6. CSS 与 JS 配合样式不止静态6.1 classList 操作JS 改样式的正规方式CSS 和 JS 配合的场景非常多。热搜词里有“js 判断字符串是否包含”“iframe 关闭刷新父页面”这类问题它们都是 JS 范畴但最终都是在操作页面状态而页面状态改变通常体现在 class 上。正确的方式是用 JS 操作类名而不是直接改 styleelement.classList.add(active); element.classList.remove(active); element.classList.toggle(active);搭配 CSS 里.active的样式就能实现开关、高亮、展开收起等交互。直接element.style.color red不是不行但可维护性差而且行内样式优先级高想覆盖还得动用!important容易恶性循环。我一直坚持“能用 class 就用 class”的原则CSS 管状态对应的样式JS 只管状态的切换这样代码各自分工明确。6.2 实战组合填表校验、菜单开关和 iframe 关闭刷新表单校验是 CSS 和 JS 配合的经典案例。输入框通过:focus显示聚焦样式通过.valid或.invalid类显示校验结果。JS 在输入事件里判断内容合法就加.valid不合法就加.invalidCSS 负责把绿框或红框渲染出来。状态切换逻辑在 JS样式表现全在 CSS一试就会上瘾。菜单开关也是同样思路汉堡按钮点击后给菜单容器加.open类菜单从display: none变display: block或者用 transform 做滑入滑出。移动端常见前端新手自己做着玩也几乎都会写一次。如果遇到 iframe 内嵌页面想关闭 iframe 并刷新父页面这种操作本质是跨页面通信不是 CSS 能管的。思路是父页面监听自定义事件子页面触发了就执行父页面的逻辑或者用parent.postMessage传递消息。这类问题我在排查环节再展开遇到时不用慌先把 CSS 和 JS 的边界分清楚问题会简单很多。6.3 CSS 变量与主题切换有一篇帖子讲到的“高级感”其实很简单CSS 变量自定义属性是这个时代写 CSS 的必备能力。定义方式是在:root里声明:root { --primary-color: #1677ff; --bg-color: #ffffff; }使用方式是var(--primary-color)。好处是全局统一管理改一个值全站颜色跟着变。做深色主题更是神器给 html 加一个>html[data-themedark] { --bg-color: #1f1f1f; --primary-color: #4d9fff; }JS 这边只需要切document.documentElement.setAttribute(data-theme, dark)事情就结束了。这个方案曾被我安利给很多人真正用一次就会发现主题切换根本没有想象的复杂。7. 样式不生效和布局错乱排查技巧实录7.1 样式不生效的五个排查步骤我总结过一套解决“CSS 不生效”的排查顺序每次遇到问题都按这个来几乎没失手过。第一确认元素定位对不对。打开浏览器开发者工具F12选中目标元素看右侧 Styles 面板里有没有你写的规则。如果没有说明选择器没匹配上检查 class 拼写或父子结构。第二确认其他规则有没有压过你。如果规则在但被划掉了那就是优先级不够提升选择器权重或者检查同权重下谁的顺序更靠后。第三确认父级或全局有没有干扰比如全局* { box-sizing: border-box }和你预期的宽度策略冲突。第四确认标签结构和预期是否一致比如 HTML 嵌套错误导致元素不是你想的那个结构。第五确认没有语法错误比如漏了分号或括号。这套流程最多五分钟可以省下大量时间。最怕的是不看控制台瞎猜改半天不知道改到哪了。7.2 居中和间距失效的常见原因新手最容易踩的坑是明明用了text-align: center为什么图片不居中答案是text-align对块级元素内的行内内容有效对图片本身无效。图片是行内元素被包在块级 div 里时text-align: center有用但如果图片直接是块级元素就要用margin: 0 auto或者父级 flex 居中。一个居中问题背后经常是多层原因叠加。间距失效常见于 margin 塌陷前面已经说过。还有种情况是 flex 布局里 margin 表现和块级布局不同flex 子项不会塌陷但对齐方式受justify-content影响更大用 margin 做间距也不是不行但我现在更推荐gap。flex 的 gap 和 grid 的 gap 都能直接产生精确间距完全不涉及 margin 合并问题能让代码干净不少。7.3 特殊场景参考HTML 邮件、HTML 转 MD、PyQt5 显示 HTML有些常见问题看着跟纯 CSS 没关系但其实是 CSS 兼容性决定的。比如 HTML 邮件很多邮件客户端尤其 Outlook对 CSS 支持极差flex、position、外部样式表通通不认。做邮件模板基本只能退回 table 布局加行内样式这是行业现状不是你的问题。遇到类似需求先查目标客户端的 CSS 支持表能省下大量返工时间。又比如把 HTML 转成 Markdown或者在一个 Electron/Qt 环境里加载 HTML它们本质上都是渲染环境不同。PyQt5 的QWebEngineView可以显示一个完整的网页但它的渲染内核是 Chromium 系现代 CSS 基本都能支持直接开发就行。这一类问题的关键判断是“当前环境的 CSS 引擎是哪一套”Chromium 内核、WebKit 内核、老版本 IE 内核支持程度天差地别。7.4 开发工具F12 是 CSS 最忠实的朋友写 CSS 不用浏览器开发者工具等于闭着眼画画。我强烈建议把 F12 按成肌肉记忆。Elements 面板里可以实时修改样式并立即看到效果右侧 Styles 面板能查看所有匹配规则、继承属性、被覆盖的规则。还有一个我常用的功能在 Styles 面板里临时勾选或取消某个属性用来确认到底哪一条在起作用。改动满意之后再回到编辑器里同步代码。这个方法比“改代码-刷新-不行-再改”的循环快五倍以上。调试响应式布局时开发者工具的设备模拟器也很有用。但我建议不要把任何布局调成只适配某一种模拟器尺寸应该在真实浏览器宽度和移动端尺寸各检查一遍因为模拟器与实际手机内核还是有一些细节差异。8. 踩坑心得这些坑我替你踩过了做前端这些年我被 CSS 折磨过无数次。有些问题现在看很简单当时真是查了一整天。说几个最典型的供各位避雷。第一个坑是全局 reset 太狠导致所有按钮和表单的默认样式被清掉。后来我把 reset 改成只清必要的 margin 和 padding并加回button、input的字体继承问题就消失了。第二个坑是用height: 100%实现全屏布局发现根本不生效很久后才知道需要 html 和 body 都设高度。后来我改用min-height: 100vh干脆利落。vh单位真的是布局利器能避免一大堆高度计算。第三个坑是动态内容导致布局跳动。比如列表加载时图片没定宽高文字加载完后图片撑开整个页面往下跳。解决办法是给图片容器预设宽高比或用aspect-ratio属性提前占位。这种细节看着小对用户体验影响特别大。第四个坑是transition加得太多任何属性变化都来一个动画结果页面卡顿。经验是过渡只用opacity、transform这类合成属性不要给all加 transition更不要在width、height上做动画不然性能会很难看。这个知识点在面试和实际开发里都很加分。说了这么多CSS 并不是什么高深不可学的技术。它更像一个工具箱你把每个工具的适用场景记清楚遇到需求能快速拿对应的那一个出来用就已经超过大多数人了。尤其是 flex、盒模型、优先级这三个关键点吃透了再配合浏览器开发工具我相信你会有一种“突然开窍了”的感觉。后面系列如果讲到 JS你会发现之前积累的 CSS 经验会反过来帮助你更好地理解“事件”“状态”“渲染”这些概念。自己动手多写几个页面踩过几轮坑你就真正把 CSS 变成自己的技能了。