前端布局进阶:盒模型、Flexbox、Grid与响应式断点实战笔记 从盒模型、Flexbox 到 Grid再到响应式断点的完整梳理这篇笔记几乎覆盖了前端布局学习路上最容易混淆的几个难点。我会把实际开发中踩过的坑和排查思路一并记下来方便后面复习也希望能帮到正在过这道坎的人。1. 学习笔记的背景这是第 1 阶段第 9 篇实战笔记先解释一下1.9是什么意思。我在整理前端学习笔记时把所有内容按阶段分了编号第 1 阶段是页面结构与样式基础第 8 篇之前分别记录了 HTML 语义化、选择器优先级、CSS 继承、浮动与清除浮动等内容。这篇是第 9 篇所以我给它标号为 1.9。到了这个节点基础的语法已经过完一遍开始进入真正的页面布局实战阶段。这篇文章适合两类人看一类是刚开始学前端、正在被各种布局方案绕晕的新手另一类是已经写了几个月页面、但总感觉Flexbox 和 Grid 每次用都要查文档的初级开发者。在我自己学习的阶段最大的困惑是明明每个 CSS 属性都认识但一放到真实页面上就发现排列效果和自己预期完全不同。后面逐渐意识到问题不在于记没记住属性而在于没有从布局模型的角度去理解浏览器是如何安排元素位置的。这篇笔记会尽量把这个过程拆开讲清楚。这篇笔记的主要内容是盒模型的基本认知以及border-box为什么成了现代开发的默认选择Flexbox 的主轴/交叉轴模型以及实际项目中高频使用到的属性Flexbox 布局里最容易犯的四个错误包括属性混淆、flex 简写歧义和溢出问题CSS Grid 的二维规划方式以及它和 Flexbox 的分工响应式断点的取舍逻辑不要直接抄网上流传的固定数值一个完整的博客首页实战项目把以上知识点汇总到代码里其中很多心得是边写代码边记录下来的不一定在官方文档里看得到但都是实际会发生的事情。2. 从盒模型到 Flexbox学会理解浏览器如何摆元素2.1 盒模型是一切布局的地基我在学习浮动之前曾经以为把元素往左推是靠float或者margin就能解决的事直到第一次做两栏布局才意识到如果不理解盒模型压根不知道元素为什么突然换行、宽度为什么超出容器。标准盒模型里一个元素占据的宽度由四部分组成content内容区、padding内边距、border边框、margin外边距。但问题是如果直接给元素设置width: 50%这个 50% 默认只算内容区不含 padding 和 border。也就是说当你给两个元素各设 50% 宽度再各自加上 10px 内边距它们的实际总宽度会超过父容器无法并排。这个问题在早年的页面开发里折磨了很多人后来大家统一用box-sizing: border-box来解决*, *::before, *::after { box-sizing: border-box; }border-box的含义是设置的宽度已经包含 padding 和 border内容区会自动压缩。这样两个 50% 宽度的元素就算加上 border 和 padding也能正好铺满父容器。我在项目的全局样式里总是第一行写这个重置它可以避免绝大多数宽度计算的噩梦。另外还需要注意一个和直觉相反的现象普通块级元素的margin不会像 padding 那样保留在元素周围而是会发生外边距合并。比如一个父元素没有边框、没有 padding子元素设置margin-top: 30px这个 30px 会被传到父元素外面把整个父元素往下推。新手经常会觉得父元素塌陷了其实是 margin 合并的机制在起作用。这种情况最直接的解决方法是从一开始就避免用 margin 去撑开父子间距改用 padding或者在父元素上加overflow: hidden。2.2 为什么需要 Flexbox浮动布局太脆弱在没有 Flexbox 的时代要做水平排列、垂直居中等操作需要借助 float、table-cell、inline-block 之类的手段每一种都有明显的副作用。比如浮动元素会脱离文档流必须手动清理浮动否则父元素高度塌陷inline-block元素之间存在间隙问题垂直居中长期只能靠 hack 实现。Flexbox 解决了这一类问题。它是一维布局模型也就是说它擅长处理一行或一列内元素的排列问题。你只需要告诉容器用 flex 排列子元素剩下的对齐、伸缩、换行都可以交给 flex 规则去处理。最简单的例子——让一个子元素在父容器里水平和垂直居中.container { display: flex; justify-content: center; align-items: center; }这两行代码是 Flexbox 使用频率最高的组合只要看到居中需求第一时间想到它即可。在实际开发中loading 遮罩、弹窗内容、按钮内部图文的居中基本都是靠这个写法完成的。2.3 主轴与交叉轴先把方向感建立起来Flexbox 最核心的概念是主轴和交叉轴。flex-direction决定哪条是主轴。flex-direction: row默认主轴是水平方向从左到右flex-direction: column主轴是垂直方向从上到下交叉轴始终与主轴垂直主轴决定justify-content的作用方向交叉轴决定align-items的作用方向。很多初学者搞混 justify-content 和 align-items根本原因是脑子里只有水平/垂直的概念没有主轴/交叉轴的概念。我一开始也踩过这个坑在 column 方向下想让元素垂直居中结果写了justify-content: center却发现无效后来才明白此时主轴是垂直的应该用这个属性才能居中。理解主轴和交叉轴之后很多属性会变得非常好记场景属性加载方向水平方向对齐justify-content沿主轴row 模式下垂直方向对齐align-items沿交叉轴row 模式下单个元素覆盖对齐align-self沿交叉轴只作用于单个元素主轴换行flex-wrap: wrap超出容器宽度后换行行间距gap子元素之间的间距不产生 margin 合并2.4 flex 属性的真实含义flex-grow、flex-shrink、flex-basisFlex 布局里最让人困惑的应该是flex: 1到底代表什么。它是一个简写属性完整形式是flex: flex-grow flex-shrink flex-basis。flex-grow剩余空间的分配比例。为 0 时不伸展。flex-shrink空间不足时如何缩小。为 0 时不压缩。flex-basis元素在主轴方向上的初始尺寸优先级高于width。所以flex: 1实际上是flex: 1 1 0%意思是基础尺寸为 0所有空间按比例分配。多个flex: 1的兄弟元素会均分父容器宽度。在导航栏布局中这个用法非常常见。比如一个 header 里有一个左侧 logo 和右侧头像中间区域想要自动撑满就可以让中间部分的flex: 1.header { display: flex; align-items: center; } .header__nav { flex: 1; display: flex; gap: 16px; }假如希望子元素保持固定宽度不拉伸也不压缩写法应该是flex: 0 0 auto。比如按钮旁边的图标、头像、标签这类内容就应该固定否则页面在不同宽度下可能出现图标被压扁的问题。3. Flexbox 的四个高频坑方向搞混、flex 简写和溢出隐患3.1 坑一flex-direction 换成 column 之后justify-content 对齐方向全变了这也是我印象特别深刻的一个问题。有一次写一个移动端页面的底部操作栏想把按钮从上到下排列然后在垂直方向上居中显示。我写了display: flex、justify-content: center按理说应该是水平居中但实际效果却是垂直居中。原因很简单设置了flex-direction: column之后主轴方向变成了垂直于是justify-content也跟着变成了控制垂直方向的对齐。如果想要水平居中此时反而应该用align-items: center因为水平变成了交叉轴方向。这个问题的解决思路在于每次写 flex 相关的对齐代码先问自己现在主轴是哪个方向再决定写 justify-content 还是 align-items。不要靠死记也不要靠试。3.2 坑二flex: 1 并不是等分等分要弄清基础宽度前面说过flex: 1 1 0%才会真正均分。但如果你写的是flex: 1是等分如果是flex: 1 1 50%那就不一样了两个元素会各自以 50% 为基础宽度再去分配剩余空间同时还需要压缩情况会变得复杂。更隐蔽的问题出现在多个 flex 元素内容长度不同的时候。比如两个按钮并排一个文字长一个文字短你给它们都设了flex: 1理论上应该等宽。但如果文字太长默认的min-width会阻止元素被压缩到内容宽度以下导致等分失败。这种情况需要给子元素设置min-width: 0让它允许被压缩或者在父容器上设置合适的overflow行为。实际项目中侧边栏 弹性主区域的布局经常遇到这个问题我最后都是通过min-width: 0解决的。3.3 坑三子元素默认不换行内容溢出比想象中容易Flex 容器里的子元素默认是单行排列的flex-wrap默认值是nowrap。这意味着即使子元素宽度总和超过了容器宽度它们也不会换行而会尽量压缩压缩不了就直接溢出。遇到过的一个实际案例是要做一组标签云每个标签是圆角背景的 span 元素里面字数不等。我把外层容器设成了display: flex; gap: 8px但忘了加flex-wrap: wrap结果标签在窄屏上全部挤成一团还溢出到了容器外面。解决办法很简单给容器加上.tags { display: flex; flex-wrap: wrap; gap: 8px; }但这件事提醒我不能只记属性写法要理解 Flexbox 默认行为是什么。Flex 容器的核心设计目标是尽量在一行内合理安排子元素而不是自动换行保持整洁。换行是需要明确表达的意图。3.4 坑四Flex 容器里的 margin: auto 很有意思但容易误用margin: auto在 Flexbox 里有一层额外的能力它可以吸收剩余空间。比如一个导航栏里有一个 logo 和一组按钮你想让按钮靠右对齐但不想写 justify-content: space-between可以考虑给中间的 spacer 元素设flex: 1或者给按钮组设margin-left: auto。但是 margin: auto 在主轴和交叉轴上有不同的表现有时候会同时影响两个方向。比如在容器里想让一个元素水平居中、垂直方向靠底用margin-top: auto比align-items更方便。这个技巧在弹窗 footer 中非常常见但新手容易写完后发现某一边的出现预期之外的对齐效果。建议的使用方式是明确知道auto 会抢占该方向上的剩余空间时再使用否则还是用 justify-content 和 align-items 更直观。3.5 还应该知道的Flexbox 里的 gap、align-self 和 flex-wrap 组合现代浏览器已经普遍支持 Flexbox 中的gap属性这是以前只能靠 margin 或 padding 实现间距的时代无法想象的便利。它直接设置在容器上子元素间自动产生间距而且不会产生 margin 合并的问题。align-self则允许单个子元素覆盖容器设置的交叉轴对齐方式。例如容器默认align-items: center但其中一个元素想要从顶部对齐就给它单独设置align-self: flex-start。这在列表中特别有用比如头像和文字描述需要顶部对齐而其余所有子元素默认垂直居中。如果配合 flex-wrap还有align-content需要留意它控制的是多行之间的对齐方式而不是单行。只有当内容换行成两行或更多时它才生效。我很少用这个属性因为大多数情况下设置每行自身的高度就够了但理解了就避免了一头雾水的情况。4. CSS Grid从排队的列表升级到画格子的棋盘4.1 为什么不能只用 Flexbox 解决所有问题如果只处理一行内的排列Flexbox 足够好。但页面布局往往不止一行一列还有这样的需求一个区域分为左侧 250px、右侧自适应右侧内部再分为上下两层。用 Flexbox 可以用嵌套的方式实现但代码会变得别扭且难维护。Grid 的核心定位是二维布局。它把容器看成由行和列组成的网格你可以指定每个子元素从哪条网格线开始、到哪条网格线结束。这种表达能力是 Flexbox 难以做到的。在实际开发中我把二者的分工基本定义为页面骨架用 Grid组件内部用 Flexbox。页面的整体结构比如侧边栏、主内容区、底部栏用的是 Grid而卡片内部的内容排列比如图标和标题一行、按钮组一行用的是 Flexbox。4.2 核心语法grid-template-columns 和 grid-template-rowsGrid 的基础操作是在容器上定义有哪些列、哪些行。最常用的写法如下.page { display: grid; grid-template-columns: 250px 1fr; grid-template-rows: auto 1fr auto; min-height: 100vh; }这里的1fr是 Grid 特有的单位表示剩余空间的一份。250px 1fr意思是第一列固定 250px第二列吃掉剩余空间。grid-template-rows: auto 1fr auto则是经典的三行布局头部自适应高度、中间占满剩余空间、底部自适应高度再配上min-height: 100vh就是一个典型的 sticky footer 骨架。如果列数很多可以用repeat()简写.grid-12 { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; }这样就有了一个 12 列网格系统后续只需要给子元素指定grid-column: span 4之类的属性就能实现类似栅格系统的布局。4.3 区域命名grid-template-areas 让布局语义更清晰Grid 的grid-template-areas是我最喜欢的功能之一因为它把 CSS 布局像画图一样描述出来。比如一个常见页面结构.layout { display: grid; grid-template-columns: 200px 1fr; grid-template-areas: sidebar main; height: 100vh; } .sidebar { grid-area: sidebar; } .main { grid-area: main; }这种写法的好处是HTML 元素的实际顺序不重要重要的是通过grid-area把元素放到指定位置。调试布局时只要看grid-template-areas就能脑补出页面长什么样。对新手极其友好完全不需要手动计算网格线编号。4.4 自动填充repeat(auto-fill, minmax(...)) 是最实用的响应式 Grid 写法要做一个自适应的卡片网格最理想的 CSS 写法是.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; }这句代码的意思是每一列最小 280px最大等分剩余宽度容器的宽度能容纳多少列就自动建多少列。不需要媒体查询不需要 JS 计算纯 CSS 就完成了窗口变宽列数变多窗口变窄列数变少的效果。我第一次看到这个写法时有点惊讶于它的简洁但实际用到项目里之后就离不开了。现在做后台管理系统卡片列表、作品集网格、文章列表我都直接用这一行作为默认卡片布局。4.5 Grid 和 Flexbox 的混用是协作不是互斥很多人会纠结到底用 Grid 还是 Flexbox这个问题其实没有非此即彼的答案。关键是理解各自的优势区间。布局骨架行 列结构Grid一行内的排列导航、按钮组、操作栏Flexbox有明确行列关系的网格Grid不确定数量但需要排列的列表项Grid 的 auto-fill 更好单个组件内部的对齐、间距Flexbox在实际项目中二者的嵌套非常普遍。外层 Grid 划分区域每个区域内部再使用 Flexbox 处理细节。这样分工的好处是每一层只解决一种维度的问题代码意图清晰也不会出现为了达到一个效果而写一堆 hack的情况。5. 响应式布局的断点策略别只会抄 768px 和 1024px5.1 断点应按内容走而不是按设备走很多地方会把响应式断点总结成手机 375px、平板 768px、电脑 1024px但这种按设备宽度的思路不完全合理。实际页面的内容变化往往是布局从单列变成双列、从双列变成四列的转折点这个转折点取决于卡片宽度、文字可读性、行宽等因素而不是设备型号。我在自己做项目时会先把页面在浏览器里慢慢拉宽观察到内容变得很难看的位置再在那里设置断点。通常的判断依据是卡片宽度低于某个值后里面的文字开始折行过多、视觉效果变差侧边栏在某个宽度下变得太窄无法容纳导航文字一行文字的阅读宽度超过 80 字符左右读起来会很累这些断点需要通过实际体验来定而不是照抄别人的数值。当然为了方便记忆我会把断点设为统一标准比如 640px、960px、1200px但这些数值背后代表的是在这个宽度以下需要切换布局而不是这个宽度对应某台手机。5.2 移动优先还是桌面优先我的选择响应式 CSS 的两种常见写法是桌面优先默认按桌面宽度写然后用max-width媒体查询去适配小屏移动优先默认按手机宽度写然后用min-width媒体查询去增强到大屏我实际开发中更喜欢移动优先。原因是从最基础的窄屏写起样式往往最简单没有太多列和布局更不容易出错而用max-width写桌面优先时大屏样式复杂一旦改到小屏需要覆盖的规则很多容易漏掉。移动优先的代码结构大约是.posts-grid { display: grid; grid-template-columns: 1fr; gap: 16px; } media (min-width: 640px) { .posts-grid { grid-template-columns: repeat(2, 1fr); } } media (min-width: 960px) { .posts-grid { grid-template-columns: repeat(3, 1fr); } }基本思路是先保证小屏下能正常阅读再在小屏基础上不断增强列数和间距。5.3 让单位更灵活clamp()、视口单位和百分比响应式布局不一定全靠媒体查询。字号、间距、边距这类设计属性适合用更灵活的单位来表达。clamp()是个很好用的函数它的作用是给一个属性设置最小、推荐、最大三个值浏览器根据当前视口宽度自动调整。比如.title { font-size: clamp(1.5rem, 3vw 1rem, 2.5rem); }意思是标题字号最小 1.5rem最大 2.5rem在中间时可以随视口宽度变化。这样在大屏上标题更大在小屏上标题不过度膨胀不需要为字号单独写媒体查询。视口单位vw、vh也很有用但要小心100vh在某些移动浏览器上会因为地址栏的显示/隐藏而跳动造成底部内容被遮挡。我现在多用100dvh动态视口高度或min-height: 100vh加安全区域的组合而不是直接写死高度。5.4 容器居中与最大宽度的约定页面整体宽度通常是受限的比如内容区最多 1200px然后水平居中。我最常用的写法是.container { width: 100%; max-width: 1200px; margin-inline: auto; padding-inline: 20px; }margin-inline: auto是逻辑属性表示水平方向 auto 居中效果等同margin: 0 auto但语义更清晰。padding-inline可以保证内容不会贴着屏幕边缘。这样设置之后无论什么屏幕宽度整个容器都能居中内容两侧始终保留 20px 间距。6. 实战纯 CSS 搭建一个响应式博客首页6.1 页面结构与设计思路把前面这些知识点串起来我这次搭建的页面是一个博客首页包含三个核心部分顶部导航栏左侧 logo右侧导航链接主内容区一个 hero 区介绍语和文章卡片网格底部栏简单的版权信息设计思路是页面骨架用 Grid 来布局文章卡片用 Grid 的 auto-fill 实现自适应列数导航栏内部用 Flexbox 排列hero 区内部用 Flexbox 做文字和图文的垂直居中卡片内部用 Flexbox 排列标题摘要和按钮。6.2 HTML 结构!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title博客首页布局实战/title link relstylesheet hrefstyle.css /head body header classsite-header div classcontainer header-inner a href# classlogoMyBlog/a nav classnav a href#首页/a a href#归档/a a href#关于/a /nav /div /header main classsite-main section classhero div classcontainer hero-inner h1记录前端学习的过程/h1 p从基础语法到页面实战每次踩坑都是成长。/p /div /section section classposts-section div classcontainer h2 classsection-title最新文章/h2 div classposts-grid article classpost-card h3Flexbox 排坑笔记/h3 p主轴、交叉轴、flex 简写一次讲清楚。/p a href# classread-more阅读全文/a /article article classpost-card h3Grid 布局初体验/h3 p用网格重新理解页面骨架。/p a href# classread-more阅读全文/a /article article classpost-card h3响应式断点怎么选/h3 p别套固定数值按实际内容体验来定。/p a href# classread-more阅读全文/a /article /div /div /section /main footer classsite-footer div classcontainer p© 2025 MyBlog/p /div /footer /body /html6.3 CSS 核心代码拆解首先是全局重置与基础样式*, *::before, *::after { box-sizing: border-box; } body { margin: 0; font-family: system-ui, -apple-system, Segoe UI, sans-serif; color: #222; line-height: 1.6; } a { text-decoration: none; color: inherit; } .container { width: 100%; max-width: 1200px; margin-inline: auto; padding-inline: 20px; }页面骨架的 Grid 布局body { display: grid; grid-template-rows: auto 1fr auto; min-height: 100vh; }这样 header 和 footer 高度自适应main 占据中间剩余空间。不依赖 flex 的 sticky footer hackGrid 的实现更直接。导航栏用 Flexbox.site-header { border-bottom: 1px solid #ddd; background: #fff; } .header-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; } .nav { display: flex; gap: 20px; } .logo { font-weight: 700; font-size: 1.25rem; }hero 区使用 Flexbox 做居中.hero { padding: 80px 0; text-align: center; } .hero-inner { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 640px; } .hero h1 { font-size: clamp(1.8rem, 4vw 1rem, 3.2rem); margin: 0; }文章卡片的响应式 Grid.posts-section { padding: 40px 0; } .posts-grid { display: grid; grid-template-columns: 1fr; gap: 20px; } media (min-width: 640px) { .posts-grid { grid-template-columns: repeat(2, 1fr); } } media (min-width: 960px) { .posts-grid { grid-template-columns: repeat(3, 1fr); } } .post-card { border: 1px solid #eee; border-radius: 12px; padding: 24px; display: flex; flex-direction: column; gap: 8px; } .post-card h3 { margin: 0; font-size: 1.25rem; } .read-more { margin-top: auto; color: #2563eb; font-weight: 500; }这里为了说明 clearfix 之外的现代布局footer 部分不复杂.site-footer { border-top: 1px solid #ddd; padding: 20px 0; text-align: center; color: #888; font-size: 0.875rem; }6.4 几个值得展开的设计决策第一个是 post-card 为什么用 flex-direction: column 而不是直接写块级元素。原因是卡片内有三部分标题、摘要、阅读全文按钮我希望按住按钮始终靠底来对齐不管摘要文字有多长。margin-top: auto让按钮占掉所有剩余空间所以所有卡片的按钮都在同一水平线上。这个细节在纯 block 布局里很难实现。第二个是 posts-grid 为什么不用repeat(auto-fill, minmax(280px, 1fr))而是写了三个媒体查询。实际上两者效果非常接近但我在实战中发现自动填充虽然省了媒体查询但有时会让列数变化过于频繁比如在窗口宽度刚好卡在某个临界点时列数会在 2 和 3 之间跳变。如果你希望博客的阅读密度稳定用固定的断点切换更可控。卡片列表类的内容我偏向于自动填充博客首页这类强调阅读节奏的内容则更偏向手动断点。第三个是全球重置里对 body 设置display: grid与 header、main、footer 直接作为 Grid 子元素。这样写完全避免了为 header 和 footer 设置固定高度的问题内容撑开多少Grid 行就多高main 永远填满中间。6.5 这段实战还能怎么扩展到这里页面已经是一个可以正常浏览的响应式博客首页了。后续如果要继续扩展有几个方向给文章卡片加上图片位Grid 的 auto-flow 和图片的 aspect-ratio 需要一起调试加入暗色模式用prefers-color-scheme调整变量把 hero 区改成真实排版比例适配更宽的屏幕把断点逻辑抽象为变量方便全站统一管理这些都属于下一个阶段的笔记内容会放在后面继续记录。7. 学习方法和排错过程的个人记录7.1 学习布局时最高效的路径我自己走下来的路径是先死磕盒模型把 border-box 和 margin 合并弄明白再学 Flexbox集中在主轴、交叉轴、flex 简写这三个概念上最后再看 Grid重点用 grid-template-areas 和 auto-fill 两个特性。如果一开始就同时学好几种布局方式反而容易混乱。另外我强烈建议写代码时不要复制粘贴网上代码而是把每个属性去掉之后“破坏性测试”一遍。比如把align-items: center删掉看效果、把flex: 1改成flex: 0 0 auto看效果很快就能建立直观感受比看十篇教程都有效。7.2 一个典型 bug 的完整排查过程我在调试前文那个博客首页时发现了一个问题导航栏的 logo 和 nav 之间有莫名其妙的空隙无论如何调整 gap 和 margin 都去不掉。排查链路是先用浏览器开发工具检查 nav 元素的盒模型确认没有 margin 和 padding再检查 header-inner 是否有justify-content: space-between发现它会把 logo 和 nav 各推到两端空隙来自剩余空间均分并不是真的边距检查父容器是否为 flex确认 header-inner 确实有display: flex问题最终落点是justify-content: space-between在只有两个子元素时会让两个元素之间的间距等于剩余空间而不是固定的 20px。如果想要固定间距应该去掉 space-between改用一个 spacer 元素并设置flex: 1或margin-left: auto。这个排查过程让我意识到在 Flex 容器里分析间隙问题时不能只看子元素的 margin还要看对齐方式对剩余空间的分配方式。很多时候界面多出来的空隙并不是哪个元素设了间距而是对齐属性在起作用。7.3 印象最深的几个经验总结记录到这里我想把几个反复踩过的教训浓缩一下写 Flexbox 先想主轴方向再写 justify-content 还是 align-items不要靠猜flex 简写比想象中容易踩坑明确用flex: 1 1 0%或flex: 0 0 auto语义更清楚子元素内容过长时默认min-width: auto会导致等分失败需要 min-width: 0Grid 的 auto-fill 配 minmax 是个万能卡片布局但要留意列数跳变的问题断点基于内容体验来定不要盲目套用网上数值排查布局问题用开发工具看盒模型比对实际渲染值和预期值比改代码试错快得多这些经验放在笔记里等再过一段时间回看应该还能帮我快速定位问题。前端布局的东西就是这样知识点不难难的是把它们组合起来并且知道出现异常时该从哪里下手检查。