摘要上一篇我们打好了CSS基础本篇将直击核心——布局。从最传统的浮动、定位开始带你搞懂元素怎么“放”在页面上再深入CSS3两大革命性布局模块弹性盒子Flexbox与网格Grid。我们不仅学理论更会用大量实战案例让你从居中一个按钮都不会变成可以轻松驾驭各种复杂页面结构。一、回顾与热身文档流与display属性在开始布局前我们必须先认识正常文档流。浏览器默认按照HTML书写顺序从上到下、从左到右排列元素。元素分为两大类块级元素block如div,p,h1~h6,ul,li等。它们独占一行可以设置宽高、内外边距默认宽度撑满父容器。行内元素inline如span,a,strong,em等。它们不换行多个行内元素会排在同一行直到空间不够才折行。宽高设置无效内外边距只在水平方向生效。还有一种常用的混合模式行内块元素inline-block。通过display: inline-block可以让一个元素既具备块级元素的可设置宽高、内外边距特性又像行内元素一样与其他元素并排。但它会带来一个小麻烦——元素间空白间隙。这是因为HTML中标签之间的换行符被解析成了空格。解决办法给父元素设置font-size: 0再在子元素上恢复字号或者把标签紧贴写成一行不推荐影响可读性。更好的方法是使用Flex或Grid后面会讲。.block { display: block; width: 200px; } .inline { display: inline; /* 宽高无效 */ } .inline-block { display: inline-block; width: 200px; height: 80px; }另外需要区分隐藏元素的两种方式display: none元素完全从文档流中消失不占空间仿佛不存在。visibility: hidden元素不可见但仍占据原来的空间。.hidden-none { display: none; } .hidden-visibility { visibility: hidden; }热身结束进入真正的布局。二、浮动布局float——经典但仍有价值浮动最初的设计目的是实现文字环绕图片的效果就像报纸排版。后来被广泛用于多栏布局在Flex和Grid出现之前它是创建多列布局的核心手段。1. 浮动的基本特性给元素设置float: left或float: right后会发生元素脱离正常文档流向左或向右移动直到碰到父容器边界或另一个浮动元素。其后的块级元素会占据它原来的位置相当于它不存在但行内元素如文字会环绕它。浮动的元素仍然保留自己的宽高和内外边距。示例图文混排!DOCTYPE html html langzh-CN head meta charsetUTF-8 title浮动演示/title !-- 所有CSS必须写在这里面 -- style .float-left { float: left; margin-right: 15px; width: 200px; /* 加个边框方便你确认样式是否生效 */ border: 2px solid #3498db; } /* 解决浮动父元素高度塌陷问题必加 */ .float-demo { overflow: auto; padding: 20px; background: #f8f9fa; border-radius: 8px; max-width: 600px; margin: 50px auto; } /style /head body div classfloat-demo img srcpic.jpg classfloat-left alt示例图片 p这是一段很长的文字会环绕在图片周围。浮动最初就是用来干这个的。这是一段很长的文字会环绕在图片周围。浮动最初就是用来干这个的。这是一段很长的文字会环绕在图片周围。浮动最初就是用来干这个的。/p /div /body /html2. 浮动引发的“高度坍塌”与清除浮动浮动元素脱离文档流导致父元素无法感知其高度父容器会坍塌成一条线如果内部全是浮动元素。这会让后续元素跑上来布局错乱。因此清除浮动就成了必备技巧。方法一空标签法在浮动元素后面添加一个空元素如div styleclear:both;/div但会添加无意义的标签。方法二伪元素清除最佳实践给父元素添加.clearfix类通过CSS生成伪元素来清除。.clearfix::after { content: ; display: table; /* 防止外边距合并同时让元素成为块级 */ clear: both; }使用时给包含浮动元素的父容器添加classclearfix即可。方法三触发BFC给父容器设置overflow: hidden或overflow: auto也能让它包裹浮动元素。缺点是有可能裁剪内容。现代布局中不建议主依赖此方法。3. 经典浮动布局两栏、三栏在没有Flex的年代圣杯布局和双飞翼布局都是靠浮动加负边距实现的理解起来非常痛苦。现在简单展示一个固定宽度侧边栏 自适应主内容区的两栏浮动写法!DOCTYPE html html langzh-CN head meta charsetUTF-8 titlefloat两栏布局/title style /* 全局重置 */ * { box-sizing: border-box; margin: 0; padding: 0; } /* 必须定义的clearfix清除浮动类 */ .clearfix::after { content: ; display: block; clear: both; } /* 父容器样式 */ .layout { width: 100%; max-width: 1200px; margin: 50px auto; background: #f8f9fa; border-radius: 8px; overflow: hidden; /* 备用清除浮动方法 */ } /* 侧边栏 */ .sidebar { float: left; width: 240px; background: #e9ecef; padding: 30px 20px; min-height: 400px; /* 给个最小高度方便看效果 */ font-size: 18px; color: #495057; } /* 主内容区 */ .content { margin-left: 260px; /* 240px宽度 20px间隙 */ background: #ffffff; padding: 30px 20px; min-height: 400px; font-size: 18px; color: #212529; } /style /head body div classlayout clearfix aside classsidebar侧边栏 固定宽度240px/aside main classcontent主内容区 自适应/main /div /body /html三栏结构只需再加一个右浮动但顺序和margin要仔细计算相当繁琐。现在除了极少数老旧项目维护浮动几乎已被Flex和Grid取代。我们学习它是为了看懂历史代码和理解定位上下文。三、定位position——精准控制元素位置定位让你可以把元素放在任意位置上甚至叠在一起。它功能强大但需要清晰理解几种定位模式。1. 五种定位模式static默认值正常文档流top/right/bottom/left无效。relative相对定位。元素相对于自身原本位置偏移依然占据原来的空间不影响其他元素。通常给子元素当定位参照。absolute绝对定位。元素脱离文档流不占空间。位置相对于最近的已定位祖先元素position非static的父级进行定位。如果没找到则相对于浏览器视口。fixed固定定位。脱离文档流相对于浏览器窗口定位滚动页面也不动。常用来做固定导航栏或返回顶部按钮。stickyCSS3粘性定位。它是relative和fixed的结合体。在滚动到指定阈值前表现为relative之后表现为fixed。兼容性已很好常用来做滚动吸附的头部。2. 相对定位与绝对定位的经典组合父元素设置position: relative子元素设置position: absolute然后通过 top/right 等定位就可以把子元素精确放到父容器的任意角落。例如制作卡片右上角的角标!DOCTYPE html html langzh-CN head meta charsetUTF-8 title商品角标演示/title style /* 全局重置 */ * { box-sizing: border-box; margin: 0; padding: 0; } body { padding: 50px; background: #f5f5f5; } /* 商品卡片容器 */ .card { position: relative; /* 绝对定位的基准必须有 */ width: 200px; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px; background: white; box-shadow: 0 2px 8px rgba(0,0,0,0.06); /* ❌ 绝对不要加 overflow: hidden否则角标会被裁剪 */ } /* HOT角标 */ .badge { position: absolute; top: -8px; right: -8px; background: #ff4d4f; color: white; padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: bold; line-height: 1.5; box-shadow: 0 2px 4px rgba(255,77,79,0.3); z-index: 10; /* 确保角标在最上层 */ } /style /head body div classcard span classbadgeHOT/span 商品内容... /div /body /html3. z-index 控制层级定位元素会发生堆叠后出现的默认覆盖前面的。可以用z-index数值越大越靠上来手动控制层级。注意z-index 只对已定位元素position非static有效。4. 实战纯CSS下拉菜单利用:hover和绝对定位可以不写一行JS做出下拉菜单。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title下拉导航菜单/title style /* 全局重置 */ * { box-sizing: border-box; margin: 0; padding: 0; } body { padding: 50px; background: #f5f5f5; font-family: Microsoft YaHei, sans-serif; } /* 导航容器 */ .nav { list-style: none; background: #333; padding: 0 20px; border-radius: 8px; font-size: 0; /* 消除inline-block间隙必加 */ } /* 导航项 */ .nav li { display: inline-block; position: relative; /* 下拉菜单的定位基准必加 */ font-size: 16px; /* 恢复文字大小 */ } /* 导航链接 */ .nav li a { display: block; padding: 15px 20px; color: white; text-decoration: none; transition: background 0.3s; } .nav li a:hover { background: #555; } /* 下拉菜单 */ .dropdown-menu { display: none; position: absolute; top: 100%; left: 0; background: white; box-shadow: 0 2px 10px rgba(0,0,0,0.2); list-style: none; padding: 0; min-width: 120px; border-radius: 0 0 8px 8px; z-index: 9999; /* 确保在最上层必加 */ } /* 下拉菜单项 */ .dropdown-menu li { display: block; } /* 下拉菜单链接 */ .dropdown-menu li a { color: #333; padding: 12px 20px; } .dropdown-menu li a:hover { background: #f0f0f0; } /* 悬停显示下拉菜单必加 */ .dropdown:hover .dropdown-menu { display: block; } /style /head body ul classnav li classdropdown a href#产品/a ul classdropdown-menu lia href#电脑/a/li lia href#手机/a/li lia href#配件/a/li /ul /li lia href#关于我们/a/li lia href#联系我们/a/li /ul /body /html定位学完你已经可以控制元素放在任何像素位置。但是如果想把很多元素排列成行、列、等分空间靠浮动和定位还是力不从心。接下来现代布局利器登场。四、Flexbox弹性布局——一维布局的王者CSS3弹性盒子Flexbox专为一维布局设计要么处理行要么处理列。它能轻松实现对齐、等分、自动换行、内容排序彻底解决了垂直居中这一历史难题。1. Flex容器与项目给父元素设置display: flex它就变成了Flex容器其直接子元素自动成为Flex项目。项目会沿着主轴默认水平方向排列不再独占一行即使原来是块级元素。.container { display: flex; }2. 容器属性父元素设置① flex-direction主轴方向row(默认)左→右row-reverse右→左column上→下column-reverse下→上② flex-wrap是否换行nowrap(默认)不换行项目可能被压缩wrap换行第一行在上方wrap-reverse换行第一行在下方③ justify-content主轴对齐方式非常重要flex-start左对齐默认flex-end右对齐center居中space-between两端对齐项目之间间隔相等space-around每个项目两侧间隔相等项目间间隔是边缘两倍space-evenly项目与容器边缘、项目之间的间隔完全相等④ align-items交叉轴垂直于主轴对齐方式stretch(默认)若项目未设高度或为auto拉伸填满容器高度flex-start顶部对齐flex-end底部对齐center垂直居中baseline文字基线对齐⑤ align-content多根轴线多行时的对齐方式属性值与justify-content类似当flex-wrap为wrap且有多行时生效。3. 项目属性子元素设置① flex一个复合属性包括flex-grow、flex-shrink、flex-basis默认0 1 auto。flex-grow放大比例默认0即使有剩余空间也不放大。若所有项目都设为1则等分剩余空间。flex-shrink缩小比例默认1空间不足时等比例缩小。flex-basis项目初始大小相当于设置了宽度或高度会覆盖width。常用写法.item { flex: 1; } /* 等分 */ .item2 { flex: 2; } /* 占两份其余各占一份 */ .item-fixed { flex: 0 0 200px; } /* 固定200px不放大不缩小 */② align-self允许单个项目有与其他项目不同的交叉轴对齐方式覆盖align-items。③ order项目排列顺序数值越小越靠前默认0。可以将某个项目提前或移后而不改变HTML结构。4. 实战Flex经典应用场景一水平垂直居中终于不用再绞尽脑汁!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title水平垂直居中/title style html, body { margin: 0; padding: 0; height: 100%; width: 100%; } body { display: flex; justify-content: center; align-items: center; background: #f5f5f5; font-family: Microsoft YaHei, sans-serif; } .box { width: 300px; height: 200px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); display: flex; justify-content: center; align-items: center; font-size: 20px; color: #333; } /style /head body div classbox我已经完美居中了/div /body /html你的子元素无论几个就完美居中了。场景二导航栏!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleFlex导航栏/title style /* 全局基础重置必加避免浏览器默认样式干扰 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Microsoft YaHei, sans-serif; line-height: 1.5; } /* 导航栏容器 - 你的核心代码 */ .nav { display: flex; justify-content: space-between; /* 左右两端对齐 */ align-items: center; /* 垂直居中 */ background: #333; padding: 10px 30px; } /* Logo样式 */ .logo { color: white; font-size: 24px; font-weight: bold; } /* 菜单容器 - 使用flex gap实现间距 */ .menu { display: flex; gap: 20px; /* 菜单项之间的间距现代浏览器完美支持 */ list-style: none; /* 去掉列表默认圆点 */ } /* 菜单链接样式 */ .menu a { color: white; text-decoration: none; /* 去掉下划线 */ padding: 8px 12px; border-radius: 4px; transition: background-color 0.3s ease; /* 添加平滑过渡效果 */ } /* 链接悬停效果 */ .menu a:hover { background-color: #555; } /* 激活状态样式当前页面 */ .menu a.active { background-color: #4CAF50; } /style /head body !-- 导航栏HTML结构 -- nav classnav div classlogo我的网站/div ul classmenu lia href# classactive首页/a/li lia href#产品/a/li lia href#服务/a/li lia href#关于我们/a/li lia href#联系我们/a/li /ul /nav !-- 页面其他内容 -- div stylepadding: 20px; max-width: 1200px; margin: 0 auto; h1欢迎来到我的网站/h1 p这是一个使用Flex布局实现的导航栏结构清晰易于维护。/p /div /body /html场景三等分布局自动换行!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleFlex图片画廊/title style /* 全局基础重置必加避免浏览器默认样式干扰 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 20px; font-family: Microsoft YaHei, sans-serif; background: #f5f5f5; } h1 { text-align: center; margin-bottom: 30px; color: #333; } /* 你的核心代码 - 画廊容器 */ .gallery { display: flex; flex-wrap: wrap; /* 允许自动换行 */ gap: 15px; /* 图片之间的间距水平垂直 */ max-width: 1200px; margin: 0 auto; } /* 你的核心代码 - 画廊项目 */ .gallery .item { flex: 1 1 200px; /* 关键基础宽度200px可放大可缩小 */ min-height: 150px; /* 给个最小高度避免空元素塌陷 */ } /* 图片自适应样式 */ .gallery .item img { width: 100%; height: 100%; object-fit: cover; /* 保持图片比例裁剪多余部分 */ border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: transform 0.3s ease; } /* 图片悬停效果 */ .gallery .item img:hover { transform: scale(1.05); box-shadow: 0 4px 16px rgba(0,0,0,0.15); } /style /head body h1图片画廊/h1 div classgallery div classitemimg srchttps://picsum.photos/400/300?random1 alt图片1/div div classitemimg srchttps://picsum.photos/400/300?random2 alt图片2/div div classitemimg srchttps://picsum.photos/400/300?random3 alt图片3/div div classitemimg srchttps://picsum.photos/400/300?random4 alt图片4/div div classitemimg srchttps://picsum.photos/400/300?random5 alt图片5/div div classitemimg srchttps://picsum.photos/400/300?random6 alt图片6/div div classitemimg srchttps://picsum.photos/400/300?random7 alt图片7/div div classitemimg srchttps://picsum.photos/400/300?random8 alt图片8/div div classitemimg srchttps://picsum.photos/400/300?random9 alt图片9/div div classitemimg srchttps://picsum.photos/400/300?random10 alt图片10/div /div /body /html这样一行能放几个就放几个自动换行且等分空间。场景四圣杯布局头尾全宽、中间三栏!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleFlex圣杯布局/title style /* 全局重置必加 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Microsoft YaHei, sans-serif; font-size: 16px; color: #333; } /* 圣杯布局容器 */ .holy-grail { display: flex; flex-direction: column; min-height: 100vh; /* 占满整个视口高度 */ } /* 头部和底部 */ header, footer { background: #e9ecef; padding: 20px; text-align: center; font-size: 18px; font-weight: bold; } /* 中间主体区域 */ .main { display: flex; flex: 1; /* 占满剩余高度 */ } /* 左侧导航栏 */ nav { flex: 0 0 200px; /* 固定宽度200px不放大不缩小 */ background: #f8f9fa; padding: 20px; border-right: 1px solid #dee2e6; } /* 中间内容区 */ article { flex: 1; /* 自动占满剩余宽度 */ background: #ffffff; padding: 20px; } /* 右侧边栏 */ aside { flex: 0 0 200px; /* 固定宽度200px不放大不缩小 */ background: #f8f9fa; padding: 20px; border-left: 1px solid #dee2e6; } /style /head body div classholy-grail headerHeader/header div classmain navNav 200px/nav articleContent 自适应/article asideAside 200px/aside /div footerFooter/footer /div /body /htmlFlex在一维排列上已经近乎完美但当我们需要同时控制行和列的时候比如完整的页面栅格系统就需要Grid登场了。五、CSS Grid网格布局——终极二维布局Grid将容器划分为行和列可以像表格一样精确放置元素却完全不依赖HTML结构还能自动响应。它是目前最强大的CSS布局方案。1. 定义网格容器.container { display: grid; }2. 定义行与列通过grid-template-columns和grid-template-rows定义轨道。.grid { display: grid; grid-template-columns: 200px 1fr 200px; /* 三列左右固定中间自适应 */ grid-template-rows: 100px auto 80px; /* 三行上下固定中间自适应 */ gap: 10px; /* 行列间距也可分别设置row-gap, column-gap */ }单位 frfraction的缩写表示可用空间的一份。1fr 2fr 1fr表示中间列占一半。fr会自动减去固定尺寸和gap后分配。函数 repeat()grid-template-columns: repeat(3, 1fr);等同于1fr 1fr 1fr。 配合auto-fill和minmax()可实现无需媒体查询的响应式栅格.grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }这表示自动填充尽可能多的列每列最小250px最大1fr。当容器宽度放不下250px时元素就会换行。3. 放置项目默认项目会按照网格顺序自动放置。你也可以手动指定grid-column-start/grid-column-end项目占据哪几列简写grid-column: 1 / 3;表示从第1条列线到第3条占两列。grid-row-start/grid-row-end同理。还可以命名网格区域极大提高可读性.layout { display: grid; grid-template-columns: 200px 1fr; grid-template-rows: 80px 1fr 60px; grid-template-areas: header header sidebar main footer footer; gap: 15px; } .header { grid-area: header; } .sidebar { grid-area: sidebar; } .main { grid-area: main; } .footer { grid-area: footer; }这样布局完全视觉化了。4. 对齐方式容器提供了和Flex极其类似的对齐属性但分为行和列justify-items单元格内项目的水平对齐start/end/center/stretchalign-items单元格内项目的垂直对齐place-items: center;水平垂直居中对于整个网格内容在容器中的对齐当网格总尺寸小于容器时使用justify-content和align-content。子项目也有justify-self和align-self。5. Grid实战响应式卡片列表!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleGrid响应式卡片网格/title style /* 全局基础重置必加避免浏览器默认样式干扰 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #f5f7fa; font-family: Microsoft YaHei, sans-serif; line-height: 1.6; color: #333; } /* 你的核心代码 - 卡片网格容器 */ .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 24px; padding: 40px 20px; max-width: 1200px; margin: 0 auto; } /* 你的核心代码 - 卡片样式 */ .card { background: white; border-radius: 12px; padding: 24px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); transition: all 0.3s ease; } /* 添加卡片悬停效果 */ .card:hover { transform: translateY(-5px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); } .card h3 { margin-bottom: 12px; color: #1a1a1a; font-size: 20px; } .card p { color: #666; font-size: 14px; } /style /head body div classcard-grid div classcard h3卡片1/h3 p这是卡片的描述内容展示Grid布局的效果。/p /div div classcard h3卡片2/h3 p这是卡片的描述内容展示Grid布局的效果。/p /div div classcard h3卡片3/h3 p这是卡片的描述内容展示Grid布局的效果。/p /div div classcard h3卡片4/h3 p这是卡片的描述内容展示Grid布局的效果。/p /div /div /body /html不需要任何媒体查询不同屏幕下自动适配列数。6. Grid与Flex的配合Grid适合页面大骨架整体区域划分Flex适合局部组件内部的一维排列比如导航栏、工具栏、卡片内部元素的排布。两者结合是现代布局的最佳实践。六、常见布局问题与解决思维1. 何时用浮动/定位文字环绕用float。重叠、角标、下拉菜单用absoluterelative。固定导航用fixed或sticky。2. 何时用Flex/Grid行或列的一维排列、对齐、等分 → Flex。复杂的页面网格、同时需要行和列控制 → Grid。微调时还可以混合使用。3. 居中方案大全文字水平居中text-align: center块元素水平居中margin: 0 auto行内/行内块垂直居中vertical-align: middle配合行高比较古老Flex水平垂直居中display: flex; justify-content: center; align-items: center;Grid居中display: grid; place-items: center;七、总结我们从文档流出发遍历了浮动、定位最后用大量篇幅掌握了Flex和Grid。现在你应该能理解块级、行内、行内块的区别使用浮动做文字环绕并能清除浮动用relativeabsolute实现重叠效果用Flex轻松完成导航栏、等分列、垂直居中用Grid构建复杂的二维页面布局知道何时选用哪种布局技术如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。动手练习是掌握编程最快的方法请务必亲手敲一遍本文的所有示例代码并截图保存你的成果。你的关注是我坚持原创和细节共享的力量来源谢谢大家。