1. 从一次样式重构说起为什么我把渐变和文本格式化放在一起看CSS3渐变和文本格式化这两个词单独拎出来都不算新东西但组合在一起做页面时很多人的第一反应是写在静态样式里的、抄一段就能用。我之前接手一个活动页改版样式文件接近八千行光渐变就有四十多处写法五花八门有的用linear-gradient(45deg, ...)有的用-webkit-linear-gradient(left, ...)还有几张渐变直接切成了 PNG 铺在上面。文本这边更乱同一段说明文字出现了五种line-height截断要么用text-overflow要么用 JS 算字数标题的字间距每个模块都不一样。结果就是设计改一版我要挨个模块去找哪段样式对应哪块内容改到第三版的时候彻底崩溃只能整体重构。那次重构完之后我形成了一个习惯只要页面里同时出现渐变和文本样式就把它们放在一起审视。原因很简单它们都属于视觉细节层的东西——不影响布局结构却决定页面的第一眼质感它们的写法都极其容易随手复制一复制就埋坑它们的兼容性坑又都集中在少数几个点上摸清楚一次就能一直受益。所以标题里这个_04的编号我理解成一段学习路径的第四站前面几站大概是基础选择器、盒模型、定位浮动这些到这一站开始真正碰好不好看的问题了。这篇文章适合两类人看。一类是刚把基础选择器和盒模型过完准备写第一个像样页面的朋友你在这里能拿到可以直接抄的渐变写法和文本处理套路另一类是写了几年样式、但一直靠切图和 JS 解决文字问题的同行这里关于角度换算、色标计算、多行截断边界条件的内容大概率能帮你省下几张切图和一段脚本。我不打算把 MDN 的语法表重抄一遍而是按我自己写代码时的实际顺序来讲先讲为什么这么选再讲参数怎么算然后给完整案例最后把踩过的坑摊开。2. CSS3渐变的底层逻辑与角度色标算法渐变这件事最核心的认知转变是它不是一张图片而是一个由浏览器实时计算出来的背景层。这个认知决定了后面所有问题的解释方式——为什么渐变动画性能差为什么打印时会消失为什么角度写 45deg 出来的效果和你想象的不一样。只要把它理解成浏览器按你给的函数在元素盒子里铺了一层像素很多疑惑自然就解开了。我选择用原生渐变而不是切图理由主要有三条。第一是分辨率一张 750px 宽的渐变图放到 2 倍屏上会糊而原生渐变在任何 DPR 下都是清晰的这对大面积背景尤其明显。第二是改色成本运营要改主题色改一个色标值就是一秒钟的事切图要走设计重新导出、上传、换 CDN 链接一整条链路。第三是体积一个有五六个色标的复杂渐变写成代码不到 200 字节存成 WebP 也要几 KB。当然切图也有它的位置比如那种带噪点、纹理、手绘笔触的复杂背景CSS 硬写会非常恶心这时候老老实实切图反而更划算。2.1 线性渐变角度与色标位置的真实计算linear-gradient的语法看着简单真正让人困惑的是角度。规范里0deg指向正上方顺时针递增所以90deg是从左到右180deg是从上到下。但如果你是从老项目迁移过来的会看到大量-webkit-linear-gradient(left, ...)这种写法那个left指的是起点在左边等价于新的to right等价于90deg。这三套写法混在一个项目里是重构时最容易出错的地方。关键词和角度有一个对应关系我整理成表方便对照关键词写法等价角度视觉方向to top0deg从下往上to right90deg从左往右to bottom180deg从上往下to left270deg从右往左to top right约45deg随盒子比例变化左下到右上注意最后一行to top right这个关键词的角度并不是固定 45 度它会随元素宽高比自动调整保证渐变线正好穿过两个对角。这一点很多人不知道以为to top right就等于45deg实际上在宽高比不是 1:1 的盒子里两者效果明显不同。再说色标位置的百分比这是最容易误算的一块。很多人默认百分比是相对元素宽度算的其实不是它是相对渐变线的长度算的。渐变线的长度怎么来公式是这样的设元素宽 W、高 H渐变角度为 a以标准角度制计则渐变线长度 L |W × sin(a)| |H × cos(a)|。举个具体例子。元素是 300px × 120px角度写60deg。sin60 ≈ 0.866cos60 0.5那么 L 300 × 0.866 120 × 0.5 259.8 60 319.8px。也就是说当你在60deg的渐变里写50%那个色标实际落在渐变线上 159.9px 的位置而不是元素宽度的 150px。这个差异在窄高盒子里尤其明显也是我明明写的是 50%为什么看起来偏了的根本原因。如果你需要让某个色标精确落在元素的某个像素位置就得先把像素位置投影到渐变线上再换算成百分比。实操中我很少做这种精确计算更常见的做法是用双位置色标语法把硬边钉死比如.strip { background-image: linear-gradient(90deg, #ff6b6b 0 25%, #ffd93d 25% 50%, #6bcb77 50% 75%, #4d96ff 75% 100%); }这种一个色标写两个位置的写法从较新的语法开始支持表示这一段是纯色而非过渡。相比以前写#ff6b6b 0%, #ff6b6b 25%的笨办法可读性高很多改起来也不容易漏。用它做条纹、进度条刻度、分段占比图非常顺手。关于透明度还有一个经典坑。你可能想做一个从白色渐隐到透明的遮罩写成linear-gradient(to bottom, #fff, transparent)。问题在于transparent的计算值是rgba(0, 0, 0, 0)也就是透明的黑色。在支持预乘 Alpha 的现代浏览器里没问题但在一些老引擎里中间过渡段会往灰色、甚至发黑的方向偏。稳妥的写法是显式写同色透明linear-gradient(to bottom, #fff, rgba(255, 255, 255, 0))。这个细节我在做图片底部渐隐遮罩时被坑过一次遮罩中间出现一条脏灰色的带子排查了半天才反应过来是transparent惹的祸。2.2 径向渐变形状、尺寸关键字与圆心控制radial-gradient的参数比线性多完整形式是形状 尺寸 at 位置, 色标...。形状只有circle和ellipse两种不写会根据盒子形状自动判断。尺寸关键字有四个closest-side、farthest-side、closest-corner、farthest-corner默认值是farthest-corner。这四个关键字的差别用一句话概括就是渐变圆的边缘落在哪个参照物上。closest-side让圆的边缘刚好贴到离圆心最近的那条边farthest-corner让它贴到最远的角。做内发光、聚光灯效果时closest-side通常更合适因为光晕不会溢出容器做整体氛围背景时farthest-corner能让四个角都覆盖到。.spotlight { background-image: radial-gradient(circle closest-side at 50% 30%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 100%); }这段代码做的是一个顶部居中的柔光。这里我特意用了circle因为如果让浏览器自动判断成椭圆在宽盒子里光晕会被拉扁看起来不自然。形状关键字该写就写别省。circle时只能给一个半径值ellipse时给两个水平半径、垂直半径。用显式半径的好处是渐变范围不随容器尺寸变化做固定大小的光斑时更可控.badge { background-image: radial-gradient(ellipse 60px 40px at 50% 50%, #ffd93d, #f6a623); }位置参数at X Y支持百分比、长度和边缘关键字组合比如at left 20px top 30%。做角标、小圆点装饰时用at 100% 0把圆心放到右上角能得到一个只露出四分之一的圆弧比用border-radius加裁剪省事。2.3 锥形渐变与重复渐变少用但好用的两把刀conic-gradient是围绕圆心按角度分布的渐变语法是conic-gradient(from 起始角度 at 圆心, 色标...)。它最典型的用途是饼图、环形进度、色轮、加载动画。.pie { width: 160px; height: 160px; border-radius: 50%; background-image: conic-gradient(#4d96ff 0 30%, #6bcb77 30% 55%, #ffd93d 55% 80%, #ff6b6b 80% 100%); }这里色标的百分比是按角度算的30% 对应 108 度。做环形进度条时可以用conic-gradient加一个内圆遮罩比 SVG 方案轻很多但如果需要动画过渡还是 SVG 的stroke-dasharray更顺滑因为conic-gradient的角度值目前不能平滑插值。repeating-linear-gradient和repeating-radial-gradient用来做重复图案配合色标可以画出条纹、格子、斜纹布、进度条刻度。写重复渐变的关键是把周期控制好最后一个色标的位置就是周期长度.diagonal-stripes { background-image: repeating-linear-gradient(45deg, #f5f7fa 0 10px, #e8eef6 10px 20px); }这段是 45 度的细斜纹周期 20px。这里有个性能提醒重复渐变如果周期特别小比如 2px在低端设备上大面积铺开会有明显的绘制开销尤其是在做滚动视差的时候。我一般会把周期控制在 8px 以上更细的纹理宁可切一张小图平铺。3. 文本格式化真正拉开页面质感的那一层说句实在话大部分人学 CSS 的时候文本属性是被跳过的部分。font-size、color、text-align三个一写感觉就完事了。但我见过太多页面布局结构没问题配色也还行就是看起来不精致追问下去往往是文本处理的问题行高不统一、标题字距太挤、说明文字换行断得莫名其妙、长英文把容器撑破。这些细节单看都很小累积起来就是专业和业余的差距。我在处理文本时的基本策略是分三层。第一层是排版基础字号、行高、字距、段落间距这些定好之后整个页面的气质就稳了。第二层是溢出控制什么时候换行、什么时候截断、截断用什么方式这是防布局崩坏的保险。第三层是视觉修饰阴影、描边、渐变文字这些是锦上添花但也是坑最多的。下面按这三层展开。3.1 text-shadow 的光影分层写法text-shadow的参数是offset-x offset-y blur-radius color可以用逗号分隔写多层从前往后依次叠加。它的能力边界很清晰没有扩散半径spread、没有内阴影inset。这两点是从box-shadow转过来的人最容易踩的坑因为box-shadow有第四个长度值和inset关键字而text-shadow没有第四个长度值如果你多写一个长度值整条声明直接失效而且不会报错你只会看到阴影莫名其妙不见了。做文字描边text-shadow的经典做法是四个方向各偏移 1px 加零模糊.outlined-title { color: #fff; text-shadow: -1px -1px 0 #1f2937, 1px -1px 0 #1f2937, -1px 1px 0 #1f2937, 1px 1px 0 #1f2937; }这个方案在字号小的时候会出现四个角的缺口看起来像描边断断续续。补的办法是再加四个斜向偏移 1px 的阴影凑成八方向或者用-webkit-text-stroke注意它画在字形内部会吃掉笔画厚度粗描边时字会变瘦。我现在的习惯是1px 描边用text-shadow八方向2px 以上才考虑-webkit-text-stroke并且配合增大字号来补偿视觉重量。真正让我觉得text-shadow值钱的是做柔和标题而非硬描边。比如深色背景上放浅色标题加一层低透明度、大模糊、轻微下偏的阴影能让文字从背景里浮起来观感比纯色好很多.hero-title { color: #fff; text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.2); }两层阴影第一层大模糊做环境光遮蔽第二层小模糊补轮廓清晰度这个组合我用了很久几乎成了默认配方。要注意的是模糊半径越大绘制成本越高字数多、面积大的标题如果叠了三四层大模糊阴影滚动时掉帧是有可能的这种情况用一层就够了。3.2 单行与多行截断text-overflow 与 line-clamp 的边界单行截断的三件套大家都背得出来overflow: hidden、white-space: nowrap、text-overflow: ellipsis。但真正会出问题的场景是 Flex 布局里。把一段文字放进display: flex的子项即使写了这三件套它依然会撑开容器而不省略原因在于 flex 子项的min-width默认是auto它拒绝收缩到内容宽度以下。解决办法有两个一是给子项加min-width: 0二是给子项加overflow: hidden有overflow非visible时min-width的自动最小值也会失效。我一般两个都写因为有些场景里子项内部还有嵌套只写一个不一定生效.list-item { display: flex; gap: 8px; } .list-item .title { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }多行截断现在主流还是用-webkit-line-clamp配合display: -webkit-box和-webkit-box-orient: vertical.desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }这个方案有边界条件需要注意。第一它不适合用在display: flex或grid的容器上会互相打架第二-webkit-box-orient在某些打包工具里会被优化掉需要在注释里加autoprefixer: off之类的提示或者改用行内样式写第三最后一行如果本身就很短省略号可能出现得很突兀这是机制决定的无法精细控制。较新的标准属性line-clamp已经在部分浏览器支持可以两个都写向下兼容。还有一种情况是多行截断加展开更多这里的取舍是如果你需要动态判断文字是否真的被截断、以决定是否显示展开按钮纯 CSS 是做不到的得用 JS 比较scrollHeight和clientHeight。我的经验是文字内容来自后端且长度不可控时这个判断必须做否则会出现按钮点了没反应的尴尬。3.3 换行与断词white-space、word-break、overflow-wrap 的分工这三个属性经常被混着用但职责完全不同。white-space管的是空白字符和换行符怎么处理word-break管的是断词规则overflow-wrap管的是一个超长单词放不下时要不要强行断开。white-space的几个值里实际用得最多的是normal、nowrap、pre-wrap。做用户评论展示时经常遇到用户输入换行但页面不换行的问题这时候用white-space: pre-wrap就够了它会保留换行和空格同时超出容器时仍然自动换行。用pre的话就完全不自动换行了长内容会横向滚动除非你就是要做代码块。word-break: break-all会把英文单词从中间切断用于处理用户输入的连续字符、URL、订单号这类东西非常有效但用在正常中文段落里会让标点跑到行首排版变丑。中文场景下更好的选择是overflow-wrap: break-word旧名word-wrap: break-word它只在单词长到一行放不下时才断正常句子不受影响。.comment { white-space: pre-wrap; overflow-wrap: break-word; word-break: normal; }这三行我基本当成用户生成内容的默认配方。另外提一句word-break: keep-all它禁止在 CJK 文本内部断行只允许在空格处断做中英混排的标题时偶尔会用到但用不好会出现一整行被撑爆的情况谨慎。还有一个细节是连字符。hyphens: auto会根据lang属性做英文断词并加连字符观感比硬断好看但必须设置正确的lang否则不生效。我做多语言站点时才用它单语言项目里收益不大。3.4 字距、行高与文本对齐的微调尺度letter-spacing有个几乎所有人都忽略的副作用它会在最后一个字符后面也加一份间距导致居中的文本视觉上偏左。给标题加了 0.1em 字距之后感觉没居中就是这个原因。修法是加一个等量的负margin-right或者用text-indent抵消.section-title { text-align: center; letter-spacing: 0.08em; margin-right: -0.08em; }line-height建议永远写无单位数值比如1.6这样它会基于元素自身字号计算。如果写24px子元素继承下来就是固定的 24px一旦子元素字号变大就会挤在一起写1.6em也有类似问题因为em在继承时已经被解析成像素了。这是 CSS 里最经典的一个继承陷阱我见过太多项目在按钮里写line-height: 40px然后所有图标文字都跟着偏移。text-align: justify在中文段落里效果不错但中英混排时会出现单词间距忽大忽小的河流现象。要缓解的话得配合text-justify: inter-ideograph和hyphens但支持度参差。我的做法是正文一律左对齐只有需要强调排版感的介绍段落才用两端对齐。最后说text-decoration的简写。现在可以把线型、样式、颜色、粗细一起写text-decoration: underline wavy #ff6b6b 2px。做链接下划线时配合text-underline-offset把线往下推 2 到 4px观感立刻从浏览器默认变成设计过a.link { text-decoration: underline; text-decoration-color: rgba(77, 150, 255, 0.4); text-decoration-thickness: 2px; text-underline-offset: 4px; } a.link:hover { text-decoration-color: #4d96ff; }这一个小改动比换字体、换颜色的效果都明显。4. 组合实操三个可直接抄的落地案例理论说完了接下来是我实际项目里反复用到的三个组合方案。每一个都涉及渐变和文本格式化的配合也都在真实场景里被反复打磨过。4.1 渐变按钮含悬停过渡与降级处理按钮是最需要渐变的组件。直接给background-image加渐变然后在:hover里换另一组色标理论上可行但会出现生硬的跳变因为渐变图像之间不能平滑过渡。我试过几种方案最后稳定下来的是双层背景 透明度过渡.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; height: 44px; padding: 0 28px; border-radius: 8px; font-size: 15px; font-weight: 600; letter-spacing: 0.05em; margin-right: -0.05em; color: #fff; background-image: linear-gradient(135deg, #4d96ff, #6bcb77); transition: transform 0.2s ease, box-shadow 0.2s ease; } .btn::after { content: ; position: absolute; inset: 0; border-radius: inherit; background-image: linear-gradient(135deg, #6bcb77, #4d96ff); opacity: 0; transition: opacity 0.25s ease; } .btn:hover::after { opacity: 1; }要点拆解一下。第一悬停的另一组渐变色放在伪元素上用opacity过渡浏览器只需要合成不触发重绘性能好。第二inset: 0是top/right/bottom/left的简写继承border-radius保证圆角一致。第三按钮文字要盖在伪元素之上所以伪元素用了::after且没有z-index冲突时文字默认在上层如果项目里有奇怪的层级问题给文字包一层span加position: relative; z-index: 1。降级方面我习惯用supports兜一层supports not (background-image: linear-gradient(135deg, #000, #fff)) { .btn { background-color: #4d96ff; } }现代浏览器基本都支持这层只是保险。但真正需要保险的是打印样式很多人不知道打印时浏览器默认不输出背景色和背景图渐变按钮在打印预览里会变成白底白字。修法是在打印媒体查询里加-webkit-print-color-adjust: exact; print-color-adjust: exact;或者干脆在打印样式里把渐变换成深色文字。4.2 渐变描边卡片与玻璃质感带渐变边框的卡片早期做法是外层渐变背景加内层白底中间留 1px 缝隙。现在更优雅的写法是用双背景加background-clip.grad-card { position: relative; padding: 1px; border-radius: 14px; background-image: linear-gradient(135deg, rgba(77, 150, 255, 0.6), rgba(107, 203, 119, 0.1) 50%, rgba(255, 217, 61, 0.5)); } .grad-card .inner { padding: 20px; border-radius: 13px; background-color: #fff; }外层负责渐变内层负责内容圆角差 1px 正好对应描边宽度。这个方案的好处是渐变描边可以有透明度变化比实线边框有层次感而且padding: 1px就是边框宽度改起来直观。玻璃质感卡片在此基础上加backdrop-filter.glass-card { border: 1px solid rgba(255, 255, 255, 0.35); border-radius: 16px; background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.05)); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 8px 32px rgba(31, 41, 55, 0.12); }这里有个性能经验backdrop-filter作用区域越大越吃 GPU如果卡片铺满整屏并且页面还有滚动动画低端安卓机上会明显掉帧。我的做法是限制模糊半径在 12px 以内、卡片面积不超过视口的三分之一超出就走半透明纯色降级。另外backdrop-filter在某些浏览器里会创建一个新的层叠上下文导致内部的position: fixed元素定位异常这个坑排查起来很费时间。玻璃卡片上的文字颜色和阴影要重新调。原来的深色正文放在半透明背景上会显得发灰通常要把文字颜色往深里压一档再加一层极淡的文字阴影提升可读性。4.3 渐变文字标题与长文本截断组合渐变文字是这几年很常见的标题样式核心三行.grad-text { display: inline-block; font-size: 32px; font-weight: 700; letter-spacing: 0.02em; background-image: linear-gradient(90deg, #4d96ff, #6bcb77 60%, #ffd93d); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }几个必须注意的点。第一display: inline-block不能省纯inline元素上做background-clip在部分浏览器里裁剪区域会算错文字换行时尤其明显。第二-webkit-text-fill-color: transparent和color: transparent要一起写前者优先于后者只写color在旧版 WebKit 里不生效。第三渐变文字的渐变方向建议用90deg或135deg如果字很长用横向渐变能让颜色过渡更均匀如果只有两三个字135deg的对角过渡更有层次。第四别忘了选中文字透明填充会让用户选中时看不清加一条::selection规则把背景和颜色定死.grad-text::selection { background: #4d96ff; color: #fff; -webkit-text-fill-color: #fff; }标题下面通常跟一段说明文字做 2 行截断这时候要注意行高和line-clamp的配合。line-clamp计算的是行数不是高度所以容器高度不用写死但父级如果用了固定高度做对齐要确保它足够容纳 N 行乘以行高.card h3 { font-size: 17px; line-height: 1.5; margin: 0 0 6px; } .card p { font-size: 13px; line-height: 1.6; color: #6b7280; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }这套组合我在列表页里用了很多次卡片高度由标题一行、描述两行、底部信息一行决定非常规整不会因为后端返回的文字长短不一而错位。5. 常见问题与排查速查下面这些是我在实际项目里真真切切踩过、并且被同事问过不止一次的坑。整理成表格方便你遇到问题时直接对号入座。5.1 渐变相关的高频坑现象可能原因解决方式渐变完全不显示整条声明被浏览器丢弃通常是角度位置写了多余关键字或单位错误用开发者工具看该属性是否被划掉逐段精简测试渐变中间出现灰黑色脏带用了transparent老引擎按透明黑插值换成同色透明如rgba(255,255,255,0)45deg 效果和设计稿对不上设计稿按元素宽度标色标未考虑渐变线长度用 悬停切换渐变色生硬渐变图像之间无法平滑过渡双层背景加伪元素opacity过渡打印后渐变消失打印默认不输出背景加print-color-adjust: exact或改打印样式大面积重复渐变卡顿周期过小导致绘制开销高周期拉到 8px 以上或改用背景图平铺关于表格里第一条我多说两句。CSS 里语法错误不只是这一行不生效整条声明都会被丢弃而浏览器控制台又不会报错所以你只能看到没效果。排查渐变失效时我的固定做法是先写最简单的两色渐变确认能出来再逐段加参数。如果一上来就复制了一段十层的复杂渐变出问题时你根本不知道是哪一层语法错了。还有一个隐蔽的失效场景给元素同时写了background-color和background-image然后background-image那一行被后面的background简写覆盖了。background简写会把所有子属性重置包括你没写的那些。所以简写和子属性不要混在一个选择器里随机排列要么全用简写要么全用子属性。5.2 文本格式化相关的高频坑现象可能原因解决方式单行省略号不生效元素在 flex 子项里且未设置min-width: 0补min-width: 0和overflow: hidden多行截断后省略号位置怪异line-clamp最后一行本身较短属机制限制必要时改 JS 计算text-shadow加了四个长度值失效该属性不支持扩散半径删掉第四个长度值中文段落断行断到标点后word-break: break-all生效中改为overflow-wrap: break-word用户输入换行显示成一整行white-space为默认normal改white-space: pre-wrap加了字距后居中偏左最后一个字符后也产生间距补负margin-right抵消子元素行高诡异错位父级用了带单位的line-height改成无单位数值多行截断那条我需要强调一下这是纯 CSS 方案固有的局限不是写法问题。如果你对省略位置的精确度要求很高比如必须保证最后一行至少显示若干个字那就得用 JS 做字符数估算或者让后端在存储时截好。这个取舍我在不同项目里做过不同选择内容运营后台可控的用纯 CSS用户自由输入的宁可多一行高度也不截断。5.3 兼容性与性能的取舍记录兼容性这块我现在的底线策略是linear-gradient和radial-gradient基本当基线能力用不做前缀conic-gradient用之前查一下目标机型做进度指示时准备纯色降级background-clip: text要带-webkit-前缀因为标准background-clip: text的支持来得晚line-clamp标准属性和-webkit-版本一起写。性能方面有三条实测经验。第一渐变本身是静态背景浏览器会缓存成纹理滚动时不重绘成本很低但如果你用background-position或background-size做动画就会每帧重绘大面积元素上明显掉帧改成transform位移一个更大的渐变层会好很多。第二多层text-shadow的成本和层数乘以模糊半径正相关标题上三四层大模糊阴影在长列表滚动时是能感觉出来的。第三backdrop-filter和filter会触发离屏渲染嵌套使用时开销叠加能不平铺就不平铺。提示调试渐变时把background-image单独抽到一个测试类里一次只加一个色标比在完整样式里盲改效率高出几倍。最后分享一个我自己在用的调试小技巧。渐变和文字的问题很多是看不出来哪一层出错所以我习惯临时加一层outline: 1px solid red把元素边界显出来特别是做渐变文字时你能立刻看出background-clip的裁剪范围到底是不是元素盒子还是只裁到了文字块的一部分。这个动作花三秒钟能省下十几分钟的猜测。我个人在实际操作中的体会是这两个主题真正难的地方不在于记住语法而在于建立渐变是一层要计算的像素、文本是一层要防守的排版这种意识。有了这个意识看到效果不对时你会本能地去算角度、去查属性有没有被简写覆盖、去想 flex 的自动最小宽度而不是漫无目的地试数值。
阅读完成 · 觉得有帮助?