Skip to content

Flex 布局(二) ​

本页对应 Flex 布局,共 7 段视频,约 1 小时 7 分。

学习目标 ​

  1. 能够按照“先结构后样式、先大后小、先上后下”的流程,独立完成爱宠案例的 H2 标题、UL、LI 和 A 链接结构与样式。
  2. 能够准确区分并运用 padding 与 margin:盒内文字或子元素间距使用 padding,盒子与盒子间距使用 margin,并在测量时避开边框区域。
  3. 能够使用高度、行高、边框、背景色、内边距等属性实现标题左侧竖线、列表虚线底边框、文字缩进和图标背景定位等效果。
  4. 能够解释标准流中文档默认排布规则,说明块级元素独占一行、行内元素一行可显示多个,并能判断页面中哪些布局属于标准流。
  5. 能够使用 float: left / float: right 让多个块级元素一行显示,并说明浮动的顶对齐、行内块特性和脱标特点。
  6. 能够完成小米模块上部布局:设置 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>

小li四列布局效果

清除浮动 ​

为什么需要:浮动元素脱标;父级没有高度时,子级无法撑开父级高度,后面的标准流盒子会顶上来,导致布局错乱。清除浮动是清除“浮动带来的影响”。
怎么想:先搭场景:父级 .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 布局示意图

Flex 组成 ​

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

Flex 组成示意图

主轴对齐方式 ​

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

主轴对齐方式示意图

css
justify-content: space-between;

显示效果:两侧没缝隙

space-between 效果图

css
justify-content: space-around;

效果如下:记住2倍

space-around 效果图

css
justify-content: space-evenly;

效果如下:记住空隙一样大

space-evenly 效果图

css
 justify-content: center;

效果如下:经常用于让一个盒子水平居中

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 是块级元素,默认上下排列,所以先单独看尺寸和内部居中。怎么做?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一行对齐效果

为什么需要这一步?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。

常见错误 ​

  1. display: flex 加在了子元素上

    • 现象:几个盒子仍然上下堆叠,没有任何横向排列或对齐变化。
    • 原因:Flex 是"容器属性",必须加在父级(弹性容器)上,子元素只是弹性盒子。
    • 修法:把 display: flex 移到直接父元素;对齐属性 justify-content / align-items 同样写在父级,只有 align-self 写在子级。
  2. 用 margin 让盒子内的文字避开背景图标,结果整个盒子跑偏

    • 现象:文字确实让开了,但盒子的背景图、下边框一起右移,与相邻元素对不齐。
    • 原因:margin 移动的是盒子本身,padding 才是挤压盒子内部内容。
    • 修法:只要是"盒子内的文字/内容往里缩",一律用 padding;只有"盒子和盒子之间拉开距离"才用 margin。
  3. 给 li 加左右 padding 想做整体留白,虚线边框却延长到两侧

    • 现象:文字位置对了,但 li 的下边框(虚线)横贯整个父容器宽度,和设计稿不符。
    • 原因:padding 属于盒子内部,背景色、背景图、边框都会跟着延伸。
    • 修法:把左右留白加在父级 ul 上(padding: 0 9px),让 li 本身变窄。
  4. 量尺寸时把边框算进了内容区

    • 现象:写出来的高度总是差几像素,多个 li 累加后底部明显错位(如 9×30 量成 280)。
    • 原因:border 像一堵墙,内容区从边框内侧开始算,字是顶不到边框上的。
    • 修法:量取时从边框内侧拉到内侧;padding 也从边框内侧起算。要么统一 box-sizing: border-box 并接受微差,要么全部改成实测值(如 31px)。
  5. 父级没高度 + 子级浮动,底部盒子"跑"上来盖住

    • 现象:.bottom 压到了浮动元素下面,页面整体错乱。
    • 原因:浮动脱标不占位,父级高度塌陷为 0,后续标准流元素从父级顶部开始排。
    • 修法:清除浮动——给父级加 .clearfix(::after { content:""; display:block; clear:both; })或 overflow: hidden;额外标签法必须用块级元素,写 span 无效(或补 display: block)。
  6. 多列宽度 + 间距写满后换行

    • 现象:本来 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 让浏览器算间距。

练习 ​

  1. 卡片头部(Flex 版):一个 .box-hd 内含 h2(含 span 副标题)与右侧 a。要求:两端分布、底部对齐、上下 40px 内边距。写完后把 align-items 分别换成 flex-start / center,观察三种效果的差异并说明业务上分别对应什么场景。

  2. 清除浮动三选一:父容器 .top 不设高度,内含左右两个浮动盒子,下面紧跟 .bottom。分别用①额外标签法 ②单伪元素 .clearfix ③overflow: hidden 实现,然后在 .bottom 上加 margin-top 观察是否被"吃掉"(BFC 副作用),说明各自代价。

  3. 小米产品区(浮动实现):.mi 宽 1226、高 614;左 234×614、右 978×614;右侧 ul 内 8 个 li,每个 234×300,右间距 14、下间距 14。要求第 4、8 个 li 无右边距,且 4 个一行不换行。写完后把 box-sizing 删掉,解释为什么坏掉。

  4. 背景图标定位:给上题的 li 加左侧小图标(background: url(...) no-repeat left center),并让文字缩进 14px。要求分别用 padding-left 和 margin-left 各写一版,截图对比差异,用一句话说明为什么只能选其中一个。

  5. 同题重写(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

小结 ​

  1. 属性写错层级是最高频的错误来源:display: flex、justify-content、align-items 归父级,align-self、flex 归子级;写之前先问一句"我是给容器还是给项目"。
  2. padding 管盒内,margin 管盒外,这一条能解决一半的对齐问题:文字让位用 padding,盒子之间拉开用 margin,两者混用必然出现"背景/边框跟着跑"。
  3. 边框不算内容区,所有尺寸从边框内侧量起;累加多个元素时误差会放大,要么统一实测值,要么用 box-sizing: border-box 后接受设计稿级别的微差。
  4. 浮动三件套必须背下来:顶对齐、具备行内块特性、脱标。脱标是父级高度塌陷和后续元素上移的唯一根因,清除浮动就是给父级"找回高度"。
  5. 清除浮动优先用 .clearfix 伪元素法,overflow: hidden 作为备选(会裁切溢出内容、影响 margin-top),额外标签法只在教学演示中用。
  6. 能算的先算,能交给浏览器的别手算:space-between 让浏览器分配剩余空间,比手写 margin-right: 14px 加 :nth-child(4n) 更稳、更少出错。
  7. 写一行、存一次、看一眼:结构错的时候改样式只会越改越乱,先确认 DOM 层级(父是谁、兄弟是谁)再动 CSS。