
CSS基础入门系列写到Part3我先把话撂在这儿这篇不是给你背语法的是帮你开窍的。前两部分我们讲了CSS的基本概念、盒模型、浮动这些地基你可能已经能照着教程写页面了但真让你独立动手大概率会遇到三种情况——样式写了没生效想居中折腾半天做点动效又不知道从哪下手。这很正常CSS的知识点是散点分布的不像JS有逻辑主线所以Part3我直接按大家的搜索热词来串样式怎么引、选择器怎么用、字体排版怎么调、五种布局怎么选、3D旋转和动画怎么做最后再给一份避坑清单。这篇适合刚学完CSS基础语法、准备独立写页面的人也适合写了大半年但一直被各种怪现象折磨的开发者。1. 样式引入与选择器先搞清楚CSS怎么上身1.1 三种引入方式以及link和import的恩怨很多人写CSS不生效第一反应是代码写错了其实八成是怎么把CSS送到页面上这一步出了问题。CSS要生效一共就三条路子行内样式、内部样式、外部样式。!-- 行内样式直接写在标签的style属性里只对当前元素生效 -- div stylecolor: red; font-size: 14px;我是行内样式/div !-- 内部样式写在style标签里放在head中作用于整个页面 -- style .internal { color: blue; } /style !-- 外部样式通过link引入独立CSS文件最推荐 -- link relstylesheet hrefstyle.css我见过不少新手在style属性里塞了一长串样式然后到处复制改起来痛不欲生。行内样式的优先级最高但它把结构和表现揉在一起违背了CSS分离的初衷只适合临时调试。内部样式适合单个页面的小项目或者给邮件写样式时用。真正做项目一律用外部样式表。外部样式表有两种写法除了link还有import/* style.css 顶部这样写 */ import url(reset.css);import看起来也能引入外部CSS但我强烈建议你别用它。原因有三第一import是CSS语法浏览器要先把包含它的CSS下载并解析完才会继续去下载被引入的文件属于串行加载页面首屏速度会被拖累第二import在部分浏览器里如果写在style标签内部还好写在CSS文件里时容易触发按需加载的怪问题尤其是页面内容很多的时候后续样式可能慢半拍第三link是HTML标签可以被JavaScript动态操作做主题切换、按需加载都方便import做不到。所以规规矩矩用link没毛病。1.2 选择器全家桶从元素选择器到伪元素搜索热词里第1关CSS 元素选择器、css选择器这些词被反复搜说明大家对选择器的掌握还停留在见过但不熟的程度。选择器是CSS和HTML之间的连接器选不中元素后面全是白搭。/* 元素选择器选中所有p标签权重最低易被覆盖 */ p { color: #333; } /* 类选择器选中classbtn的元素可复用最常用 */ .btn { display: inline-block; } /* ID选择器选中idheader的元素页面唯一权重很高 */ #header { height: 60px; } /* 属性选择器按属性或属性值筛选 */ input[typetext] { border: 1px solid #ccc; } a[href^https] { color: green; } /* 伪类描述元素的状态或位置 */ a:hover { color: #f60; } li:first-child { font-weight: bold; } input:focus { outline: 2px solid #09c; } /* 伪元素在元素内部创建不存在的虚拟子元素 */ .btn::after { content: →; } p::first-line { font-weight: bold; }伪类和伪元素特别容易搞混你就记一个原则伪类是单冒号:hover描述的是元素的状态比如鼠标悬停、聚焦、第几个孩子伪元素是双冒号::before、::after它会在页面里凭空生造一个不可见的元素节点用来插入装饰内容。老项目里可能看到单冒号的::before写法那是为了兼容IE8现在不用管了统一双冒号就好。实际开发中选择器不是单个用的经常是组合拳。比如.nav li li意思是.nav下面的直接子元素li并且这个li必须紧跟在另一个li后面这种写法在导航菜单做分隔线间距时很顺手。还有.card:not(.disabled)、.item:hover .delete-btn这种嵌套写法平时多练写多了自然就有感觉。1.3 优先级与层叠为什么你写的样式不生效样式写了没生效这个搜索词背后藏着CSS最核心的机制层叠与优先级。样式冲突时浏览器按这话来定胜负先比重要性再比选择器权重最后比书写顺序。我提供一个土办法不用背复杂的计算规则把选择器的权重当成四位数字来记。选择器类型权重参考!important99分一票否决行内style属性1,0,0,0ID选择器0,1,0,0类、属性、伪类0,0,1,0元素、伪元素0,0,0,1通配符*、继承值0,0,0,0举个例子body .content .title这样的选择器权重就是元素1个加类2个即0,0,2,1。#main .title就是0,1,1,0。后者大所以即便前者的样式写在后面也赢不了。这里有个反直觉的坑!important权重最高不假但它不是无条件的。同一条声明里行内样式加!important会压过外部样式的!important两个!important撞在一起还是比谁的选择器权重高。我见过一个项目里为了改第三方组件全站铺了一堆!important后来谁也不敢删删了不知道哪块会炸。我的原则是能用选择器权重解决的绝对不用!important实在要覆盖第三方组件的内联样式才用它而且一定要注释清楚原因。2. 文本与字体处理排版好看的前提2.1 字体核心属性别再用默认字体走天下了页面排版好不好看字体占了七成。很多人写页面只顾着调颜色和间距字体永远用浏览器默认的宋体或者系统黑体出来效果就是一股未完成的味道。body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Microsoft YaHei, sans-serif; font-size: 16px; line-height: 1.6; text-align: justify; }font-family这一长串是有讲究的浏览器会从左往右找第一个系统里存在的字体所以苹果设备用苹方Windows用微软雅黑都没毛病时用通用无衬线体兜底。不建议在中文页面直接引一大坨网络字体一个字体文件动辄几兆为了个标题字体拖慢首屏不值得。font-size和line-height这对组合最容易被忽略但它直接影响阅读节奏。我调试时的习惯是正文font-size设16px、line-height设1.6到1.8标题想紧凑就line-height: 1.2。至于字号单位老项目用px没毛病新项目可以试试rem配合根元素html { font-size: 62.5% }这种写法做整体缩放时特别省事。文字装饰方面删除线用text-decoration: line-through下划线用完记得调text-underline-offset不然下划线贴在文字底部挤成一团。上标下标用vertical-align配合font-size调整这些细节不贵但很提气质。2.2 换行、省略与查看详情排版的隐藏难点搜索热词里css换行省略、在文章末尾或者两行中的最后展示查看详情css怎么写这两个高频问题其实是一个问题的两面文本太长怎么截断然后怎么在截断处做文章。/* 单行省略white-space不换行 溢出隐藏 省略号 */ .line-clamp-1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 多行省略用-webkit-box实现加一个上限行数 */ .line-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }-webkit-line-clamp这套写法有年份了但依然好用兼容性也够。就想提醒一句它本质是-webkit-box的私有特性个别极老的浏览器不认兜底方案是给容器一个固定max-height至少保证不会撑破布局。至于两行文字最后加查看详情我推荐不用JS硬判断直接用CSS伪元素或者一个跟在文本流后面的内联链接div classnews-item p这里是一段比较长的新闻摘要可能在两行或者更多行内展示用省略号截断。/p a href# classdetail-link查看详情/a /div.news-item { display: flex; flex-wrap: wrap; } .news-item p { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin: 0; } .detail-link { margin-left: 6px; color: #09c; }让查看详情跟在文本后面而不是另起一行关键是外层用flex-wrap摘要文本占满一行后链接自然落到第二行末尾。想让它更贴文本可以把detail-link也放进-webkit-box里或者干脆把查看详情用伪元素加在p的::after里不过那样链接就无法点击了所以真实场景还是保留独立的a标签更靠谱。2.3 字体渐变一行代码让标题高级起来css 字体渐变这个热词几乎每个做页面的人都搜过。原理说穿了很简单把渐变背景铺满文字区域然后让字体的颜色变透明把背景透出来。.gradient-text { background: linear-gradient(90deg, #ff6034, #ee0a6b); -webkit-background-clip: text; background-clip: text; color: transparent; }关键点就两个一是background-clip: text把背景裁剪到文字形状内这个属性对Chrome、Safari、Edge都挺友好Firefox新版本也支持了但老版本不行所以-webkit-前缀必须带上二是color: transparent千万别忘忘了就是一块渐变长方条砸在页面上。实际使用中渐变文字的坑主要在背景面积上。如果标题容器本身有背景色或者用了padding渐变会按照整个元素的背景区域来裁不是按文字笔画裁结果就是文字细看会有色斑。应对办法是给这个标题单独设一个没有其他背景的span标签来包文字或者直接设display: inline-block避免渐变背景被撑得太大。3. 盒模型、浮动与居中绕不开的三大基础3.1 盒模型再深挖一层box-sizing是怎么救人的Part1我们讲过盒模型这块内容得往深走一步因为宽度算来算去不对这类问题几乎全是盒模型理解不到位。标准盒模型里width只算内容区padding和border会往外撑于是你明明设了width: 100px加上两边各10px的内边距和2px边框实际占的宽度就是124px。两个这样的盒子放在一行直接就挤爆了。/* 全局切换到IE盒模型width包含padding和border */ *, *::before, *::after { box-sizing: border-box; }这一句就是我说的救人——它把所有元素的宽度计算方式统一成了你设的宽度就是最终占的宽度内边距和边框在内部消化。老前端当年不用它是因为老浏览器不支持现在你写新项目第一行就加上它没有理由不用。真要在某些老系统里排查问题记得确认是不是有人漏了这句我排查过不少布局神秘错位的案例凶手都是它。3.2 清除浮动理解原理别再到处加overflow清除浮动css这个热词能火这么多年说明浮动引发的高度塌陷问题至今还在坑人。浮动元素会脱离文档流父容器不设高度的话就会因为感知不到浮动的子元素而塌成一条线。/* 经典clearfix方案现在依旧是最通用的 */ .clearfix::after { content: ; display: table; clear: both; }把clearfix类加到父容器上::after会在父容器的最后生成一个看不见的块它要求左侧和右侧都不能有浮动元素于是把父容器的高度撑回正常值。这里display: table不是随便写的它能把伪元素的盒模型搞成BFC兼容性比display: block更稳。还有人用overflow: hidden来清浮动原理是让父容器生成BFC块级格式化上下文BFC内部的高度计算会把浮动子元素也算进去。这个方案能用但副作用明显父容器的内容一旦超出就会莫名被裁剪或者出现滚动条。我的建议是维护老代码遇到底部或者下拉框被截断先怀疑是不是overflow: hidden清了浮动顺带把不该藏的藏了。更好的出路是新布局直接放弃浮动改用flex或grid浮动就留给图文环绕这种本职场景。3.3 水平垂直居中的N种方案以及怎么选css中心对齐搜的人多说明这题在面试和日常里都是拦路虎。其实居中方案就那几套关键是搞清每种方案的适用场景。flex是现在的默认首选.parent { display: flex; justify-content: center; align-items: center; }只要是父子关系display: flex加上两个属性水平垂直一次搞定子元素数量不限高度自适应。这是我用得最多的一套没有理由不用。绝对定位也是经典方案分两种情况。子元素宽高已知时用负margin.parent { position: relative; } .child { position: absolute; left: 50%; top: 50%; width: 200px; height: 100px; margin-left: -100px; margin-top: -50px; }子元素宽高未知或动态时用transform平移自身。transform: translate(-50%, -50%)是CSS3的能力把子元素向左上各移自身一半的距离配合left: 50%; top: 50%就能精确居中。这套方案在父容器是相对定位的场景里很好用缺点是用了transform之后如果元素本身还有别的变形需求会有冲突比如你想再给这个元素加个scale动画就得一起写进transform里。还有一个老方案是table-cell.parent { display: table-cell; text-align: center; vertical-align: middle; }这套适合做未知高度上下居中的老场景但如今flex完全能覆盖而且table-cell对内部某些属性有坑我只有在改老邮件模板时才用它。最后是griddisplay: grid; place-items: center一行搞定跟flex一样干净区别在于grid更擅长处理整个页面的二维网格布局居中一个子元素时反而有点杀鸡用牛刀。4. 五种布局方式对比从文档流到Grid4.1 普通流、浮动布局、定位布局老三门html css 五种布局方式这个热词说明大家想系统性理解布局。我按历史演进把布局方式理一遍你就明白什么时候该用什么了。第一种是普通流文档流这是默认的布局方式块级元素从上到下排列行内元素从左到右排列整页内容像水一样往下流。写文章、列表、表单天然就该用普通流不需要任何布局技巧。第二种是浮动布局。浮动最初是为了做图文混排让文字环绕图片后来被拿来搭页面框架两栏、三栏都是float加大量的clearfix。这个方案我前面已经吐槽过了能做但别扭现在除非维护老项目否则不建议新页面再这么搭。第三种是定位布局position四兄弟各有分工relative保留原位置做微调也能作为绝对定位的参照物absolute脱离文档流相对于最近的定位祖先定位做弹层、角标、悬浮按钮非常好用fixed相对视口固定做吸顶导航、返回顶部按钮是首选sticky是个相对新的老熟人了在滚动容器里既参与布局又能吸在某个位置做表格表头吸顶很爽但要注意它会在父容器边界内生效如果父容器也设了overflow: hidden它就不动了。4.2 Flex布局解决一维排列的核心答案Flex解决了一行或一列内的排列问题现代页面90%的横向排布需求它都能搞定。Flex的核心是主轴和交叉轴justify-content控制主轴方向align-items控制交叉轴方向。.container { display: flex; justify-content: space-between; /* 两端对齐中间留空 */ align-items: center; gap: 16px; /* 子元素间距比margin省心 */ }gap这个属性现在可以放心用它专门解决子元素间距问题再也不用对着第一个元素设margin-left: 0了。子元素这边flex-grow决定空间富余时是否扩张flex-shrink决定空间不足时是否收缩flex-basis指定基准大小。我提供一个速记flex: 1等于flex: 1 1 0%表示可伸缩、基准为0用它做等宽非配很顺手flex: auto是1 1 auto会先按内容撑开再伸缩。4.3 Grid布局二维网格页面骨架的首选Grid和Flex最大的区别是维度Flex是一条线Grid是一张网。想让某块区域同时控制行和列Grid是正解。.grid { display: grid; grid-template-columns: repeat(12, 1fr); /* 12等分经典栅格 */ grid-template-rows: auto 80px; gap: 16px; } .col-4 { grid-column: span 4; /* 占4列 */ }fr单位是Grid的精华它表示剩余空间的份数1fr 2fr的含义是第二列宽度是第一列的两倍比百分比计算省心得多。特别喜欢Grid的一点是它让区域划分像excel一样直观。做整页骨架的时候我会用Grid把header、aside、main、footer划好里面的小排列再交给Flex这叫各司其职。4.4 布局方案怎么选一张决策表收尾布局需求推荐方案不推荐方案文档流、文章、表单普通流对普通内容强行flex图文环绕浮动Flex自身不支持环绕单行排列、按钮组、微调对齐FlexGrid过度设计整页二维骨架、复杂栅格Grid浮动拼格子后期改死弹层、悬浮、吸顶定位absolute/fixed/sticky硬用flex模拟我自己的习惯是先看布局是一排还是一片。一排用flex一片用grid一中一静用定位图文混排用浮动普通内容稳稳地待在文档流里。这套选择逻辑问清楚之后布局不会再是玄学。5. transform、过渡与动画让页面活起来5.1 transform基础与3D旋转的正负判断css 3d旋转正负判断核心规则这个热词问得很专业很多人栽在rotate旋转方向搞反这事上。先把2D的四个基础招式过一遍translate平移、rotate旋转、scale缩放、skew斜切。.item { transform: translate(20px, -10px) rotate(45deg) scale(1.1); }注意transform是从右往左应用的先scale再rotate再translate所以写多个函数时顺序不同结果也不同。想控制执行顺序就按你期望的从右到左排列。进入3D关键在于CSS的坐标系。X轴向右、Y轴向下、Z轴朝屏幕外这个Y轴向下的设定跟数学里正好相反很多人的正负判断错就错在这里。记一个通用规则从对应轴的正方向往原点看正角度是顺时针旋转。可是坐标系本身很抽象我提供一个更实操的记忆方式rotateX(正值)元素的上边缘朝屏幕里倒下边缘朝屏幕外翘像低头。rotateY(正值)元素的左边缘朝屏幕外翻右边缘朝屏幕里收像以右边为轴把门向外推开。translateZ(正值)元素沿Z轴朝观看者移动靠近你视觉上变大负值则远离你。推敲一下热词里那个具体案例transform: rotateY(60deg) translateZ(300px)元素先沿Z轴向外靠近你300px再绕Y轴旋转60度结果是一张卡片向你飘近同时侧转了60度左边朝你、右边朝里配合透视就有强烈的立体感。想看到3D效果必须给父级加透视.stage { perspective: 800px; } .card { transform: rotateY(60deg) translateZ(300px); }perspective的值越小透视变形越夸张800px是接近人眼观感的数值我的经验值是做卡片翻转用600到1000px都不会太吓人。3D翻转还常用一个技巧backface-visibility: hidden可以让元素背对我们时隐藏做翻牌效果时必用。5.2 鼠标移入事件与过渡hover的正确用法热词里的css 鼠标移入事件在CSS世界里对应的就是:hover伪类。没有JavaScript参与的情况下hover能做的事情其实很多。.btn { background: #333; color: #fff; padding: 10px 24px; border-radius: 6px; transition: all 0.3s ease; cursor: pointer; } .btn:hover { background: #f60; transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.15); }这里面最容易忽视的是transition。不写它hover变化是瞬间切的生硬得像换脸写上all 0.3s ease所有可过渡的属性会在0.3秒内平滑变化。我强烈建议不要无脑写all因为all会把opacity、transform、background一起过渡有时性能不好更关键的是如果元素还有别的动画在跑会互相干扰。更精细的写法是transition: background 0.3s, transform 0.2s分开控制节奏。hover的适用范围比你想的广。给列表项加个背景渐变、给图片加个scale缩放都会让页面有互动感。但切记hover的反馈要轻别搞得元素又跳又闪用户会觉得页面在抽风。而且移动端的触屏没有hover状态触屏上hover效果是点一下就亮了很多不习惯所以只有桌面端需要hover移动端直接忽略它或改成active态。5.3 动画实战涟漪光圈扩散与流光边框热词css涟漪光圈扩散流光边框 css都是非常经典的项目需求。先说涟漪光圈它模拟的是水波或者点击按钮时那一圈涟漪。核心是keyframes定义关键帧再用animation控制播放。.ripple-btn { position: relative; overflow: hidden; padding: 12px 28px; border: none; background: #1a73e8; color: #fff; border-radius: 6px; cursor: pointer; } .ripple-btn::before { content: ; position: absolute; left: 50%; top: 50%; width: 0; height: 0; background: rgba(255, 255, 255, 0.4); border-radius: 50%; transform: translate(-50%, -50%); animation: ripple 0.8s ease-out infinite; } keyframes ripple { from { width: 0; height: 0; opacity: 0.6; } to { width: 200px; height: 200px; opacity: 0; } }原理就是让一个白色半透明圆形从中心点尺寸从0扩张到目标尺寸同时透明度降到0。因为是无限循环视觉上像波纹一圈圈荡开。这个方案光看代码很简单真正的坑在于overflow: hidden如果不加扩散的圆形会溢出去反而破坏按钮圆角加了之后圆形被按钮边界裁切就有水波封在里面的效果了。流光边框更讲究一些用的是background的渐变位移或者border的渐变伪装。最实用的方案是用一个比元素本身略大的渐变层通过旋转或者位移制造光扫过效果.shine-box { position: relative; padding: 20px 30px; border: 1px solid #ddd; overflow: hidden; } .shine-box::after { content: ; position: absolute; top: 0; left: -150%; width: 50%; height: 100%; background: linear-gradient(120deg, transparent, rgba(255,255,255,.8), transparent); transform: skewX(-20deg); transition: left 0.6s ease; } .shine-box:hover::after { left: 150%; }这个skewX(-20deg)是精髓它让白色的渐变条斜着扫过去视觉上像一道光掠过卡片表面。hover时改变left让它从左边扫到右边。想做成流光描边而不是光带扫过可以把渐渐层背景换成带有透明度的金色或青色配一个深色卡片效果立刻高级起来。5.4 数字加载动画与穿出屏幕的实现思路热词里的数字加载动画效果css与css能实现屏幕穿出来的效果吗放一起讲正好。数字加载动画老实用法其实要配合JS因为CSS自己动不了数值但你可以用一个CSS自定义属性的技巧把数字交给property来动画化。property --num { syntax: integer; initial-value: 0; inherits: false; } .counter { counter-reset: num var(--num); animation: count 2s ease-out forwards; } .counter::before { content: counter(num); } keyframes count { from { --num: 0; } to { --num: 100; } }这是近年来的玩法property让CSS可以动态插值一个整数型自定义属性配合counter()把它显示出来就能实现纯CSS的从0到100的数字滚动。缺点是property在部分浏览器还没全量放开生产环境建议还是JS驱动但做个Demo或者内部工具页面非常香。至于穿出屏幕的效果CSS完全能模拟。原理是3D变换配合不同的视点偏移让元素像从屏幕里探出来一样。我给一个最基础的视差翻转案例.scene { perspective: 600px; } .pop-card { transform: rotateX(20deg) translateZ(60px) scale(1.1); transform-style: preserve-3d; }把rotateX设成20度让卡片顶部朝后仰再给translateZ增加纵深位移视觉上就有了从屏幕里撑出来的悬浮感。再加上box-shadow和背景渐变的配合可以做得很像3D海报。总结一句话想让页面有立体感和动感核心就是perspective transform这俩工具。6. 常见问题排查与经验技巧6.1 IE11打开CSS样式失效兼容问题排查热词html网页 ie11打开css样式失效是很多企业内网开发者的痛点。IE11是个老顽固以下特性它都不支持或者需要前缀CSS Grid布局、background-clip: text、gap属性、property、部分动画属性等等。我先给一套排查顺序确认页面头部有没有!DOCTYPE html声明没有的话IE会进入怪异模式盒模型、样式解析全部是最老一套连基础的边距都会错。这是样式全乱的头号原因。确认样式引入方式。IE11对link和import的支持没有太大区别但import本身会让样式加载更慢在IE上尤其明显。检查新特性有没有加前缀。IE11支持一部分Flex但需要-ms-前缀而且它的Flex实现跟标准有不少出入flex: 1这种简写在老IE里可能被忽略需要写成-ms-flex: 1 1 0%。查到页面里用了Grid就直接放弃用Grid兼容IE的念头用Flex或者display: table兜底。IE11最常见的问题之一是CSS变量失效。如果你用:root { --main-color: #f00 }这种写法IE11完全不认变量会像没定义一样所有颜色回退到默认。我给内网系统的建议是如果不能完全放弃IE11就建议用CSS变量回退兜底双写或者干脆用预编译工具在构建时把变量替换成具体色值。6.2 清浮动、居中不生效快捷键排查思路有读者遇到clearfix写了没用、居中代码贴上去还是歪的我分享一个排查心法别盯着代码看直接在浏览器里按F12用Elements面板逐级检查盒模型。清浮动没效果先看clearfix类有没有加到父容器上再看父容器本身是不是也被浮动了。如果你的父容器是float: left或者position: absolute它自己就脱流了子元素的clear再清也撑不起它的高度。这时候最省事的办法是把父级也设成display: flow-root这是CSS新出的天然BFC方案跟overflow: hidden清浮动原理一致但没有裁剪副作用。居中不生效九成是父容器高度没有撑起来。Flex的align-items: center只能让子元素在交叉轴上居中如果父容器的高度是auto它被内容撑多高就多高居中自然没有意义。先把父容器设一个明确的高度比如height: 400px或者min-height: 100vh再看效果。还有一个高频错误是子元素自己设了margin: 0 auto想水平居中结果这个是块级元素的水平居中方案对flex子元素无效因为Flex布局里margin: auto有自己的作用方式别混用。6.3 原子性CSS新潮但别滥用热词原子性css指的是一种CSS组织思想把样式拆成一个个单一职责的工具类比如.text-center { text-align: center }、.mb-10 { margin-bottom: 10px }、.w-full { width: 100% }然后在HTML里堆类名。Tailwind CSS是这套思想的集大成者这几年火得不得了。原子性CSS的好处很实在完全不用想类名写HTML时顺手就把样式加了组件复用度高同样的原子类在任意项目里都通用CSS文件大小可控不用担心命名冲突。坏处也明显HTML里塞满了几十个类名维护时样式和语义被拆得稀碎而且一个效果往往要组合十几个类才能看懂对新手并不友好。我的立场是原子化CSS最适合组件密集、样式零散的中后台项目因为它能极大减少自定义CSS的维护量。但拿它写博客、落地页这种内容型页面就有点别扭因为内容排版需要的是语义化结构和统一风格堆原子类会让代码很难读。真要入坑建议从Tailwind的Play CDN先跑一个demo亲自感受一下类名堆叠和语义化类的差别再说。6.4 个人避坑清单这些年踩过的CSS坑最后把我在实操中经常踩、也看别人反复踩的坑汇总一下每条都对应具体的受害者场景。忘记box-sizing: border-box宽度百分比加padding直接挤爆布局这是最频繁的问题。z-index无效先确认元素有没有position值不是static没有定位就没法参与层级比较其次确认是不是被父级的overflow或transform创建了新的层叠上下文。外边距合并margin collapse父子元素的margin-top会合在一起取较大的值导致父容器顶部莫名其妙多出间距解决方式是用padding替代或者给父级加overflow: hidden也能生成BFC阻断合并。过渡和动画没效果检查目标属性的初始值。比如从height: 0过渡到height: auto在很多浏览器里是无效的必须给一个具体高度或者用max-height技巧。100vh在移动端会超出可视区一点因为移动端地址栏会遮挡视口要配合100dvh或者min-height: 100svh这类新单位来适配。a:hover样式不生效检查是不是被a:visited的顺序盖住了a:hover要写在a:visited之后CSS伪类的顺序对链接来说有固定讲究。这份清单没有全列列出来的是最高频的几项。碰到问题先对着清单过一遍很多时候不用上搜索引擎就解决了。写到这儿Part3的内容差不多齐了。我个人的体会是CSS入门最大的坎不在语法而是知道场景不知道选型你明明会flex会grid一到真页面就不知道该用哪个。所以这系列文章我故意把布局、居中、动画这些知识点都放到场景里去讲目的就是让你下次面对一个需求时能条件反射地说出这里用flex一排搞定这里用grid划个骨架这里用3D transform做个翻牌效果。最后再分享一个小习惯写CSS之前先问自己三个问题——这段样式要解决什么问题有没有更简单的方案如果把这段删掉页面会不会更好想明白这三点比死记任何技巧都管用。要是你练习时撞上什么奇怪的布局或动画问题欢迎评论区留言我看到都会尽量回复。