主题
Flex 布局(二)
本页对应 Flex 布局,共 7 段视频,约 1 小时 7 分。
学习目标
- 能够按照“先结构后样式、先大后小、先上后下”的流程,独立完成爱宠案例的 H2 标题、UL、LI 和 A 链接结构与样式。
- 能够准确区分并运用 padding 与 margin:盒内文字或子元素间距使用 padding,盒子与盒子间距使用 margin,并在测量时避开边框区域。
- 能够使用高度、行高、边框、背景色、内边距等属性实现标题左侧竖线、列表虚线底边框、文字缩进和图标背景定位等效果。
- 能够解释标准流中文档默认排布规则,说明块级元素独占一行、行内元素一行可显示多个,并能判断页面中哪些布局属于标准流。
- 能够使用 float: left / float: right 让多个块级元素一行显示,并说明浮动的顶对齐、行内块特性和脱标特点。
- 能够完成小米模块上部布局:设置 1226px 版心,使用父容器约束左右浮动盒子,并按 234px、978px、614px 等尺寸搭建左右模块结构。
知识点
浮动基本使用
为什么需要:块元素默认独占一行,想让多个块元素水平排列,就要打破标准流;浮动是传统布局方式,本节了解即可。
怎么想:先写两个 div,默认上下排列;给它们分别加 float:left/right,观察是否一行、是否顶对齐、宽度是否变化、下面的标准流盒子是否被影响。转写稿演示:两个盒子高度 200 和 300 时仍按上沿对齐;去掉宽度后宽度随内容变化,说明具备行内块特点;底部黑色盒子会被浮动盒子压住,说明浮动盒子脱标、不占标准流位置。
怎么做:属性 float,值只有 left、right。
易错点:没有 center;浮动后盒子顶对齐,不是垂直居中;浮动盒子脱标,不占标准流位置,不要以为原位置还留着。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮动</title>
<style>
.left,
.right {
/* width: 200px; */
height: 200px;
background-color: pink;
}
.left {
/* 左浮动 */
float: left;
margin-left: 20px;
}
.right {
/* 右侧浮动 */
float: left;
height: 300px;
background-color: purple;
}
.bottom {
height: 50px;
background-color: black;
}
</style>
</head>
<body>
<div class="left">左侧123</div>
<div class="right">右侧123</div>
<div class="bottom"></div>
</body>
</html>特点:浮动后的盒子顶对齐;具备行内块特点;脱标,不占用标准流位置。

产品区域布局
为什么需要:实际页面常是“大盒子套左右盒子,再套小 li”,用浮动完成多列排列。
怎么想:先大后小。父盒子定宽居中;左侧一个盒子、右侧一个盒子;右侧内部再放 8 个 li,每行 4 个。转写稿演示:父级保持标准流,浮动子盒仍受父级约束,不会跑出父级。
怎么做:左盒子 float:left,右盒子 float:right;小 li 也 float:left,用 margin 控制间距,用 nth-child(4n) 去掉每行第 4 个的右外边距。
易错点:宽度要算准;小 li 宽度 234、右间距 14,4 个正好铺满 978;第 4、8 个要去掉右边距。

左右布局 HTML 结构:
html
<div class="mi">
<div class="left">左侧</div>
<div class="right">右侧</div>
</div>CSS 样式:
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
.mi {
width: 1226px;
height: 614px;
/* background-color: pink; */
margin: 100px auto;
}
.left {
float: left;
width: 234px;
height: 614px;
background-color: skyblue;
}
.right {
float: right;
width: 978px;
height: 614px;
background-color: purple;
}
区域小 li 布局完整写法:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
.mi {
width: 1226px;
height: 614px;
/* background-color: pink; */
margin: 100px auto;
}
.left {
float: left;
width: 234px;
height: 614px;
background-color: skyblue;
}
.right {
float: right;
width: 978px;
height: 614px;
/* background-color: purple; */
}
.right li {
float: left;
width: 234px;
height: 300px;
background-color: pink;
margin-bottom: 14px;
margin-right: 14px;
}
/* 让第4,8 个li 去掉外边距 */
.right li:nth-child(4n) {
margin-right: 0;
}
</style>
</head>
<body>
<div class="mi">
<div class="left">左侧</div>
<div class="right">
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
</div>
</body>
</html>
清除浮动
为什么需要:浮动元素脱标;父级没有高度时,子级无法撑开父级高度,后面的标准流盒子会顶上来,导致布局错乱。清除浮动是清除“浮动带来的影响”。
怎么想:先搭场景:父级 .top 不写高度,左右子盒浮动,底部 .bottom 会受影响。
怎么做:可用额外标签法、单伪元素法、双伪元素法、overflow 法。
易错点:额外标签必须放在父元素内容最后且是块级元素;伪元素要写 content:""、display、clear:both;父级要记得加 clearfix 类。

场景代码:
html
<style>
.top {
margin: 10px auto;
width: 1200px;
/* height: 300px; */
background-color: pink;
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: skyblue;
}
.right {
float: right;
width: 950px;
height: 300px;
background-color: orange;
}
.bottom {
height: 100px;
background-color: brown;
}
</style>
<div class="top">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="bottom"></div>额外标签法:在父元素内容最后添加块级元素,设置 clear:both。
易错点:不能加在浮动元素中间;标签必须是块级。
html
<style>
.clearfix {
clear: both;
}
</style>
<div class="father">
<div class="left"></div>
<div class="right"></div>
<div class="clearfix"></div>
</div>单伪元素法:给父级加 clearfix 类,用 ::after 清除。
易错点:display:block 和 clear:both 不能漏。
css
.clearfix::after {
content: "";
display: block;
clear: both;
}html
<div class="father clearfix"></div>双伪元素法:::before 解决外边距塌陷问题,::after 清除浮动。
易错点:两个伪元素都要 content:""、display:table;::after 还要 clear:both。
css
/* before 解决外边距塌陷问题 */
/* 双伪元素法 */
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
/* after 清除浮动 */
.clearfix::after {
clear: both;
}html
<div class="father clearfix"></div>overflow 法:给父级设置 overflow:hidden;。
易错点:写在父级,不是浮动子级;笔记中写作“overfow法”,实际属性是 overflow。
css
.father {
margin: 10px auto;
width: 1200px;
/* height: 300px; */
background-color: pink;
overflow: hidden;
}Flex 布局为什么需要
为什么需要:转写稿从标准流讲起:块级元素默认独占一行,想让多个块级元素一行显示,就要打破标准流;浮动虽然能做到,但会脱标、可能压住标准流盒子。Flex 布局是浏览器提倡的布局模型,适合结构化布局,提供强大的空间分布和对齐能力,并且不会产生浮动布局中的脱标现象。
怎么想:先判断需求是“多个盒子一行、分布、对齐”,还是普通上下排列;需要强分布和对齐时优先用 Flex。
怎么做:给父元素设置 display: flex,子元素可以自动挤压或拉伸。
易错点:display: flex 加在父元素上,不是加在每个子元素上;不要再用浮动思路处理 Flex 子项。

Flex 组成
为什么需要:不知道弹性容器、弹性盒子、主轴和侧轴,就分不清属性该加给谁。
怎么想:把父元素想成弹性容器,直接子元素是弹性盒子;默认主轴在水平方向,侧轴/交叉轴在垂直方向。
怎么做:父元素设置 display: flex;容器控制整体排列,弹性盒子可单独控制。
易错点:主轴和侧轴默认方向别记反;align-items 给弹性容器,align-self 给某个弹性盒子。

主轴对齐方式
为什么需要:横向分布、两端对齐、等间距、居中都要靠主轴对齐。
怎么想:先看“两侧有没有缝、缝隙是否一样、是否两倍”。
怎么做:使用 justify-content。重点记住标红值;最常用的是 space-between。记忆:两侧没缝隙是 between,缝隙一样大是 evenly,2 倍缝隙是 around。
易错点:space-between 两侧没缝隙;space-around 是 2 倍缝隙;center 常用于让一个盒子水平居中;不要把主轴对齐写成侧轴属性。

css
justify-content: space-between;显示效果:两侧没缝隙

css
justify-content: space-around;效果如下:记住2倍

css
justify-content: space-evenly;效果如下:记住空隙一样大

css
justify-content: center;效果如下:经常用于让一个盒子水平居中

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
/* 给父亲添加 flex */
display: flex;
/* 主轴的排列方式 */
/* justify-content: flex-start; */
/* justify-content: flex-end; */
/* 让子盒子居中对齐 */
/* justify-content: center; */
/* between */
/* justify-content: space-between; */
/* justify-content: space-around; */
justify-content: space-evenly;
width: 900px;
height: 200px;
background-color: pink;
}
.box div {
width: 249px;
height: 200px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</body>
</html>
侧轴对齐方式
为什么需要:主轴解决横向分布,侧轴还要解决顶部、底部、居中、拉伸等对齐。
怎么想:整体统一对齐用 align-items;某个盒子特殊对齐用 align-self。
怎么做:align-items 给弹性容器设置,控制当前容器内所有弹性盒子的侧轴对齐;align-self 给某个弹性盒子设置,单独控制它自己。
易错点:stretch 是默认值,子盒子没给高度时容易和父元素一样高;给容器和给单个盒子的属性别混用。

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
/* 给父亲添加 flex */
display: flex;
/* 主轴的排列方式 */
/* justify-content: flex-start; */
/* justify-content: flex-end; */
/* 让子盒子居中对齐 */
/* justify-content: center; */
/* between */
/* 两侧没缝隙 */
/* justify-content: space-between; */
/* 两倍缝隙 */
/* justify-content: space-around; */
justify-content: space-evenly;
/* 侧轴的对齐方式 */
/* 顶部对齐 */
/* align-items: flex-start; */
/* 底部对齐 */
/* align-items: flex-end; */
/* 居中对齐 */
/* align-items: center; */
/* 默认的 拉伸和父亲一样 */
align-items: stretch;
width: 900px;
height: 500px;
background-color: pink;
}
.box div {
width: 249px;
/* height: 200px; */
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</body>
</html>
盒子水平和垂直居中
为什么需要:一个盒子在父盒子中水平垂直居中是高频需求。
怎么想:主轴水平居中用 justify-content: center,侧轴垂直居中用 align-items: center。
怎么做:父元素设置 display: flex,再同时写主轴居中和侧轴居中。
易错点:两个 center 分别管不同轴;只写一个只能在一个方向居中。转写稿也提醒:盒子和盒子之间的距离常用 margin,盒子内部文字/内容常用 padding;量尺寸时从边框里侧量,不要把边框算进去。

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.father {
/* 利用flex实现 */
display: flex;
/* 主轴水平居中 */
justify-content: center;
/* 侧轴水平居中 */
align-items: center;
width: 300px;
height: 300px;
background-color: pink;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>调试与布局思路
为什么需要:转写稿反复强调,不要截图抄代码,否则不知道下一步做什么;结构错了只改 CSS 会越改越乱。
怎么想:先大后小、先上后下;写一两行就保存看效果,再根据效果决定下一步。
怎么做:先搭结构,再修饰盒子;忘了属性就回看笔记或示例,但要根据当前效果写。
易错点:结构错时先查结构,不要死改样式;量尺寸不要量边框;Flex 里也要分清容器和盒子的属性。
案例目标与整体思路

这个综合案例要把“新鲜好物”做成一个完整模块:外面一个大盒子,上面是头部标题,下面是商品列表。为什么要先看整体?因为布局要“先大后小、先上后下”,先把大盒子搭出来,再修饰里面的小盒子。怎么想?先确定版心宽度、居中和临时背景色,方便观察盒子位置。怎么做?先写 HTML 骨架,再写 CSS。易错点:不要一上来就抠文字样式,结构没搭好时越改越乱;写一两行就保存看效果,别把示例代码放一边照抄。
大盒子搭建
HTML 结构:
html
<div class="box">
<div class="box-hd">头部</div>
<div class="box-bd">主题</div>
</div>CSS 样式:
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
.box {
width: 1240px;
height: 540px;
background-color: pink;
margin: 100px auto;
}显示:

为什么需要大盒子?它是整个模块的约束范围。怎么想?宽度 1240px,用 margin: 100px auto 水平居中;先给粉色背景便于看边界。怎么做?按上面代码写。易错点:margin: 100px auto 是上下 100、左右自动;box-sizing: border-box 要保留,后面加 padding 不易撑破宽度;li 默认小圆点要先去掉。
头部标题制作
HTML 写法:
html
<div class="box">
<div class="box-hd">
<h2>新鲜好物
<span>新鲜出炉 品质靠谱</span>
</h2>
<a href="#">查看更多> </a>
</div>
<div class="box-bd">主题</div>
</div>CSS 写法:
css
.box-hd {
/* 给父亲添加 flex 里面的孩子 h2 和 a 可以一样显示 */
display: flex;
/* 两侧没缝隙 主轴对齐 */
justify-content: space-between;
/* 侧轴底对齐 */
align-items: flex-end;
padding: 40px 0;
}效果:

为什么需要 flex?h2 和 a 要在一行,并且一个靠左、一个靠右。怎么想?flex 要加给它们的父亲 .box-hd,不是加给 h2 或 a。怎么做?主轴 space-between 让两端分开,侧轴 flex-end 让底部对齐,padding: 40px 0 留上下间距。易错点:flex 加错层级;align-items: flex-end 是底对齐,不是 flex-start;盒子和盒子之间用 margin,盒内文字挤动用 padding,不要混。
修饰文字
CSS 样式:
css
.box-hd h2 {
font-size: 32px;
font-weight: 400;
}
.box-hd h2 span {
font-size: 16px;
color: #999;
}
.box-hd a {
font-size: 16px;
color: #999;
}展示:

为什么需要修饰?标题和说明文字要有层级。怎么想?span 是 h2 里的说明,选择器要写 .box-hd h2 span。怎么做?主标题 32px、字重 400;说明和链接 16px、灰色。易错点:span 选择器不要只写 span,否则会影响全页;a 默认有下划线,本笔记未要求去掉就不要擅自加。
底部小 li 制作
HTML 结构:
html
<ul>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
</ul>CSS 样式:
css
.box-bd li {
width: 306px;
height: 406px;
background-color: skyblue;
text-align: center;
}
.box-bd li img {
width: 100%;
}
.box-bd li h4 {
font-size: 22px;
font-weight: 400;
margin: 12px 0 20px;
}
.box-bd li p {
font-size: 18px;
color: orangered;
}展示:

为什么先做一个小 li?先把一个商品卡片调好,再复制。怎么想?li 是块级元素,默认上下排列,所以先单独看尺寸和内部居中。怎么做?li 定宽高,text-align: center 让图片、文字水平居中;图片 width: 100% 适应 li;h4 用 margin 拉开上下距离。易错点:图片不设宽度容易溢出;li 的蓝色只是临时观察,最后可去掉;h4 默认字重较粗,这里用 400 改回常规。
多个 li 显示到一行并对齐
CSS 样式:
css
.box-bd ul {
/* 一定是li的亲爸爸 */
display: flex;
justify-content: space-between;
}展示:

为什么需要这一步?li 是块级元素,默认会竖着排;要一行显示就要打破标准流。怎么想?flex 要加在 li 的亲爸爸 ul 上。怎么做?.box-bd ul 加 display: flex,主轴 justify-content: space-between 让多个 li 两端对齐、中间自动分缝。易错点:不要把 flex 加到 li 上;父级宽度和 li 宽度要算得过来;如果结构写错,先查 HTML,不要只盯着 CSS 改。
完整效果与调试习惯

完整代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
.box {
width: 1240px;
height: 540px;
/* background-color: pink; */
margin: 100px auto;
}
.box-hd {
/* 给父亲添加 flex 里面的孩子 h2 和 a 可以一样显示 */
display: flex;
/* 两侧没缝隙 主轴对齐 */
justify-content: space-between;
/* 侧轴底对齐 */
align-items: flex-end;
padding: 40px 0;
}
.box-hd h2 {
font-size: 32px;
font-weight: 400;
}
.box-hd h2 span {
font-size: 16px;
color: #999;
}
.box-hd a {
font-size: 16px;
color: #999;
}
.box-bd ul {
/* 一定是li的亲爸爸 */
display: flex;
justify-content: space-between;
}
.box-bd li {
width: 306px;
height: 406px;
background-color: skyblue;
text-align: center;
}
.box-bd li img {
width: 100%;
}
.box-bd li h4 {
font-size: 22px;
font-weight: 400;
margin: 12px 0 20px;
}
.box-bd li p {
font-size: 18px;
color: orangered;
}
</style>
</head>
<body>
<div class="box">
<!-- 头部部分 -->
<div class="box-hd">
<h2>新鲜好物
<span>新鲜出炉 品质靠谱</span>
</h2>
<a href="#">查看更多> </a>
</div>
<!-- 主体部分 -->
<div class="box-bd">
<ul>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
</ul>
</div>
</div>
<div class="box">
<!-- 头部部分 -->
<div class="box-hd">
<h2>新鲜好物
<span>新鲜出炉 品质靠谱</span>
</h2>
<a href="#">查看更多> </a>
</div>
<!-- 主体部分 -->
<div class="box-bd">
<ul>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
</ul>
</div>
</div>
</body>
</html>为什么最后要放完整代码?方便对照结构和样式。怎么想?做页面时先大后小、先上后下;写一句保存一句看效果。怎么做?结构上先 .box,再 .box-hd、.box-bd;样式上先公共重置,再逐层修饰。易错点:测量时不要量到边框里侧,盒子和盒子之间用 margin,盒内文字用 padding;如果效果错位,先查 HTML 结构,不要只改 CSS。
代码示例
示例 1:浮动基本使用(脱标演示)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮动</title>
<style>
.left,
.right {
/* width: 200px; */
height: 200px;
background-color: pink;
}
.left {
/* 左浮动 */
float: left;
margin-left: 20px;
}
.right {
/* 右侧浮动 */
float: left;
height: 300px;
background-color: purple;
}
.bottom {
height: 50px;
background-color: black;
}
</style>
</head>
<body>
<div class="left">左侧123</div>
<div class="right">右侧123</div>
<div class="bottom"></div>
</body>
</html>要点解释:
float只有left和right两个值,没有 center,想居中只能给盒子加margin挤过去。- 浮动的盒子顶对齐:
.left高 200px、.right高 300px,两个盒子是沿上沿对齐的,不是底对齐也不是居中对齐。 - 浮动的盒子具备行内块特点:注释掉
width后宽度不再撑满浏览器,而是由内容撑开;给了宽度也能按给定宽度显示。 - 易错点(脱标):
.bottom是标准流,而上面两个盒子加了浮动已经脱离标准流,所以黑色盒子会跑到浮动盒子底下被压住——浮动的盒子会压住标准流的盒子,且原位置不再保留。 - 两个盒子都写
float: left就能挨在一起,不必一个 left 一个 right。
示例 2:清除浮动(父级无高度导致高度塌陷)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清除浮动</title>
<style>
.top {
margin: 10px auto;
width: 1200px;
/* height: 300px; */
background-color: pink;
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: skyblue;
}
.right {
float: right;
width: 950px;
height: 300px;
background-color: orange;
}
.bottom {
height: 100px;
background-color: brown;
}
/* 单伪元素法清除浮动 */
.clearfix::after {
content: "";
display: block;
clear: both;
}
</style>
</head>
<body>
<div class="top clearfix">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="bottom"></div>
</body>
</html>要点解释:
- 场景:
.top父级没有高度,两个子盒子又都浮动了(脱标),子级撑不开父级,.top高度变成 0,.bottom会顶上去,页面布局错乱。 - 解决方法是清除浮动(清除浮动带来的影响),本段用笔记中的单伪元素法:
.clearfix::after+content: ""+display: block+clear: both,再给父级加上clearfix类。 - 易错点:
content: ""和display: block一个都不能少——伪元素默认是行内元素,不加display: block就撑不开高度;clear: both加在伪元素上,不是加在.left/.right上。 - 其他可选方案(笔记中同样记录):额外标签法(父元素内容最后加块级元素
.clearfix { clear: both; })、双伪元素法(::before, ::after { content: ""; display: table; },::after { clear: both; },before顺带解决外边距塌陷)、overflow 法(直接给父级overflow: hidden)。 - 验证方法:把
clearfix类从.top上删掉,就能看到.bottom被压住/顶上去的错误效果。
示例 3:Flex 布局综合案例(新鲜好物)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
.box {
width: 1240px;
height: 540px;
/* background-color: pink; */
margin: 100px auto;
}
.box-hd {
/* 给父亲添加 flex 里面的孩子 h2 和 a 可以一样显示 */
display: flex;
/* 两侧没缝隙 主轴对齐 */
justify-content: space-between;
/* 侧轴底对齐 */
align-items: flex-end;
padding: 40px 0;
}
.box-hd h2 {
font-size: 32px;
font-weight: 400;
}
.box-hd h2 span {
font-size: 16px;
color: #999;
}
.box-hd a {
font-size: 16px;
color: #999;
}
.box-bd ul {
/* 一定是li的亲爸爸 */
display: flex;
justify-content: space-between;
}
.box-bd li {
width: 306px;
height: 406px;
background-color: skyblue;
text-align: center;
}
.box-bd li img {
width: 100%;
}
.box-bd li h4 {
font-size: 22px;
font-weight: 400;
margin: 12px 0 20px;
}
.box-bd li p {
font-size: 18px;
color: orangered;
}
</style>
</head>
<body>
<div class="box">
<!-- 头部部分 -->
<div class="box-hd">
<h2>新鲜好物
<span>新鲜出炉 品质靠谱</span>
</h2>
<a href="#">查看更多> </a>
</div>
<!-- 主体部分 -->
<div class="box-bd">
<ul>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
<li>
<img src="./images/1.jpg" alt="">
<h4>全防水HABU旋钮</h4>
<p>¥444.00</p>
</li>
</ul>
</div>
</div>
</body>
</html>要点解释:
display: flex加在父元素上:.box-hd加了 flex,里面的h2和a就能一行显示,不会产生浮动那种脱标现象。- 主轴对齐
justify-content: space-between:两侧没缝隙,这是最常用的值;记忆口诀——两侧没缝隙是between,缝隙一样大是evenly,2 倍缝隙是around。 - 侧轴对齐
align-items: flex-end:让h2和a底对齐,配合.box-hd的padding: 40px 0得到标题区的效果。 - 易错点:
.box-bd ul上的display: flex一定是给 li 的亲爸爸(ul),给.box-bd或给li都无效,四个 li 不会排到一行。 .box-bd li img { width: 100% }让图片宽度跟随 li 的 306px,防止图片撑破盒子。- 水平垂直居中盒子的写法:父级同时写
display: flex、justify-content: center(主轴水平居中)、align-items: center(侧轴居中)即可。 - 如需单独控制某个弹性盒子的侧轴对齐,用
align-self(写在弹性盒子上),不要改align-items。
常见错误
display: flex加在了子元素上- 现象:几个盒子仍然上下堆叠,没有任何横向排列或对齐变化。
- 原因:Flex 是"容器属性",必须加在父级(弹性容器)上,子元素只是弹性盒子。
- 修法:把
display: flex移到直接父元素;对齐属性justify-content/align-items同样写在父级,只有align-self写在子级。
用
margin让盒子内的文字避开背景图标,结果整个盒子跑偏- 现象:文字确实让开了,但盒子的背景图、下边框一起右移,与相邻元素对不齐。
- 原因:
margin移动的是盒子本身,padding才是挤压盒子内部内容。 - 修法:只要是"盒子内的文字/内容往里缩",一律用
padding;只有"盒子和盒子之间拉开距离"才用margin。
给
li加左右padding想做整体留白,虚线边框却延长到两侧- 现象:文字位置对了,但
li的下边框(虚线)横贯整个父容器宽度,和设计稿不符。 - 原因:
padding属于盒子内部,背景色、背景图、边框都会跟着延伸。 - 修法:把左右留白加在父级
ul上(padding: 0 9px),让li本身变窄。
- 现象:文字位置对了,但
量尺寸时把边框算进了内容区
- 现象:写出来的高度总是差几像素,多个
li累加后底部明显错位(如 9×30 量成 280)。 - 原因:
border像一堵墙,内容区从边框内侧开始算,字是顶不到边框上的。 - 修法:量取时从边框内侧拉到内侧;
padding也从边框内侧起算。要么统一box-sizing: border-box并接受微差,要么全部改成实测值(如 31px)。
- 现象:写出来的高度总是差几像素,多个
父级没高度 + 子级浮动,底部盒子"跑"上来盖住
- 现象:
.bottom压到了浮动元素下面,页面整体错乱。 - 原因:浮动脱标不占位,父级高度塌陷为 0,后续标准流元素从父级顶部开始排。
- 修法:清除浮动——给父级加
.clearfix(::after { content:""; display:block; clear:both; })或overflow: hidden;额外标签法必须用块级元素,写span无效(或补display: block)。
- 现象:
多列宽度 + 间距写满后换行
- 现象:本来 4 个一行,第 4 个掉到第二行。
- 原因:
width+margin/padding累加超过父容器宽度,忘了box-sizing: border-box或没给最后一个去边距。 - 修法:先算总账(4×234 + 3×14 = 978),用
:nth-child(4n) { margin-right: 0 }去尾边距;或改用 Flex 的justify-content: space-between让浏览器算间距。
练习
卡片头部(Flex 版):一个
.box-hd内含h2(含span副标题)与右侧a。要求:两端分布、底部对齐、上下40px内边距。写完后把align-items分别换成flex-start/center,观察三种效果的差异并说明业务上分别对应什么场景。清除浮动三选一:父容器
.top不设高度,内含左右两个浮动盒子,下面紧跟.bottom。分别用①额外标签法 ②单伪元素.clearfix③overflow: hidden实现,然后在.bottom上加margin-top观察是否被"吃掉"(BFC 副作用),说明各自代价。小米产品区(浮动实现):
.mi宽 1226、高 614;左 234×614、右 978×614;右侧ul内 8 个li,每个 234×300,右间距 14、下间距 14。要求第 4、8 个li无右边距,且 4 个一行不换行。写完后把box-sizing删掉,解释为什么坏掉。背景图标定位:给上题的
li加左侧小图标(background: url(...) no-repeat left center),并让文字缩进 14px。要求分别用padding-left和margin-left各写一版,截图对比差异,用一句话说明为什么只能选其中一个。同题重写(Flex 版):用 Flex 重写第 3 题的整体布局与
li排列,与浮动版对比:代码行数、是否需要清浮动、li宽度是否要手算。结论写成两行注释放在代码顶部。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 爱宠案例-标题制作 | 08:42 |
| 2 | 爱宠案例-ul制作 | 07:26 |
| 3 | 爱宠案例-li和a制作 | 06:34 |
| 4 | 爱宠案例结束 | 12:37 |
| 5 | 标准流 | 06:39 |
| 6 | 浮动 | 12:13 |
| 7 | 小米模块布局上 | 12:49 |
小结
- 属性写错层级是最高频的错误来源:
display: flex、justify-content、align-items归父级,align-self、flex归子级;写之前先问一句"我是给容器还是给项目"。 padding管盒内,margin管盒外,这一条能解决一半的对齐问题:文字让位用 padding,盒子之间拉开用 margin,两者混用必然出现"背景/边框跟着跑"。- 边框不算内容区,所有尺寸从边框内侧量起;累加多个元素时误差会放大,要么统一实测值,要么用
box-sizing: border-box后接受设计稿级别的微差。 - 浮动三件套必须背下来:顶对齐、具备行内块特性、脱标。脱标是父级高度塌陷和后续元素上移的唯一根因,清除浮动就是给父级"找回高度"。
- 清除浮动优先用
.clearfix伪元素法,overflow: hidden作为备选(会裁切溢出内容、影响margin-top),额外标签法只在教学演示中用。 - 能算的先算,能交给浏览器的别手算:
space-between让浏览器分配剩余空间,比手写margin-right: 14px加:nth-child(4n)更稳、更少出错。 - 写一行、存一次、看一眼:结构错的时候改样式只会越改越乱,先确认 DOM 层级(父是谁、兄弟是谁)再动 CSS。