
CSS这玩意儿入门门槛低到几乎不需要门槛但真到写项目的时候基础属性没有吃透的人会在最不起眼的地方卡壳半天。我见过不少前端新人会写CSS选择器知道color和font-size是什么但遇到中文字体为什么没生效margin为什么会重叠删除线怎么做都达不到效果文字渐变色怎么实现这类问题时还是得现场查资料。这篇东西的定位很简单把CSS基础属性里最常见、最实用、也最容易踩坑的部分从头到尾捋一遍。不管你是刚接触HTMLCSSJS基础语法的新手还是已经写了几个静态页面、正在往组件化和框架方向走的人都可以拿来当一份查漏补缺的笔记。文章里所有结论都来自我在真实页面上反复调出来的经验哪些写法兼容性好、哪些写法只是demo里好看但不适合上线我会直接说清楚。1. 先认清CSS基础属性在网页三件套里的真实地位1.1 结构、表现、行为的分工决定了CSS的学习路径很多人学CSS上来就背属性背了一堆却不知道为什么要学这些。其实CSS的全称是Cascading Style Sheets直译过来是层叠样式表它管的只有一件事网页长什么样。HTML负责结构JS负责行为CSS负责表现。这个分工搞清楚之后你再看热搜词里的html css js知识梳理html css js网页设计这类搜索本质都是想弄清楚三者的协作关系。我举个例子你就明白了。一个div里放一段文字HTML只负责告诉你这里有一段文字、它是一个段落至于这段文字是红色还是蓝色、是16px还是20px、是水平居中还是靠左全部由CSS决定。CSS基础属性就是这些决定背后的最小单元颜色属性、字体属性、盒模型属性、背景属性、布局属性。它们单独看都很简单组合起来却能实现从静态页面到动态交互的一切视觉效果。1.2 基础属性没吃透项目里到处是暗坑基础属性给人的感觉是太简单了简单到让人轻视。直到真正开始写项目你会发现一堆问题中文字体没生效抄了网上的font-family也不对给父元素设置了line-height子元素里的图标还是对不齐明明设置了width但padding一加盒子就变大了上下两个div的margin奇怪的合并在一起想做个梯形标签搜了css 变形 梯形半天抄了代码还是变形成功。这些问题没有一个是高级知识点全是基础属性之间的协作关系没有建立起来。所以基础属性的价值不在单个字典式掌握而在理解它们如何互相影响。这篇文章后面每一章我都会按先说清楚属性本身再说清楚它和其他属性怎么相处的方式来讲这也是我自己写样式多年的切身体会。2. 文本与字体属性字色、字族、删除线、渐变一次讲透2.1 color与font-size高频但格式值得注意color大概是最早接触的CSS属性但它没那么简单。color接受的格式至少有四种颜色关键词red、black这类、十六进制#ff0000或缩写#f00、rgb/rgbargb(255,0,0)、rgba(255,0,0,0.5)、hsl/hslahsl(0,100%,50%)。我这里放一张表方便对照格式示例常用场景关键词red, black, white快速demo、原型十六进制#ff0000、#f00最常用精确又省字符rgb/rgbargb(255,0,0)、rgba(0,0,0,0.5)需要透明度时hsl/hslahsl(210,60%,50%)同色系调整、配合透明度做主题色我平时最推荐的是十六进制和rgba。十六进制省事、压缩后体积也小rgba的优势是能控制透明度做hover效果或遮罩层时非常方便。hsl相对用得少但做同色系不同深浅时很好用比如hsl(210, 60%, 40%)和hsl(210, 60%, 60%)就是同一蓝色系的不同明度做渐变和配色特别高效。font-size的坑主要在单位。px是绝对单位em是相对父元素的字号rem是相对根元素html的字号。新手最常踩的坑是混用em和rem导致字号层层叠叠乱套。我的建议是项目里统一用rem做全局字号局部需要微调时用px少用em。这样页面缩放和适配时行为是可以预期的。浏览器默认字号一般是16px所以很多人习惯把html的font-size设为62.5%因为16px的62.5%正好是10px后面rem换算直接除以10比如1.4rem就是14px。这个技巧实用但一定要记得html根元素字号先设好再换算否则rem会按默认值计算一换算就是一道天坑。2.2 font-family的字族机制与中文字体坑font-family是最容易被忽视的基础属性之一。它的工作机制是浏览器从左到右检查字体列表中每个字体当前字体存在就用它不存在才用下一个。所以字体列表的顺序非常重要应该把最想用的放前面通用的兜底字体放最后。中文字体有一个特别坑的地方因为中文字体文件动辄十几MB网页通常不能直接加载完整中文字体只能依赖用户操作系统里已经安装的字体。所以写font-family时要针对不同系统给不同候选body { font-family: -apple-system, PingFang SC, Microsoft YaHei, Segoe UI, Helvetica Neue, Arial, sans-serif; }这里-apple-system是苹果系统专用PingFang SC是macOS/iOS的中文默认字体Microsoft YaHei是Windows的中文默认字体最后sans-serif兜底。如果你把宋体SimSun放前面Windows页面的现代感瞬间没了因为全站文字都会被渲染成衬线字体。另一个常见问题是只写微软雅黑不写它的英文名Microsoft YaHei在一些浏览器和系统里识别不了因为系统内的字体注册名可能是英文。2.3 删除线、下划线与字体的修饰细节热搜词里css 删除线搜索量不小说明很多人在做价格划线、任务完成态这类效果。删除线最直接的写法是text-decoration: line-through。但text-decoration其实是个复合属性完整展开是text-decoration-line、text-decoration-style、text-decoration-color.price { text-decoration: line-through #999; } .done { text-decoration: line-through wavy red 2px; }text-decoration支持的细节比多数人想的多你可以指定下划线的颜色、波浪线、粗细。不过它有个原生限制不能精确控制线条距离文字的高度也不能控制绝对粗细都是浏览器默认的。如果你在还原设计稿时需要删除线刚好压在文字1/2高度、粗细是1px更可靠的做法是用背景渐变模拟.del { background: linear-gradient(to right, #999, #999) center left / 100% 1px no-repeat; padding: 0 2px; }这个做法的本质是用线性渐变画一条1px高的灰线通过center left控制位置在文字垂直居中的地方。优点是可以随意调高度、位置、颜色缺点是需要给行内文字留出padding否则线会贴到文字边缘。具体用哪个方案取决于你是在做快速原型还是精细还原设计稿。2.4 字体渐变、换行与省略号的正确姿势热搜词里css 字体渐变频率很高。纯CSS实现文字渐变核心是background-clip: text.gradient-text { background: linear-gradient(135deg, #ff7e5f, #feb47b); -webkit-background-clip: text; background-clip: text; color: transparent; }原理其实很简单给元素设置一个背景渐变然后通过background-clip: text把背景裁剪到文字的形状内最后把color设为transparent文字就露出了背景色。注意必须保留-webkit-前缀否则Safari和部分安卓浏览器不认。坑还有两个一是如果元素背景设置了background-size造成渐变重复文字里会出现好几段颜色渐变需要把background-size调整成和元素尺寸匹配二是外部想加text-shadow在color: transparent的情况下阴影会直接透出来看起来像文字糊了一层影子真要阴影就得想别的方案。换行和省略号也是高频需求。单行省略号是固定的三件套.one-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }white-space: nowrap禁止换行overflow: hidden隐藏溢出内容text-overflow: ellipsis在溢出边缘显示省略号。三个属性缺一个都不行缺了nowrap它会换行缺了overflow它会撑出去缺了text-overflow就只是截断没有省略号。多行省略号推荐这样写.multi-line { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }-webkit-line-clamp: 3表示最多显示3行超出后就省略。这个写法虽然带-webkit前缀但主流现代浏览器都支持可以直接用。需要留意的是display: -webkit-box会覆盖元素原有的display值如果这个容器本身还需要flex布局两者会冲突通常在外层再套一个容器来处理布局。3. 盒模型属性所有布局问题的最终解释者3.1 盒子尺寸的计算方式与box-sizing的选择CSS里每个元素都是一个矩形盒子。盒模型由内到外分别是内容区content、内边距padding、边框border、外边距margin。这就是为什么你设置了div的width: 100px但它在页面上实际宽度可能是120px的原因——padding和border默认是加在width之外的。这个默认行为叫content-box意思是width只代表内容区宽度。还有另一个取值叫border-boxwidth代表内容区paddingborder的总宽度。用一个算式说明content-box实际宽度 内容区宽度 padding borderborder-box内容区宽度 width - padding - border绝大多数情况下你应该用border-box。因为给一个宽度确定的按钮加padding和border时你不会希望它被撑大导致换行。最简单的全局设置是*, *::before, *::after { box-sizing: border-box; }我做过不少老项目改造挨个元素去改box-sizing太痛苦了全局通配符一次解决。当然如果遇到需要精确控制内容区的特殊场景再单独写box-sizing: content-box覆盖。这个属性看起来不值一提却是所有盒模型计算的起点也是面试里经常被拿来问为什么你的div比设定的宽了一半的答案。3.2 border不只是边框三角形和梯形的自绘方案热搜词里有css 变形 梯形很多新手第一反应是用transform但纯border也能画出梯形甚至三角形。原理是元素的四条边框在元素角落处是以45度斜角相接的当元素本身宽高为0时border的四个区域会形成四个三角形拼接的视觉效果。三角形的经典写法.triangle { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid #333; }这段代码生成的是一个底边100px、高100px的朝上三角形。原理是左右边框透明、下边框有颜色下边框会在底部撑开一个三角形另外两侧透明部分用于撑起形状。如果给四个方向都设置不同颜色你甚至能拼出菱形和更复杂的图形。梯形的做法和三角形类似关键是让元素拥有一个非零的width.trapezoid { width: 80px; height: 0; border-left: 60px solid transparent; border-right: 60px solid transparent; border-bottom: 100px solid #f80; }此时左右透明边框和底部实心边框组合出来的就是一个上窄下宽的等腰梯形。这个技巧常被用来做导航菜单的斜肩标签、价格标签、气泡尾巴。不过用border画形状最大的问题是内容很难放进去因为宽高是0或者很小。所以这类图形更适合做装饰元素真正要往里放文字的梯形还是用transform或clip-path更合理具体我放到第六章展开。3.3 margin的合并与居中margin是盒模型里最让人迷惑的属性之一因为它存在外边距合并margin collapsing机制。相邻两个元素垂直方向上的margin不会相加而是取较大值。比如上面div的margin-bottom是30px下面div的margin-top是20px两者之间的距离不是50px而是30px。这个行为常让新手抓狂他们会困惑为什么我明明设了边距它就是不生效。合并的触发条件通常是相邻兄弟元素之间、父子元素的margin-top或margin-bottom发生重叠、空容器的上下margin。解决思路有三种改用padding代替其中一个margin给父元素设置overflow: hidden或display: flow-root触发BFCBlock Formatting Context阻断合并直接用flex或grid布局现代布局方式下margin合并不太会出现。水平和垂直居中是另一个高频需求。水平居中最简单的是text-align: center作用于行内元素和文字或者对块级元素设置margin: 0 auto前提是元素有明确宽度。垂直居中的经典老办法是让line-height等于容器高度仅适用于单行文本.box { height: 100px; line-height: 100px; text-align: center; }这招在按钮文字垂直居中里非常常见。多行内容的居中最稳的还是flex.box { display: flex; justify-content: center; align-items: center; }flex出现之后很多老式hack比如table-cell法、绝对定位加负margin法都可以退役了。但理解老方法的原理还是有价值的至少你知道它们为什么能居中在哪些特殊场景下它们仍然可靠。3.4 容器内文本位置怎么调整热搜词怎么调整css容器里的文本位置其实涵盖了好几个维度水平方向、垂直方向、与容器的间距。我按场景拆开说水平方向text-align控制文字对齐left/center/right可选。它作用的对象是行内内容所以img、span也受它影响。垂直方向单行文本用line-height等于height最直接多行用flex加align-items: center或者padding上下撑开。文本与容器的间距用padding而不是text-indent。text-indent只能控制首行缩进控制不了整体缩进很多人在这里写错。中文和英文混排时vertical-align也会影响文本的垂直对齐特别是在img和文字并排的场景。给图片设置vertical-align: middle往往比调整margin更靠谱。还有一个小细节text-align设置在外层容器上对内层文字生效但如果块级元素内部放的是另一个块级元素子元素里的行内内容要继承text-align需要子元素自己没有覆盖text-align。这些细微差别实际调样式时最能拉开效率差距。4. 背景属性与视觉细节涟漪光圈、banner背景图的底层逻辑4.1 background的构成属性与简写background是CSS基础属性里最多合一的属性它至少由以下属性构成background-color背景色background-image背景图可以用url()引入图片也可以是渐变background-repeat是否平铺repeat、no-repeat、repeat-x、repeat-ybackground-position背景图位置left top、center、百分比background-size背景图尺寸cover、contain、具体像素值。其中background-size: cover是高频写法它让背景图等比缩放并覆盖整个容器超出的部分裁剪掉contain则是让整张图片缩放并完整放进容器可能有留白。做banner背景图时cover几乎是默认选择因为banner通常不需要展示图片全貌只需要填满这个区域。background简写的时候顺序可以随意但size必须写在position后面并用/分隔比如background: url(x.jpg) center / cover no-repeat。最容易犯的错是写着写着忘记写no-repeat结果小图被平铺成满屏。另外注意背景图默认跟随内容滚动如果希望固定不随页面滚要用background-attachment: fixed长页面做视差效果时常用。4.2 涟漪光圈扩散效果的核心拆解热搜词css涟漪光圈扩散是很多用户想用纯CSS做交互反馈时的搜索词。涟漪光圈的实现核心其实只有三件事一个居中定位的伪元素、一个从scale(1)到scale(更大值)的transform动画、一个不断降低的opacity。代码演示.ripple { position: relative; display: inline-block; width: 120px; height: 120px; line-height: 120px; border-radius: 50%; background: #1677ff; color: #fff; text-align: center; } .ripple::after { content: ; position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 50%; background: rgba(22, 119, 255, 0.35); animation: ripple 2s ease-out infinite; } keyframes ripple { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(2); opacity: 0; } }核心思路是用一个绝对定位的伪元素覆盖整个按钮或卡片让它在动画中从1倍大小放大到2倍同时透明度降到0。因为动画是infinite无限循环视觉上就像一圈圈光波不断扩散。想让光圈更柔和就把伪元素的background换成径向渐变radial-gradient从内圈透明到外圈更透明效果会更接近真实物理的光晕。想让多圈同时扩散可以用::before和::after分别延迟动画或者给animation-delay设负值错开起始帧。我很建议你在理解这个demo之后记住绝对定位伪元素动画这个组合。绝大多数纯CSS动态效果——水波纹、呼吸灯、按钮光晕——都是这个组合的变体。基础属性看似零散真正组合起来才是干活的东西。4.3 动态相册与banner背景图的实践思路热搜词里还有css动态相册纯代码和css第四天综合案例banner效果背景图这两个其实都指向同一种能力用CSS让背景或图片动起来。动态相册最简单的实现是让元素背景在几张图片之间循环切换.album { width: 300px; height: 200px; animation: slideshow 9s infinite; } keyframes slideshow { 0%, 30% { background-image: url(pic1.jpg); } 33%, 63% { background-image: url(pic2.jpg); } 66%, 100% { background-image: url(pic3.jpg); } }这里关键帧的百分比不能乱算。每张图片的显示时长要一致三张就切成33%、66%、100%通过0%-30%、33%-63%、66%-100%的区间保证每张图片停留时间相同。但background-image本身不能做渐变过渡切换是瞬间的。要让切换有淡入淡出效果得用两个相互叠加的图层交替控制opacity——复杂度会上去但原理仍然是伪元素opacity动画的组合。做产品时还要注意不要用纯背景图放重要信息否则图片加载失败时信息直接消失重要内容应该用img标签加alt属性兜底。banner背景图的做法其实也就三步容器设好宽高背景图用background-size: cover铺满再把文字用flex居中。如果还要加蒙版就在文字和背景之间加一层半透明黑色背景层可以是伪元素也可以是一个独立的div属性上就是rgba背景色加一个z-index层级问题。别看banner效果在课程案例里很常见它把背景属性、盒模型、flex布局全串起来了是很好的综合练习。5. 选择器与样式引入方式CSS如何精准“命中”元素5.1 三种样式引入方式与file协议下的常见报错CSS样式引入方式有且基本只有三种外链样式、内嵌样式、行内样式。热搜词里css样式引入方式第2关css样式引入方式都指向这个基础知识点。外链方式在HTML的head里写 hrefstyle.css relstylesheet/ 。优点是可复用、可缓存、便于维护是项目里唯一推荐的方式。内嵌方式直接在HTML里写 。适合单页demo或临时调试不推荐在真实项目里用因为无法跨页面复用。行内方式在标签上写stylecolor: red。优先级最高但和结构耦合太深几乎无法维护只适合非常临时的样式覆盖。关于外链有一个实际项目里常见的新手报错值得单独说热搜词里出现了access to css stylesheet at file:///c:/users/administrator/desktop/...这种报错这是浏览器从file协议直接打开本地HTML文件时出于安全策略拒绝加载本地CSS文件导致的。这种问题不是CSS写错了而是用浏览器直接双击了本地HTML。正确做法是起一个本地静态服务器——最简单的命令是npx serve或python -m http.server然后通过http://localhost访问页面。开发时养成本地起服务器的习惯能避开一堆file协议带来的诡异问题。5.2 从基础选择器到伪类的进阶路径选择器是CSS用来找到元素的手段基础属性写得再好选择器写歪了也白搭。基础选择器有四类标签选择器p { }选中所有p标签影响范围最大类选择器.btn { }最常用可以重复使用ID选择器#header { }唯一性最高但不建议给样式用ID因为无法复用通配符选择器* { }选中所有元素一般只用于重置样式。在此基础上组合选择器解决的是精确命中问题.nav li { } /* 子代选择器只选nav下的直属li */ .main .card { } /* 后代选择器选main内所有.card */ h2 p { } /* 相邻兄弟选择器选h2后面紧邻的p */ input[typetext] { } /* 属性选择器选type为text的input */伪类选择器是让CSS具备状态能力的关键。最常见的:hover表示鼠标移入:active表示按下:focus表示获得焦点:nth-child(n)可以按位置选中子元素::before和::after这两个伪元素能凭空生成内容是画三角形、做涟漪光圈的基础。基础属性加上合适的伪类或伪元素几乎能实现任何视觉组件。这部分和热搜词里css选择器css 鼠标移入事件直接相关后面我会结合hover再展开。5.3 优先级与!important的边界多个选择器同时命中同一个元素、且设置了相同属性时听谁的由优先级决定。优先级从高到低大致如下优先级档位内容示例最高!importantcolor: red !important次高行内样式stylecolor:red高ID选择器#header中类/属性/伪类选择器.btn、[typetext]、:hover低标签/伪元素选择器p、::before最低默认样式和继承值浏览器默认规则可以理解成ID一个大数值、类一个中小数值、标签一个小数值三种分值相加分数高的生效。同分数时后写的生效。我在团队里见过一个很无奈的情况为了覆盖一个类样式有人直接在另一个类里加!important然后下一个同事又要用!important去覆盖最后代码里满是!important谁都不敢动。我的建议是!important只用于覆盖第三方无法触及的样式或者作为紧急兜底日常开发里遇到优先级问题优先调整选择器结构而不是加!important。CSS的层叠机制本身希望你利用顺序和特殊性来控制样式而不是靠硬写来对抗。6. 布局与位移position、transform与鼠标移入事件的配合6.1 position四种定位方式的使用场景position有static、relative、absolute、fixed、sticky五个取值前四个是基础。static是默认值相当于没有定位。relative是相对自己原来的位置偏移定位参照系是元素自身。absolute是绝对定位它会脱离正常文档流参照最近的已定位祖先position不是static的祖先如果没有就参照浏览器视口。fixed相对视口固定不随页面滚动。实际项目里最常见的组合是父元素relative 子元素absolute。比如做banner图上的标语、按钮上的小红点、涟漪光圈的光圈层都是这个组合。举个例子在按钮右上角加一个数字角标.btn-wrap { position: relative; } .btn-badge { position: absolute; right: -6px; top: -6px; padding: 2px 6px; border-radius: 999px; background: #f00; color: #fff; font-size: 12px; }这里right和top用负值是为了让角标突出到按钮边缘之外。absolute脱离文档流的特性让这类装饰性元素不影响原来的布局。sticky虽然出场晚但做吸顶导航很实用给一个元素设置position: sticky; top: 0它会在滚动到指定位置时粘住。sticky有两个坑要提前知道它只在父容器范围内生效父容器高度不足以产生滚动时它不会粘住而且它必须设置top或left等触发值才有效光写position: sticky等于没写。6.2 梯形变形的三种思路把css 变形 梯形这个热搜词单独拎出来讲因为它特别能说明CSS基础属性组合的威力。实现梯形至少有三种思路各有适用场景先看对照表方案核心写法优点缺点border法width非0 左右透明边框 底部实心边框纯CSS、代码少内容放不进只能做装饰transform法perspective rotateX元素内容保留容器可放文字文字会轻微变形clip-path法polygon多边形裁剪最灵活内容不变形裁剪区外无交互老浏览器兼容一般border法在第三章已经给过代码这里重点看transform法和clip-path法。transform法的关键是用perspective给元素一个透视视角然后rotateX旋转.trapezoid { width: 200px; height: 100px; background: #f80; transform: perspective(100px) rotateX(10deg); transform-origin: top; }给元素加perspective后旋转视觉上产生上窄下宽的梯形。因为旋转的是整个盒子容器内部的文字和子元素也会跟着变形但10度以内基本看不太出来。transform-origin默认在中心改成top会让底边保持固定、顶边向内收缩更容易得到自然的梯形效果。clip-path法更直接.trapezoid { width: 200px; height: 100px; background: #f80; clip-path: polygon(15% 0%, 85% 0%, 100% 100%, 0% 100%); }clip-path按多边形裁剪元素四个点从左上的15%、0%开始到右上85%、0%再到右下100%、100%最后是左下0%、100%把左上和右上往里收就得到梯形。这个方法最灵活内部内容不变形复杂切角都靠它。缺点前面说了裁剪区外的部分鼠标事件不生效做hover和点击效果时要特别小心。6.3 hover鼠标移入事件与过渡动画热搜词里css 鼠标移入事件说得通俗其实就是:hover伪类。基础用法是鼠标移上去改变样式.btn { background: #1677ff; transition: background 0.3s ease; } .btn:hover { background: #0f5dd4; }注意transition写在.btn上而不是.btn:hover上。为什么因为transition是要让元素从A状态过渡到B状态再回退到A状态的如果你只写在:hover里鼠标移出时样式会瞬间跳回原样毫无过渡。写在原状态上移入移出都有动画。这个细节我问过很多新人十有七八都搞反了。cursor属性也常和hover一起出现。cursor: pointer表示手型光标cursor: not-allowed表示禁止这两个在UI里最常用。还有一点要注意移动端没有真正意义上的hover手指触摸一次会触发hover再点一次才会触发点击事件。所以在移动端设计时不要把关键交互只挂在:hover上否则用户会感觉按钮点了没反应。transition可以过渡的属性很多background、color、transform、opacity、box-shadow这类视觉属性都支持。但display不支持过渡所以做下拉菜单展开时不能从display: none到display: block过渡正确做法是用opacity和visibility组合或者用max-height技巧。7. 基础属性学完之后往哪些方向走更有价值7.1 原子性CSS与工具类设计热搜词里原子性css是一个值得展开的方向。原子化CSS本质是把每一条样式声明拆成独立的工具类比如.text-center代表text-align: center.p-4代表padding: 1rem。这种方式在Tailwind CSS等框架里被发扬光大。它的优势是样式类完全可复用、减少重复定义、开发者不用频繁起语义化类名劣势是HTML里类名很长可读性下降团队里需要约定工具类的命名规范。从基础属性理解原子CSS其实很容易——每一个工具类背后就是一条基础属性声明。我建议学习基础属性阶段就把属性拆细、理解清楚这样看原子CSS就像在看属性字典基本不需要额外学习成本。如果你要用它初期先用它自带的核心工具类不要一上来就自定义各种奇怪的类保持简单才能享受它的效率。7.2 CSS Houdini代表的样式系统未来另一个热搜词css houdini看起来很高深其实一句话能说清CSS Houdini是一组浏览器底层API它允许开发者用JavaScript直接参与CSS引擎的工作比如注册自定义CSS属性、定义动画属性类型、用paint worklet绘制自定义图形。它让CSS从只能使用浏览器提供的样式变成了可以自己扩充样式规则。当前它还没完全普及但Chrome等现代浏览器的支持度一直在提升。对刚学完基础属性的人来说了解Houdini的意义不在于马上用而在于知道CSS这条线还有很深的技术演进空间。基础属性是地基Houdini是地基之上更灵活的框架先把地基打好再关注前沿路径最稳。我做前端这些年最深的体会是所有看着高级的CSS效果拆到底都是基础属性的组合。能把字体这些基础坑说清能把盒模型搞透能在需要时想到border画形状能用伪元素做光晕比背下十个高级关键词有用得多。如果你正在入门别急着堆从入门到精通的学习量先把彩色文本、盒模型、背景、定位、选择器这些属性之间的为什么想明白再去看那些炫酷demo你会发现你已经有了拆解它们的底子。最后再分享一个小习惯每学一个CSS属性就在浏览器里同时改它的几个取值对比看眼见为实比背一百个写法都牢靠。CSS从来不是背出来的是调出来的。