写了快十年的前端我一直保持着随手记录笔记的习惯。这份“HTML-CSS笔记_0424”是我某次整理本地文档时的产物里面记的都是日常开发中反复用到、但偶尔还是会卡壳的知识点从HTML文档骨架到CSS盒模型、居中方案、文本装饰、动效交互再到各种零碎的避坑经验。今天把这些笔记重新梳理了一遍把其中最核心、最容易被问到、也最实用的部分展开讲讲希望能给正在学前端、或者做全栈偶尔需要写页面的朋友一些参考。先简单交代一下这篇笔记适合谁刚学完HTML和CSS基础语法想系统梳理知识体系的初学者写过一些页面但对布局、居中、样式优先级这些概念还比较模糊的准中级开发者以及像我一样需要经常回头查笔记的老手。内容不会停留在“这个属性是干什么的”层面更多会讲我实际用下来觉得好用的方案以及那些让新手抓狂的坑是怎么踩、怎么绕的。1. HTML文档骨架为什么doctype和meta这么重要1.1 标准文档结构的逐行拆解先看一个我每次写页面都会用到的标准骨架!DOCTYPE html html langzh-cn head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title页面标题/title /head body !-- 页面主体内容 -- /body /html这段代码看起来简单但每一行都有它的讲究。!DOCTYPE html是文档类型声明它告诉浏览器“我用的是HTML5标准来解析这个页面”。很多人会忽略它但如果不写浏览器会以怪异模式Quirks Mode渲染页面导致盒模型计算、行高、字体渲染都跟你预期的不一样。我在面试新人时经常问这行代码的作用能答清楚的确实不多。html langzh-cn里的lang属性也不能小看。它告诉搜索引擎和屏幕阅读器这个页面的主要语言是简体中文对SEO和无障碍访问都有影响。如果你做的是英文页面记得改成langen。有些团队会忽略这个属性我个人建议永远不要省。meta charsetutf-8这行决定了字符编码。UTF-8是国际通用的编码方式支持所有语言字符如果漏掉它页面里的中文很可能会变成乱码。这行是HTML5里唯一一个必须放在head最前面的meta标签因为浏览器需要尽早知道页面的编码方式。1.2 meta标签的常用配置与选择逻辑除了 charsetmeta还有一些实用配置我按照使用频率整理在下面meta标签作用使用建议meta nameviewport contentwidthdevice-width, initial-scale1.0控制移动端视口所有响应式页面必备不写的话手机端字会特别小meta namedescription content页面描述设置页面描述会影响搜索引擎展示摘要建议每页写一句meta namekeywords content关键词设置页面关键词对搜索引擎权重的影响已经很小但写了无害meta nameauthor content作者名标明作者团队项目建议统一规范meta http-equivX-UA-Compatible contentIEedge兼容旧版IE如果是现代项目基本可以不用管了这里面最容易踩坑的是 viewport。我第一次写移动端页面时忘了加这行结果在手机上打开整个页面被浏览器缩成一个小方块用户体验非常差。原因很简单没有 viewport 声明时移动浏览器默认以 980px 左右的宽度渲染页面然后再缩放到屏幕宽度。加了widthdevice-width之后页面宽度才会和屏幕宽度对齐1px 才是真正的 1px。1.3 语义化标签怎么选才合理HTML5 引入了header、nav、main、article、section、aside、footer这些语义化标签它们比纯粹的div更能表达内容结构。我在笔记里专门记过几条选择标准后来也一直按这个来页面顶部的导航区用header和nav不要把整个页面都塞进header独立成块的内容比如一篇博客、一个商品卡片用article同一主题下的内容分组用section可以在里面继续嵌套section和主内容关系不大的补充区域用aside页脚信息用footer如果一段文字只是单纯为了样式分组没有语义含义才用div语义化不能过度把div全部换成section并不是进步。我的经验是先想清楚这个区块“内容上是什么”再选标签。打个比方article就像一本书里的独立文章section像文章里的小节div则像没有任何含义的包装盒。2. CSS定义与引用从三种引入方式到特异性优先级2.1 外部样式、内部样式、行内样式的使用场景CSS 有四种引入方式除了最常见的三种还有一种通过import引入的方式不过现在基本不推荐了。我把它们对比一下引入方式写法位置适用场景缺点外部样式表写在单独的.css文件通过link引入正式项目、多页面共用样式需要额外请求文件内部样式表写在style标签里单页面、演示页面、邮件模板不能复用行内样式写在元素的style属性里动态样式、覆盖场景优先级太高难以维护import写在CSS文件顶部极少使用阻塞渲染性能差正式项目里我推荐全部使用外部样式表。原因很简单浏览器可以缓存 CSS 文件用户访问第二个页面时不需要重新下载样式。一个几十KB的CSS文件如果被十几个页面共用缓存带来的性能收益非常可观。import这个方式我特别提一下因为它看起来很方便在CSS文件第一行写import url(common.css);就能引入另一个CSS文件但实际上它会在页面加载时阻塞渲染而且只有等这个CSS文件下载完浏览器才知道下一步该做什么。真实项目中完全没有必要用它用多个link标签引入效果更好。2.2 三种引入方式冲突时的优先级怎么算当同一个元素被多种方式设置了相同属性时浏览器会根据一个叫“特异性”Specificity的规则来决定哪个声明生效。简单排序是行内样式 ID选择器 类选择器/属性选择器/伪类 元素选择器/伪元素 通配符。我见过太多新手在这个地方栽跟头尤其是“辛辛苦苦写了一行样式页面上却没有任何反应”。举一个实际例子/* 外部样式 */ .title { color: blue; } /* 内部样式 */ .title { color: red; }如果这两个规则同时生效最终显示红色。为什么因为后加载的样式会覆盖先加载的相同优先级规则。如果你在link引用了外部CSS又在style里写了同名规则style在后它就赢了。如果还不动可能是你的规则选择器权重太低了。比如style h1 { color: green; } /style h1 classtitle标题/h1同时存在h1标签选择器和.title类选择器时类选择器的权重更高所以颜色会是类选择器里定义的那个如果你在别处定义了。正确答案是避免依赖这种覆盖链来写样式尽量保持选择器扁平、特异度一致省得后面改样式时抓狂。2.3 通配符*的优缺点以及我在什么情况下会用它热词里有一个“css 样式表中使用*的优缺点”我笔记里正好记过一段。*通配符会选中页面上所有元素。最常见的用法就是清零默认边距* { margin: 0; padding: 0; }优点很明显一行代码就把浏览器默认的边距全部干掉写样式时不用再反复初始化。缺点同样明显*会遍历页面中每一个元素在大型页面上会产生性能损耗而且它会覆盖所有元素的默认样式如果你的重置规则和组件库冲突排查起来相当头疼。我现在更推荐用这份更精细的重置方式*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }加上box-sizing: border-box是重点后面讲盒模型时会详细说。另外如果你用了像 reset.css 或 modern-normalize 这样的工具库就不需要自己写*重置了避免重复。2.4 原子性CSS一种极端的样式复用思路热词列表里还有“原子性css”这个理念很有意思原则是每个类名只负责一个样式属性。比如.text-center { text-align: center; } .text-left { text-align: left; } .mt-10 { margin-top: 10px; } .mb-20 { margin-bottom: 20px; } .font-bold { font-weight: bold; }这样做的优势是复用度极高写页面时直接在HTML上组合类名就行基本不用再写新的CSS。缺点是HTML会变得很长类名一多就不太好看。现在流行的 Tailwind CSS 其实就是这个思路的集大成者。我的态度是小项目或者原型阶段可以用大型项目如果团队没有统一规范建议还是谨慎不然很容易产生一批看不懂的类名组合。3. 盒模型把布局的基础彻底讲透3.1 content、padding、border、margin 的尺寸计算规则盒模型是CSS里最基础也最核心的概念。任何元素在页面上都被浏览器当做一个矩形盒子由内到外依次是内容区content、内边距padding、边框border和外边距margin。默认情况下即box-sizing: content-box给元素设置的width和height只作用于内容区实际占用的宽度是总宽度 width padding-left padding-right border-left border-right 总高度 height padding-top padding-bottom border-top border-bottom这个规则让很多新手困惑我明明设置了width: 200px怎么元素宽度看起来不止200px没错因为 padding 和 border 是额外加在200px之外的。解决办法就是前面提到的box-sizing: border-box。把它设置之后width: 200px表示元素总宽度就是200pxpadding 和 border 会自动从内容区里挤内容区会变小。这样布局时更好心算也更符合直觉。我现在的习惯是全局加上这条规则这就是为什么前面重置样式里要写* , *::before, *::after { box-sizing: border-box; }。3.2 盒模型相关的常见坑margin合并与溢出写CSS时最容易遇到的盒模型问题是 margin 合并Collapsing Margins。上下相邻的两个块级元素它们的 margin-bottom 和 margin-top 不会相加而是取最大值。比如上面元素有margin-bottom: 50px下面元素有margin-top: 30px最终两个元素之间的间距是50px不是80px。解决方式有几种给其中任意一个元素加上display: flow-root、overflow: hidden、padding或border打破合并条件。我自己最常用的是给父容器加padding或者overflow: hidden虽然各有同学喜欢用display: flow-root这个属性也是现代浏览器都支持的。另一个常见坑是子元素设置了 margin-top结果父元素跟着“掉”了下来。这是因为子元素的 margin 和父元素的 margin 发生了合并。解决方式给父元素加padding-top代替子元素的margin-top或者给父元素设overflow: hidden。还有一个就是内容溢出。给固定宽高的容器放入了过长的文字或大图内容会撑破或溢出。排查时先检查是不是盒模型计算问题确定不是之后再考虑用overflow: hidden隐藏或者用word-break: break-all强制换行。3.3 水平居中、垂直居中、完美居中的方案对比css怎么把input居中、css body居中、怎么调整css容器里的文本位置这几个热词背后其实是同一个需求让内容居中。我笔记里专门整理了一张表记录不同场景应该用哪种方案。场景方案关键代码优缺点块级元素水平居中设置 margin: automargin: 0 auto;需要元素有确定的宽度行内元素或行内块水平居中父容器设置文本居中text-align: center;简单直接单行文字垂直居中设置行高等于容器高度height: 50px; line-height: 50px;只适合单行文本任意元素垂直水平居中使用 flex 布局display: flex; justify-content: center; align-items: center;现代布局首选兼容性好任意元素垂直水平居中使用 grid 布局display: grid; place-items: center;代码最简适合现代浏览器任意元素垂直水平居中绝对定位加 transformposition: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);适用于脱离文档流的元素我平时最推荐 flex 方案因为代码简单、语义清晰而且几乎不需要考虑子元素的尺寸。那为什么还需要绝对定位transform主要是某些场景下元素需要浮在父容器中间比如弹窗遮罩、加载动画。这时 flex 虽然也能用但绝对定位更容易控制层级关系。顺带提一下让 body 整体居中的正确打开方式是body { min-height: 100vh; display: flex; justify-content: center; align-items: center; }不给 body 设置高度单纯依靠margin: auto是没法让整个页面内容垂直居中的因为 body 的默认高度是由内容撑开的不存在多余空间。这个坑我早期踩过好多次。4. 文本与字体样式从删除线到渐变字体的实战4.1 字体栈的正确写法和字体加载顺序字体样式是CSS里看似简单、实际门道很多的部分。先说最基础的font-family。不能只写一个字体名因为用户电脑上不一定装了那个字体。标准做法是写一组字体栈body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Arial, sans-serif; }这个字体栈的逻辑是在苹果设备上优先用系统字体在Windows上优先用微软雅黑都没有再退化到 Arial 等通用字体。注意中文字体名要加引号避免和CSS关键字冲突。字体加载顺序很重要先字母数字的字体再中文字体最后才是通用字体。如果你把sans-serif写在前面浏览器会直接忽略后面的中文字体列表因为通用字体已经兜底了所有字符都会用默认无衬线字体显示。4.2 删除线、下划线、段落分割线的实现技巧热词里出现了“css 删除线”和“css实现段落分割线”这两个都是实际开发里很常见的小需求。删除线用text-decoration实现.del { text-decoration: line-through; }如果需要对删除线做颜色、粗细的控制可以用text-decoration-line、text-decoration-color、text-decoration-thickness这几个子属性比如.del { text-decoration-line: line-through; text-decoration-color: #e74c3c; text-decoration-thickness: 2px; }段落分割线则有两种做法。一种是简单用边框.divider { border-top: 1px solid #e0e0e0; }另一种是带文字的“分割线标题”这种更常见比如“———— 猜你喜欢 ————”。用 flex 实现非常方便.divider { display: flex; align-items: center; color: #999; font-size: 14px; } .divider::before, .divider::after { content: ; flex: 1; height: 1px; background: #e0e0e0; } .divider span { margin: 0 16px; white-space: nowrap; }之后在HTML里写div classdividerspan猜你喜欢/span/div中间的横线会自动拉长填满容器两侧文字自动居中非常稳定。这里flex: 1是关键它让伪元素平均分配剩余空间文字两侧的横线就一样长了。4.3 字体渐变和外描边让文字不单调这两个属于CSS里比较进阶的文本效果。文字渐变必须结合background-clip来实现单纯给color设渐变值是不行的.gradient-text { background: linear-gradient(90deg, #ff7e5f, #feb47b); -webkit-background-clip: text; background-clip: text; color: transparent; }原理是先给文字的背景设置渐变色然后把背景裁剪到文字的形状上最后把文字颜色设为透明渐变就“透”出来了。注意兼容性某些老浏览器需要-webkit-前缀。文字外描边用-webkit-text-stroke.outline-text { -webkit-text-stroke: 2px #333; color: transparent; }-webkit-text-stroke虽然带浏览器前缀但大部分现代浏览器都支持得很好。它可以实现描边字、空心字、双色字等效果。如果要做发光效果可以叠加text-shadow这在做标题、Logo、活动页时非常好用。4.4 input输入框的文本位置和光标控制“css中怎么把input居中”这个热词我展开说说。input 是行内块元素直接text-align: center只能让输入的文字居中输入框本身不会居中。让输入框在容器里居中还是得靠父容器的 flex.input-wrapper { display: flex; justify-content: center; align-items: center; } input { text-indent: 10px; }text-indent用来控制输入文字的起始缩进这样输入的字不会紧贴边框视觉上更舒服。另外padding也能起到类似作用还可以增大点击区域。还有个小技巧默认情况下 input 在聚焦时会有一个蓝色的轮廓outline如果不喜欢可以去掉但注意要设置替代的焦点样式保证键盘导航的用户能看清焦点在哪。5. 布局进阶定位、Flexbox 与现代布局方案5.1 position五种值的适用场景对比CSS 定位方式总共有7种值日常最常用的是5种。笔记里我这样记值定位基准是否脱离文档流典型场景static默认无定位否默认文档流relative自身原本的位置否微调元素位置、作为absolute的父级absolute最近的定位祖先元素是弹窗、角标、上下左右贴边fixed浏览器视口是返回顶部按钮、固定导航栏sticky滚动容器是滚动时吸顶导航、表格头部固定我最想叮嘱的是absolute它查找的祖先元素必须是设置了position: relative、absolute、fixed或sticky的最近节点如果所有祖先都没有定位它会以body初始包含块为基准。很多新手写下拉菜单发现位置不受控制就是因为忘了给父级加position: relative。sticky是个特别好用的属性它和fixed的区别是sticky元素在滚动到达指定位置之前是普通的文档流元素到达指定位置之后才“粘住”继续滚动之后又会“弹走”。吸顶导航一般可以这样写.nav { position: sticky; top: 0; z-index: 100; }注意sticky生效的前提是父容器有足够的滚动空间如果父容器高度跟子元素一样高它就不会有粘住的机会。5.2 Flexbox核心属性速查与实战Flexbox 可以说是目前使用频率最高的布局方案。笔记里把它的核心属性分成了两组容器上的属性和项目上的属性。容器上的属性display: flex开启弹性布局让子元素在主轴方向排列flex-direction控制主轴方向默认row从左到右改成column则从上到下justify-content控制主轴方向的对齐方式常用值flex-start、flex-end、center、space-between、space-around、space-evenlyalign-items控制交叉轴方向的对齐方式常用值stretch、flex-start、flex-end、centerflex-wrap控制是否换行默认nowrap内容太多时会压缩改成wrap才会换行gap控制子元素之间的间距比margin更干净项目上的属性flex-grow定义项目的放大比例默认为0设置了1以上才会占据剩余空间flex-shrink定义项目的缩小比例默认为1容器空间不足时会压缩flex-basis定义项目在分配剩余空间之前的主轴尺寸和width类似align-self单独控制某一个项目在交叉轴上的对齐方式order控制项目的排列顺序值越小越靠前一个常见的三栏布局用 flex 可以这样写.container { display: flex; gap: 20px; } .sidebar { flex: 0 0 200px; } .main { flex: 1; }flex: 0 0 200px的意思是不放大、不缩小、基础宽度200px。flex: 1是flex: 1 1 0%的简写表示空间不足时等比例缩小并且会占用所有的剩余空间。这样侧边栏固定主区域自适应比 floats 或 inline-block 的方案稳定得多。5.3 案例拆解用HTML/CSS实现educoder风格顶部导航栏热词里有一个很有意思的案例使用 html/css 实现 educoder 顶部导航栏。这个需求代表了很经典的企业官网顶部导航结构拆开看主要包含三块网站 Logo 或产品名左侧导航菜单项中间或右侧用户名或操作按钮右侧我用 flex 来实现10分钟就能搭好header classnavbar div classlogoEducoder/div nav classmenu a href#首页/a a href#课程/a a href#实训/a a href#竞赛/a /nav div classuser button classbtn登录/button button classbtn btn-primary注册/button /div /header对应CSS.navbar { display: flex; align-items: center; justify-content: space-between; height: 60px; padding: 0 24px; background: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .menu { display: flex; gap: 24px; } .menu a { text-decoration: none; color: #333; font-size: 14px; padding: 6px 12px; transition: color 0.2s; } .menu a:hover { color: #1890ff; } .user { display: flex; gap: 12px; }关键点是justify-content: space-between它让左边Logo、中间菜单、右边按钮组三块内容在水平方向均匀分布。菜单项用gap控制间距鼠标悬停的颜色变化用transition做了平滑过渡。这就是一个很实用的导航栏不管后续怎么扩展比如加下拉菜单、加搜索框框架都不用动。6. 交互与动效鼠标事件、动画和涟漪效果6.1 CSS中的“鼠标移入事件”hover伪类及其局限CSS里没有真正意义上的“鼠标移入事件”我们平时说的这个功能绝大多数是:hover伪类实现的。它能在鼠标悬停在元素上时触发一组样式变化.btn { background: #333; color: #fff; transition: background 0.3s, transform 0.3s; } .btn:hover { background: #555; transform: translateY(-2px); }:hover可以配合transition做平滑过渡这是最基础的悬停交互。但它的局限也很明显只能控制“悬停”这一种状态管不了鼠标移入和移出这两个时间点更做不了复杂的交互逻辑。如果需要在鼠标移入时触发AJAX请求、改变其他元素状态、或者做动画播放控制那必须上JavaScript用mouseenter和mouseleave事件。另外要提醒的是移动端没有真正的“鼠标悬停”:hover在触屏设备上行为非常不稳定所以重要交互不要只依赖 hover要额外考虑点击态:active和焦点态:focus。6.2 transition 与 animation 的选择逻辑CSS里做动效有两套体系transition过渡和animation动画。简单来说transition是“状态切换时的平滑过渡”它需要两个状态比如默认态和hover态才能生效animation是“自定义关键帧动画”可以定义多个时间点的样式并且可以循环、反向播放。选哪个我一般按下面几个问题来判断是否只在两个状态之间切换用transition是否需要循环播放用animation是否需要多个中间步骤比如弹跳效果用animation是否需要暂停、反向、控制进度用animation只是 hover 时变个颜色、变大变小用transition一个典型的animation写法keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .box { animation: fadeInUp 0.6s ease-out both; }both关键字的意思是动画开始前应用from的样式动画结束后保留to的样式这样不会出现动画播放前元素突然出现、播完后元素又闪走的尴尬。6.3 涟漪光圈扩散效果的实现思路热词里有一个“css涟漪光圈扩散”这个效果常用来做按钮点击反馈、地图定位点、或者背景装饰。它实现起来不复杂核心是给元素加一个会不断放大的伪元素或子元素配合透明度变化和无限循环动画。keyframes ripple { 0% { transform: scale(1); opacity: 0.6; } 100% { transform: scale(2.5); opacity: 0; } } .ripple { position: relative; width: 100px; height: 100px; border-radius: 50%; background: rgba(24, 144, 255, 0.3); } .ripple::after { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; border: 2px solid rgba(24, 144, 255, 0.6); animation: ripple 1.5s ease-out infinite; }原理不复杂伪元素从原始尺寸开始放大透明度从0.6降到0因为设置了infinite所以会不断循环。如果你想要多个光圈扩散可以再添加一个伪元素的兄弟节点给它设置动画延迟比如animation-delay: 0.75s这样两个光圈就能交错扩散看起来更丰富。这个效果我常用来做地图上的定位点或者直播间的“新消息”提示视觉上很抓人而且不依赖任何JS。注意一点动画元素过多会消耗性能如果页面里有几十个涟漪在同时播放建议控制频次或减少光圈层数。6.4 一键返回顶部的两种实现方式热词里有个“html一键返回顶部算法”这里也顺手一并整理。返回顶部常见的做法有两种纯CSS方式给顶部锚点设置scroll-behavior: smooth然后用a href#top跳转。但这个方式依赖于页面上有ID为top的元素而且锚点跳转会改变URL哈希有些人不太喜欢。更可控的方式是用JavaScriptbutton idbackTop返回顶部/buttonconst backTopBtn document.getElementById(backTop); backTopBtn.addEventListener(click, function () { window.scrollTo({ top: 0, behavior: smooth }); });window.scrollTo配合behavior: smooth就能实现平滑滚动不需要自己写 requestAnimationFrame 动画。如果滚动容器不在 window 上而在某个div上就把window.scrollTo换成对应容器的scrollTo。“算法”本身并不复杂复杂的是判断滚动距离、显示/隐藏按钮的时机以及兼容不同的滚动容器。我的经验是先确认滚动发生在哪个容器上再决定用window还是document.getElementById(container)否则很容易出现“点击没反应”但控制台也不报错的情况。7. 常见问题与排查技巧实录这一节我整理成速查表都是平时被问得最多、也是我自己踩过的坑。现象可能原因排查思路与解决方案样式完全没生效选择器写错、文件路径错误、优先级被覆盖打开浏览器开发者工具查看元素计算的样式看哪个规则被划掉了设了width却还是超宽没有设置 box-sizing: border-box全局重置盒模型子元素设置了margin-top父元素跟着下移margin合并给父元素加 overflow: hidden / padding-top / display: flow-root背景图不显示路径问题、容器没有高度检查相对路径的基准目录确认容器有内容或明确高度删除线、下划线不生效被更具体的样式覆盖检查text-decoration是否被其他规则覆盖注意text-decoration是简写属性input在容器里不居中行内元素用margin:auto无效父容器用 flex justify-content: center align-items: center移动端字太小没有设置 viewport补上meta nameviewport contentwidthdevice-width, initial-scale1.0动画卡顿动画属性触发了重排优先使用 transform 和 opacity避免动画 width、height、top、left字体显示为默认字体font-family写错或字体未加载打开控制台检查字体是否加载检查字体名是否带引号hover在手机上没反应触屏设备没有hover状态使用 :active / :focus 或专门考虑移动端交互7.1 我排查样式问题时的固定流程写CSS写久了遇到样式不生效我基本不慌按顺序排查90%都能解决先看浏览器开发者工具F12里元素的计算样式。这不是上来就改代码而是先搞清楚浏览器到底给你算了什么。如果计算样式里没有你的规则说明选择器没匹配上或者优先级不够如果计算样式里有你的值但页面看起来不对那问题可能出在盒模型、层叠或者继承上。再看选择器的特异性。类选择器和元素选择器的权重差了整整一个量级我之前见过有人用.container div去覆盖.nav-item的样式结果怎么都覆盖不掉原因就是.container div里div是元素选择器权重不够。最后确认被覆盖的规则是从哪来的。浏览器开发者工具的 Styles 面板会按优先级从高到低列出所有匹配的规则看最上面那个就是你当前的胜者。如果有一条来自bootstrap.min.css或某个组件库的规则压着你优先考虑提高自己选择器的权重而不是加!important硬怼。7.2 笔记里那几条必须留给自己的忠告翻到笔记最后几页还有几条我在反复踩坑之后写下的“忠告”这里一起分享出来。第一条写CSS前先明确盒模型。无论从哪开始一个项目第一件事就是把全局重置和box-sizing: border-box写好不然后面所有宽度计算都是麻烦事。第二条不要过度依赖定位。遇到布局问题先想 flex再想 grid最后才用 absolute 和 fixed。绝对定位会让元素脱离文档流用多了页面会变得很难维护。第三条做动效优先用transform和opacity。这两个属性不触发重排reflow和重绘repaint性能开销小。动画top、left、width、height这些属性虽然也能动但性能差得多。第四条命名要可读。类名尽量用语义化的单词比如.card、.nav-link、.btn-primary别用.d1、.d2这种。等过几个月回头看自己的代码时语义化的命名能救命。8. 后续可以怎么扩展这套知识笔记整理到这里HTML和CSS最核心的知识点就过了一遍。如果你顺着这套体系往下学我会建议重点看看这几个方向CSS Grid 布局它和 Flexbox 搭配能解决几乎所有页面布局问题CSS 变量自定义属性在维护大型项目、实现主题切换时非常好用CSS 动画的进阶用法比如使用steps()做逐帧动画、控制贝塞尔曲线让动画更自然还有目前小区并比较常见的 CSS 方案比如 CSS Modules、Tailwind CSS、CSS-in-JS它们解决了样式隔离和复用的问题。如果哪天你把基础吃透了可以尝试脱离框架从零手写一个完整的静态页面比如个人主页、企业官网首页或者一个简单的后台登录页。HTML和CSS就是这样看了再多笔记不如亲手敲一遍印象深。最后再分享一个小技巧学习HTML/CSS时一定要善用浏览器开发者工具。我不夸张地说我后来这几年大部分的CSS问题都是靠这个工具定位的。看到一个效果想弄明白怎么做的就右键检查看它的结构和样式想试一个属性直接在开发者工具里改不用改文件再刷新。这样久而久之你对布局和样式的直觉会越来越准。