主题
Flex 布局(一)
本页对应 Flex 布局,共 7 段视频,约 1 小时 29 分。
学习目标
- 能够解释外边距塌陷的成因,并分别用父元素加
padding-top、overflow: hidden、透明上边框三种方式解决。 - 能够实现版心居中:为有宽度的块级元素设置
margin: 0 auto,并说明其生效条件。 - 能够独立复现“网页新闻列表”作业模块,正确使用高度剩余法、
li下边框、链接去下划线及:hover效果。 - 能够独立复现“课程卡片”作业模块,正确设置图片
width: 100%、标题与段落的margin对齐、局部文字变色。 - 能够完成小米登录案例的 logo、标题、两个输入框和登录按钮,正确使用背景图、
placeholder、padding-left、margin-bottom及按钮悬停样式。 - 能够搭建爱宠案例大盒子,设置固定宽高、水平居中、边框、背景图片,并说明标准流默认排列及浮动仅作了解。
知识点
标准流:标签默认的排布规则
为什么需要:一个页面里往往同时存在 div、h2、p、ul、li、a、span、input 这些标签。如果不知道它们默认怎么排,写 CSS 就只能靠试——挪一下看看,不行再挪一下,效率极低。转写稿里反复追问“块的元素需要给宽吗”,就是在确认大家对默认规则的掌握程度。
怎么想:浏览器在完全没有 CSS 的情况下,也有一套自己的排布规则,这套规则叫标准流,也叫文档流。它不需要我们写任何代码,只要不给标签加浮动、定位、flex,它就一直在起作用。所以我们写布局,本质上是“先接受标准流,再按需要打破它”。
怎么做:在页面里写两个 div、两个 span,不写任何样式,打开浏览器观察它们的落位。

块元素独占一行,行内元素可以一行显示多个——这是标准流最直观的两条结论。
易错点:标准流不是一条 CSS 属性,不存在“开启标准流”的写法。它是默认状态,你只能通过浮动、定位、flex 去改变它。
块级元素:独占一行,宽度默认撑满父元素
为什么需要:转写稿讲作业时,直接说:“块的元素是不是默认的宽度和父亲一样宽呀,所以我们只需要给个高给个下边框。”这句话决定了 CSS 到底写几行。不知道这一点,就会习惯性给每个 div 补一句 width: 100%。
怎么想:块级元素(div、h1~h6、p、ul、li 等)有两个默认行为:一是独占一行,后面的元素只能换行;二是宽度自动填满父元素。所以父盒子有确定宽度时,子块不写 width 就是满宽。
怎么做:给新闻列表的 li 只写高度和下边框就够了:
css
.box ul li {
height: 50px;
line-height: 50px;
border-bottom: 1px dashed #ccc;
}不用写 width,li 默认就和 ul 一样宽。
易错点:块元素即使写了 width,也仍然独占一行,右边不会自动补上别的块。想让两个块并排,必须等后面学浮动或 flex。另外“撑满父元素”的前提是父元素有宽度,父元素没宽度时,块元素的宽度由它的包含块决定。
行内元素:一行显示多个,盒子大小由内容决定
为什么需要:新闻列表里“体验 JavaScript 的魅力”是 a 标签,转写稿里特意强调:“你没有必要非得给 A 这么大,我们这是网页新闻,你没有见过鼠标放到这儿去就可以点击。”这说明行内元素的盒子范围就是文字本身。
怎么想:行内元素(a、span 等)不独占一行,能在一行里连续排。它的宽高由内容撑开,所以给它设 width、height 是没有意义的。
怎么做:想让文字往里缩,从 li 的角度给 padding-left,而不是给 a 设宽度:
css
.box ul li {
padding-left: 30px;
}
.box ul li a {
color: #333;
text-decoration: none;
}转写稿里也提到“给 A 来一个 margin-left: 30px 也行”,两种都能挤过去,暂时没区别。但要注意原则:想改谁就选谁,改文字颜色必须选到 a,选 li 是不生效的。
易错点:给行内元素设宽高无效;给行内元素设上下 margin 往往不生效,只有左右 margin 可靠。
行内块元素:input 的默认宽度不是父元素的宽度
为什么需要:小米登录案例里,两个 input 和按钮都要撑满 339px。转写稿里的原话是:“因为 input 它属于行内块元素,默认的大小呀,它不会和父亲一样宽,所以这个 input 必须要给宽高。”
怎么想:input 既不完全是块,也不完全是行内——它一行能放多个,但又能设宽高,所以归为行内块。正因为“不会和父亲一样宽”,就必须手动量出来给它。
怎么做:
css
.mi input {
width: 339px;
height: 50px;
border: 1px solid #ccc;
padding-left: 12px;
}易错点:这里的 padding-left: 12px 只能用 padding,不能用 margin——margin 会把整个盒子推走,而我们要的是“盒子不动、文字往里缩”。同理,text-indent 是段落首行缩进用的,布局时不要拿它调距离。
标准流下的版心居中
为什么需要:转写稿里说“所有的块级元素默认是不是都是左对齐”,而网站主要内容必须居中。小米版心 1226px、淘宝版心 1190px,宽度不同但居中的写法一样。
怎么想:块元素默认左对齐,说明它右侧有多余空间。把左右外边距都设成 auto,浏览器会把剩余空间平分到两边,盒子就居中了。
怎么做:
css
.w {
width: 1226px;
height: 500px;
background-color: pink;
margin: 0 auto;
}易错点:第一,必须给宽度,没宽度的块本来就满宽,看不出居中效果;第二,行内元素不能用这招;第三,margin: 0 auto 只解决水平居中,上下写 auto 不会让盒子垂直居中。
小结
标准流是所有布局的地基:块独占一行且默认满宽,行内能并排但盒子随内容,行内块能设宽高但不随父元素。记住这三条,写 CSS 时就知道哪些属性该写、哪些纯属多余。
本节定位:浮动“了解即可”
转写稿里明确说:浮动“作为一个弱化的了,简单了解了”,重点讲 flex 布局。所以本节不把浮动当主力布局,只掌握三件事:float 怎么用、浮动盒子有什么现象、父级没高度时怎么清除浮动。转写稿里常把 margin 说成“麻疹/马真”、padding 说成“排定/排令”,这里统一写 margin、padding,避免记错单词。
基本使用
为什么需要:块元素默认独占一行,想让两个块元素水平排列,早期常用 float。
怎么想:给盒子加 float: left 或 float: right,让盒子向左/向右靠。
怎么做:
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,右盒子 float: right。
怎么做:
html
<div class="mi">
<div class="left">左侧</div>
<div class="right">右侧</div>
</div>html
<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;
}
</style>效果:

易错点:左右宽度和间距要算准;父级最好给高度或后续清除浮动,否则可能影响下面布局。
产品区域布局:小 li 排列
为什么需要:右侧商品列表要一行多个排列。
怎么想:让 li 左浮动,用 margin-right、margin-bottom 做间距,每行最后一个去掉右间距。
怎么做:
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>
易错点:nth-child(4n) 是去第 4、8 个的右间距;宽度、间距、父级宽度要能对上,否则会掉行。
清除浮动:为什么需要
为什么需要:浮动元素脱标,父级没高度时,子级撑不开父级高度,下面盒子会跑上来。
怎么想:清除浮动不是“删除浮动”,而是清除浮动对后面布局的影响。
怎么做:先看问题场景:

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 类。
css
.clearfix::after {
content: "";
display: block;
clear: both;
}html
<div class="father clearfix"></div>双伪元素法:before 解决外边距塌陷,after 清除浮动。
css
/* before 解决外边距塌陷问题 */
/* 双伪元素法 */
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
/* after 清除浮动 */
.clearfix::after {
clear: both;
}html
<div class="father clearfix"></div>overflow 法:给父级加 overflow: hidden。
css
.father {
margin: 10px auto;
width: 1200px;
/* height: 300px; */
background-color: pink;
overflow: hidden;
}易错点:额外标签法会多一个空标签;伪元素法要记得给父级加类;overflow: hidden 可能裁剪溢出内容。实际开发中优先按项目规范选,不要混用后忘记原因。
本节图示

代码示例
代码示例一:浮动基本使用
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让块元素水平排列,两个盒子顶对齐。- 浮动后的盒子脱标,不占标准流位置,所以
.bottom会钻到浮动盒子的下面(被遮住),这是最典型的“看不出效果”的原因。 - 浮动后的盒子具备行内块特点:不给宽度时宽度由内容撑开(
.left的width被注释掉就是这个演示点)。 .right只改了height: 300px,与.left高度不同,用来验证顶对齐而不是底部对齐。
代码示例二:小米产品区域布局(左右布局 + 小 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>关键行与易错点:
margin: 100px auto是版心居中:有宽度的块级元素,左右外边距设为auto才能水平居中。.left用float: left、.right用float: right,一个靠左一个靠右,实现左右布局。- 每个
li都float: left才能一行排 4 个;宽度计算依赖box-sizing: border-box(内减模式)。 - 易错点:一排 4 个时,第 4 个 li 的
margin-right会把 4 个挤到下一行,必须用:nth-child(4n)去掉每行最后一个的右外边距。 - 易错点:
* { margin: 0; padding: 0 }和li { list-style: none }是清除默认样式的固定前置写法,漏写会出现小圆点和莫名间距。
代码示例三:清除浮动(父级没有高度,子级浮动脱标)
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 类即可 */
.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的height被注释掉(父级没有高度),里面两个子盒子都浮动脱标,子级撑不开父级高度,父级高度塌成 0,.bottom就顶上去造成布局错乱。 - 单伪元素法三件套必须齐全:
content: ""、display: block、clear: both,少任何一个都清不掉浮动。 - 注意
.clearfix要加在父级(.top)上,不是加在子级上。 - 笔记中的其他三种写法(任选其一即可):
css
/* 双伪元素法:before 解决外边距塌陷,after 清除浮动 */
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
.clearfix::after {
clear: both;
}
/* overflow 法:直接加给父级 */
.father {
overflow: hidden;
}- 额外标签法:在父元素内容的最后加一个块级元素,设置
clear: both(行内元素无效,这是易错点)。 - 易错点:
clear: both是加在“清除浮动影响”的元素上(伪元素/额外标签/父级 overflow),不是加在浮动盒子自己身上。
常见错误
父级没有高度,子级浮动后底部盒子顶上来
现象:父盒子背景/边框包不住浮动子元素,后面的.bottom与浮动区域重叠。
原因:浮动元素脱标,父级未形成 BFC,也未清除浮动。
修法:给父级加.clearfix(伪元素清除)或overflow: hidden,不要只在浮动子元素上写clear: both。清除浮动写成给浮动子元素加
clear: both
现象:父级高度仍然塌陷,页面布局没恢复。
原因:clear要作用在浮动元素之后的块级元素/伪元素上,不是随便加在浮动元素自身。
修法:在父元素内容最后加块级清除元素,或用.clearfix::after { content:""; display:block; clear:both; }。版心居中写成
text-align: center或只写margin-left: auto
现象:盒子没有整体水平居中,或只有左侧自动外边距导致偏右/无效。
原因:text-align控制行内内容,不是块级盒子居中;块级盒子需左右外边距都为auto。
修法:有宽度的块级盒子写margin: 0 auto;或margin: 100px auto;。父子嵌套时直接给子元素
margin-top,父盒子一起下移
现象:想让子盒子往下走,结果父盒子整体被带下来。
原因:父子外边距塌陷。
修法:优先给父级加padding-top;或父级overflow: hidden;或加透明上边框;或按需求改用父级 padding 控制内容位置。input不给宽高,直接指望它撑满父级
现象:输入框很短,和设计稿宽度不一致。
原因:input是行内块元素,不会像块元素一样默认占满父级宽度。
修法:显式给width、height、border,需要文字内缩时用padding-left。背景图被前面的
background-color或简写覆盖
现象:写了background: url(...)后背景色没了,或背景图不显示。
原因:background是复合属性,后写会覆盖前面同名部分;层叠顺序写反。
修法:按“先大后小”写,先写background简写,再补background-color;或分开写background-image、background-color。多列小
li给每个都加右外边距,最后一列被挤换行
现象:一行 4 个变成一行 3 个或布局错位。
原因:第 4、8 个li仍保留margin-right,总宽度超过父级。
修法:用:nth-child(4n) { margin-right: 0; }去掉每行最后一个的右外边距,并确认盒模型为border-box。
练习
找错并修复:浮动父级塌陷
给出.top内两个浮动子元素、下方.bottom的结构,要求让.top正确包住子元素且.bottom不被覆盖。
检查点:父级是否使用清除浮动;是否没有给浮动子元素乱加clear。实现一个版心居中的两栏区域
要求:外层宽1226px居中,左栏234px左浮动,右栏978px右浮动,并保证下方模块不重叠。
检查点:margin: 0 auto、浮动方向、父级高度/清除浮动处理。实现 4 列小卡片布局
要求:右栏内 8 个li左浮动,每行 4 个,卡片宽234px、右间距14px、下间距14px。
检查点:第 4、8 个li的右外边距是否为 0;总宽度是否超出容器。复现小米登录框局部
要求:完成 logo、标题、两个input、登录按钮。logo 用h1+ 背景图;输入框给宽高、边框和左内边距;按钮去掉默认边框并设置背景色。
检查点:input是否显式设宽高;文字是否用padding-left内缩;按钮边框是否清除。复现爱宠卡片局部
要求:大盒子宽高约262×342,水平居中,带边框和背景图;内部标题、列表项按设计稿调整间距。
检查点:背景图是否平铺;父级是否居中;列表项间距是否用外边距/内边距合理控制。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 反馈和复习 | 19:56 |
| 2 | 作业1 | 18:52 |
| 3 | 作业2 | 12:47 |
| 4 | 小米登录案例-logo制作 | 13:41 |
| 5 | 小米标题和input | 10:17 |
| 6 | 小米input和button | 07:26 |
| 7 | 爱宠案例-大盒子搭建 | 06:02 |
小结
- 浮动适合让块元素水平排列,但必须处理脱标带来的父级高度塌陷问题。
- 清除浮动的核心是让父级重新包住浮动子元素,常用伪元素法或
overflow: hidden。 - 版心居中的关键是“有宽度的块级盒子 + 左右
margin: auto”,不是text-align。 - 父子嵌套优先用父级
padding控制内容整体内缩,能减少外边距塌陷和重复写子元素外边距。 - 盒子和盒子之间的距离优先考虑
margin;盒子内部文字/内容的内缩优先考虑padding。 input、按钮等行内块/表单元素通常需要显式宽高,不能默认依赖父级宽度。- 背景图、背景色、边框和盒模型要一起检查,尤其注意
background简写的层叠覆盖。 - 多列布局要计算总宽度,并用
:nth-child去掉每行最后一个元素的多余外边距。