Skip to content

学成在线(一) ​

本页对应 学成在线,共 8 段视频,约 1 小时 21 分。

学习目标 ​

  • 能够说明浮动与 Flex 布局的适用场景,并在需要多个块级元素一行排列时优先使用 Flex 布局。
  • 能够为父容器设置 display: flex,并使用 flex-wrap: wrap 让子元素在容器宽度不足时自动换行。
  • 能够使用 justify-content、align-items、align-content 分别完成主轴对齐、单行侧轴对齐和多行侧轴对齐。
  • 能够使用 align-self 单独控制指定子盒子的侧轴对齐方式,并使用 flex-direction: column 更改主轴方向实现垂直排列。
  • 能够使用 flex: n 为子盒子分配主轴方向的伸缩比例,并解释外边距对剩余空间分配的影响。
  • 能够按照“先大后小、先上后下”的布局思路,完成小米版心居中、左右分栏及右侧 8 个子项换行对齐的 Flex 布局案例。

知识点 ​

弹性盒子换行 ​

为什么需要:flex 默认让所有子项挤在同一行,即使子项写了固定宽度,父容器不够宽时也会被压缩。
怎么想:先给父容器 display:flex,观察子项是否都在一行;需要多行时再给父容器加 flex-wrap:wrap。
怎么做:属性是 flex-wrap,wrap 表示换行,nowrap 表示不换行(默认)。
易错点:换行属性写给父容器,不是写给子项。转写稿里的现象是:容器宽 1000px,8 个子项各 250px,默认一行显示时宽度被压成 125px;加 flex-wrap: wrap 后才按 4 个一行换行。

小米flex布局 ​

为什么需要:练习“父控子”的左右布局和右侧多行布局。
怎么想:先分大结构:.mi 里放 .left 和 .right;.right 里是 ul > li。让 .left、.right 一行显示,要找它们的亲爸爸 .mi 加 flex;让 li 一行显示并换行,要找 li 的亲爸爸 ul 加 flex 和换行。
怎么做:.mi 用 display:flex; justify-content:space-between;;.right ul 用 display:flex; flex-wrap:wrap; justify-content:space-between;;li 固定宽高并加 margin-bottom。
易错点:不要给 .right 直接加 flex 来控制 li,跨层级无效;控制谁,就给谁的最近一级父元素加 flex。

小米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;
    }

    .mi {
      /* 父控子 */
      display: flex;
      justify-content: space-between;
      width: 1226px;
      height: 614px;
      /* background-color: pink; */
      margin: 100px auto;
    }

    .left {
      width: 234px;
      height: 614px;
      background-color: skyblue;
    }

    .right {
      width: 978px;
      height: 614px;
      background-color: purple;
    }

    .right ul {
      display: flex;
      /* 让li 自动换行 */
      flex-wrap: wrap;
      /* 主轴两侧对齐 */
      justify-content: space-between;

    }

    .right li {
      width: 234px;
      height: 300px;
      background-color: orange;
      list-style: none;
      margin-bottom: 14px;
    }
  </style>
</head>

<body>
  <div class="mi">
    <div class="left"></div>
    <div class="right">
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
      </ul>
    </div>
  </div>
</body>

</html>

多行对齐方式 ​

为什么需要:主轴解决左右排列,侧轴还要解决上下排列;单行和多行的侧轴对齐不是同一个属性。
怎么想:单行侧轴用 align-items;出现换行、多行侧轴用 align-content。
怎么做:父容器设置 display:flex; flex-wrap:wrap;,多行时用 align-content: space-between; 等;父容器必须有高度,空隙才拉得开。
易错点:align-content 对单行无效;父容器没有高度时,容器被内容撑高,多行对齐看不出效果。转写稿调试时给 .box 设了 height:500px,align-content:space-between 才明显生效。

多行侧轴对齐示意

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 {
      display: flex;
      /* 换行 */
      flex-wrap: wrap;
      /* 主轴对齐 */
      justify-content: space-between;
      /* 侧轴单行控制 */
      /* align-items: center; */
      /* 侧轴多行对齐 */

      /* align-content: center; */
      align-content: space-between;
      width: 1000px;
      /* 亲父亲得有高度 */
      height: 500px;
      border: 3px solid #000;
      margin: 100px auto;
    }

    .box div {
      width: 300px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div>
</body>

</html>

多行对齐效果图

修改主轴方向 ​

为什么需要:只要父容器加了 display:flex,子项默认沿主轴横向排列;需要竖排时就要改主轴。
怎么想:不要死记 X 轴、Y 轴,要记“主轴、侧轴”。主轴默认水平,改成纵向后,justify-content 控制纵向,align-items 控制横向。
怎么做:父容器加 flex-direction: column;,再用 justify-content:center; align-items:center; 做水平垂直居中。
易错点:改主轴后仍按原来的 XY 方向理解会写反;column 是常用值,默认是 row。

主轴默认方向示意

修改主轴方向后的居中效果图

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 {
      display: flex;
      /* 默认主轴是横向 row  */
      /* 更改主轴的方向 我想要1和2盒子竖着排列 */
      flex-direction: column;
      width: 300px;
      height: 300px;
      border: 1px solid #000;
      /* 主轴 */
      justify-content: center;
      /* 侧轴 */
      align-items: center;

    }

    .box div {
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">
    <div>1</div>
    <div>2</div>
  </div>
</body>
   
  
  
   
  
</html>

弹性伸缩比 ​

为什么需要:做圣杯布局、比例分栏时,不必写死每个子项宽度,让子项按份数分配父级剩余空间。
怎么想:flex 写给子项,值表示占几份;有 margin 时先扣除外边距,再把剩余宽度按份数分。
怎么做:子项写 flex:1 表示各占一份;flex:2 表示占两份。父容器宽度可以是固定值或百分比。
易错点:flex 不写单位,只写整数;它控制主轴方向尺寸;父容器有 margin 时,转写稿的推导是“总宽先减去外边距,剩余空间再按份数分”,不是直接按总宽分。

弹性伸缩比效果图

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 {
      display: flex;
      width: 80%;
      height: 200px;
      border: 1px solid #000;
    }

    .box span {
      /* 不会区分原来属于什么模式 */
      /* width: 100px;
      height: 100px;
      background-color: pink; */
      flex: 1;
      background-color: pink;
    }

    /* 圣杯布局两侧固定,中间自适应 */
    .left,
    .right {
      width: 100px;
      background-color: skyblue;
    }

    .center {
      flex: 1;
      background-color: purple;
    }

    .center1 {
      flex: 2;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>

  <div class="box">
    <div class="left">左</div>
    <div class="center">中</div>
    <div class="center1">中</div>
    <div class="right">右</div>
  </div>
</body>

</html>

网站根目录:为什么需要 ​

网站不是只有一个 HTML 文件,还会包含 CSS、图片、JavaScript 等素材。根目录就是存放网站的第一层文件夹,里面包含当前网站的所有素材。它的意义在于:给所有资源一个统一的“起点”,写路径、找文件、引入样式都以此为准。转写稿里反复强调做页面要“先大后小、先上后下”,放到项目里也是同理:先确认根目录和素材位置,再写 HTML 结构,最后写样式,否则文件一多就容易找不到、路径写错。

网站根目录:怎么想 ​

把根目录想成整个网站的总入口:HTML 页面、CSS 文件夹、图片、JavaScript 都应能在它的内部找到。写 href、src 时,不要凭感觉写本地电脑上的绝对路径,而要从项目根目录和当前 HTML 文件的位置出发。转写稿中提到“单个盒子不能构成网页,需要多个盒子组成页面”,项目文件也是一样:不是只放一个 HTML 就结束,而是要把页面需要的素材组织在同一根目录体系内。图中展示的就是这种“第一层文件夹包含网站素材”的关系:

网站根目录示意图

网站根目录:怎么做 ​

先确认当前项目的第一层文件夹就是网站根目录,HTML、CSS、图片、JavaScript 等素材都放在它内部;具体子文件夹名以项目实际为准,笔记代码中可见 css 文件夹。写页面时先搭 HTML 结构,再在首页中按相对路径引入样式。调试时可以利用转写稿提到的“拆屏”习惯:一边看文件结构,一边看 HTML 里的引入路径,结构长时不容易看漏。

网站根目录:易错点 ​

常见错误是根目录外面又套一层文件夹,导致 ./css/... 找不到;或者把路径写成自己电脑上的绝对路径,换电脑就失效。转写稿里 flex 常被同音识别成“flash、fless、fex”,这提醒我们:文件名、文件夹名、link 属性都要按真实拼写写,不能凭读音猜。移动素材后也要回头检查路径是否仍然正确。

首页引入 CSS 文件:为什么需要 ​

首页通常要引入多个 CSS 文件。笔记中特别强调顺序要求:先清除再设置。因为 base.css 往往用于清除默认样式、打基础,index.css 用于设置当前页面样式;如果顺序反了,后面可能把前面的设置覆盖掉,页面效果就会和预期不一致。

首页引入 CSS 文件:怎么想 ​

link 标签在 HTML 中按从上到下的顺序加载和生效,后面的同名规则会覆盖前面的规则。所以先引入 base.css,再引入 index.css。转写稿里调试时强调看颜色、看波浪线、看结构,这里也一样:样式不对时,先检查 link 的路径和先后顺序,再怀疑具体 CSS 规则。

首页引入 CSS 文件:怎么做 ​

在首页中按下面顺序引入:

html
<!-- 顺序要求:先清除再设置 -->
<link rel="stylesheet" href="./css/base.css">
<link rel="stylesheet" href="./css/index.css">

rel="stylesheet" 表示引入样式表,href 写相对路径。先 base.css,后 index.css,保证“先清除默认样式,再设置页面样式”。

首页引入 CSS 文件:易错点 ​

不要把两个 link 顺序写反;不要漏写 rel="stylesheet";href 中的路径、文件名大小写要和实际文件一致。若样式没生效,先看文件树中是否存在 css/base.css、css/index.css,再看首页路径是否从当前 HTML 出发。转写稿中“版心”被识别成“版新”等同音误写,也说明属性名和路径必须按真实拼写检查,不能靠读音判断。

知识点一:为什么需要版心居中 ​

版心居中效果

为什么需要:网页内容如果直接贴着浏览器左右边缘,在大屏幕上会显得很散,阅读和排版都不稳定。实际页面通常需要一个“版心”区域,把主要内容限制在固定宽度内,并放在页面中间,两侧留白。

怎么想:先确定版心的宽度,再让这个盒子在水平方向居中。转写稿里也提到:页面中如果有版心盒子,一般情况下应该给宽度,因为“有了宽度才能居中”;高度不一定要给,可以让内容把它撑开,但需要时也可以直接给宽高。

怎么做:给版心盒子设置固定宽度,再用 margin: 0 auto; 让左右外边距自动分配剩余空间。

css
.wrapper {
  margin: 0 auto;
  width: 1200px;
}

易错点:只写 margin: 0 auto; 不写宽度,盒子作为块级元素默认可能占满父级宽度,左右没有剩余空间可分配,看起来就不会居中。所以版心居中的关键之一是先有明确宽度。

知识点二:margin: 0 auto 的推导 ​

为什么需要:版心有了固定宽度后,浏览器窗口比版心宽,左右会剩下空间。我们需要让这些剩余空间平均分到左右两边,盒子才会在视觉上居中。

怎么想:margin: 0 auto; 中,0 表示上下外边距为 0,auto 表示左右外边距自动计算。左右都为 auto 时,剩余空间被平均分配,版心就居中了。

怎么做:把版心盒子写成固定宽度加左右 auto:

css
.wrapper {
  margin: 0 auto;
  width: 1200px;
}

易错点:不要误以为所有大盒子都必须同时设置宽高。转写稿中解释过:所有盒子都可能被内容撑起来;版心盒子一般要给宽度,高度可以让内容撑开。大盒子里面套块级子盒子时,子盒子宽度默认和父亲一样宽,给不给宽都可能跟随父级,这一点要和版心盒子区分开。

知识点三:给页面加背景色 ​

为什么需要:版心居中后,版心两侧会露出页面背景。给 body 设置浅灰背景,可以让内容区域和页面底色有层次,避免整页纯白显得没有边界。

怎么想:背景色一般加在 body 上,让整个页面铺底色;版心盒子负责承载主要内容。这样版心宽度和页面背景互不干扰。

怎么做:

css
body {
  background-color: #f3f5f7;
}

易错点:不要把页面背景色和版心宽度混在一个盒子里理解。版心负责“内容区域有多宽、是否居中”,body 负责“整页底色是什么”。调试时先确认版心有没有宽度、margin: 0 auto 是否写对,再看背景色是否生效。

先整体再局部:布局不是一上来就写样式 ​

为什么需要:做案例时“脑子一片空白”,往往不是属性不会,而是没有先分析结构。网页不是单个盒子,而是多个盒子套在一起。

怎么想:先大后小、先上后下、从左到右。先看大盒子里面套了上下还是左右,再看每个区域里面又分几块。比如小米案例,先确定 .mi 是大盒子,里面分 .left 和 .right;右侧再放一个 ul,里面装 8 个 li。

怎么做:先把结构分出来,再按“画盒子 → 调位置 → 调内容样式”的顺序写。转写稿里反复强调:先知道谁套谁,再想宽高、背景色、flex、内外边距。

易错点:不要一上来就纠结 margin、padding 写多少;结构没分清楚,越调越乱。调试时可以点开编辑器的“拆屏”,一边看 HTML 结构,一边改 CSS,避免样式太长看串行。

画盒子:先用宽高和背景色把范围显出来 ​

为什么需要:盒子看不见,位置就很难调。先把大盒子“画”出来,才能判断左右宽度、上下高度对不对。

怎么想:版心大盒子一般先给宽度,高度可以给,也可以让内容撑开;块级子盒子宽度默认和父级一样,很多时候可以不写宽,高度多数情况要给。转写稿里的结论是:大部分情况直接给宽高最稳,特殊简约写法再省略。

怎么做:小米案例中,.mi 宽 1226、高 614;左侧宽 234,右侧宽 978;右侧小 li 宽 234、高 300。先给背景色,把盒子范围显出来,再往下调。

易错点:不要因为“能不能不写宽高”卡住。版心通常要有宽度才能居中;大盒子套上下子盒子时,块级子盒子宽度可不写,但高度常要给。先让盒子出来,再优化。

调位置:flex 解决“多个块级元素在一行” ​

为什么需要:标准流里块级元素上下排,但网页经常要求一行显示多个盒子,所以需要布局。转写稿反馈里问“什么时候用浮动、什么时候用 flex”:浮动是较早的布局方式,现在用得少,主流用 flex,实在需要才考虑浮动。

怎么想:一看到“多个块级盒子要在一行”,就想到 flex。关键是找“亲爸爸”:想让谁一行,就给它们最近一级父级加 display: flex。

怎么做:让 .left 和 .right 一行,给 .mi 加 flex;让 8 个 li 一行,给 .right 里的 ul 加 flex。

css
.mi {
  display: flex;
  justify-content: space-between;
}
.right ul {
  display: flex;
}

易错点:flex 是父控子,必须找最近一级父级,不能跨层级;版心本身不用 flex。justify-content: space-between 表示主轴两侧没缝隙、中间分开,常用于左右贴边。

换行与多行对齐:flex-wrap、align-content ​

为什么需要:8 个 li 直接 flex 会全挤在一行,宽度被压缩,原来 250 的宽度可能变成 125。flex 默认不换行。

怎么想:要让一行放 4 个、8 个分两行,就给父级 ul 加换行。垂直方向单行用 align-items,多行用 align-content。

怎么做:

css
.right ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  height: 614px;
  align-content: space-between;
}

易错点:align-items 只适合单行,多行时常常无效;align-content 控制多行侧轴,但父级必须有高度,否则没有空间拉开。临时也可以用 margin-bottom 把行挤开,但多行对齐更推荐 align-content。

单独控制和改主轴:align-self、flex-direction ​

为什么需要:只想移动某一个子盒子时,align-items 会让所有盒子一起动;想让盒子竖着排列时,默认 flex 又是横排。

怎么想:只动一个子盒子,用 align-self,并且写给子盒子;要竖排居中,就改主轴方向,不要记死 X 轴、Y 轴,要记主轴和侧轴。

怎么做:

css
.box div:nth-child(2) {
  align-self: center;
}
.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

易错点:align-self 写到父级无效;改主轴后,justify-content 管的是新的主轴,align-items 管新的侧轴。主轴改了,侧轴自然跟着变。

伸缩比:flex:份数 ​

为什么需要:几个盒子平均分或按比例分宽度时,手算百分比容易除不尽。flex: 1 表示占一份。

怎么做:三个子盒子各写 flex: 1,就是各占一份;第二个写 flex: 2,它占两份,另外两个各一份。若有 margin,先扣除外边距,再把剩余宽度按份数分。

css
.box div { flex: 1; }
.box div:nth-child(2) { flex: 2; }

易错点:flex 写给子盒子,值是无单位整数;有间距时不是把盒子撑大,而是先减掉间距再分剩余空间。整体调试顺序仍是:结构 → 盒子范围 → flex 位置 → 图片文字样式。

课件图示 ​

课件第19页:1. 布局思路:先整体再局部,从外到内,从上到下,从左到右 2. CSS 实现思

课件第30页:精品推荐(recommend) 实现方法: • 标签结构:.recommend

课件第14页:网站根目录是指存放网站的第一层文件夹,内部包含当前网站的所有素材,包含 HTML

课件第15页:总结 总结 1. 项目目录中,images 文件夹存放什么? 固定使用的图片素材

课件第21页:header 区域-布局 通栏:宽度与浏览器窗口相同的盒子 标签结构:通栏 >

课件第23页:导航制作技巧(nav) 导航功能 • 单击跳转页面 实现方法: • 标签结构:u

课件第27页:banner 区域 – 布局 结构:通栏banner > 版心 > .left

课件第28页:左侧侧导航(left) 实现方法: • 标签结构:.left > ul > li

代码示例 ​

示例一:小米 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;
    }

    .mi {
      /* 父控子 */
      display: flex;
      justify-content: space-between;
      width: 1226px;
      height: 614px;
      /* background-color: pink; */
      margin: 100px auto;
    }

    .left {
      width: 234px;
      height: 614px;
      background-color: skyblue;
    }

    .right {
      width: 978px;
      height: 614px;
      background-color: purple;
    }

    .right ul {
      display: flex;
      /* 让li 自动换行 */
      flex-wrap: wrap;
      /* 主轴两侧对齐 */
      justify-content: space-between;

    }

    .right li {
      width: 234px;
      height: 300px;
      background-color: orange;
      list-style: none;
      margin-bottom: 14px;
    }
  </style>
</head>

<body>
  <div class="mi">
    <div class="left"></div>
    <div class="right">
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
      </ul>
    </div>
  </div>
</body>

</html>

关键行与易错点

  • display: flex 写在 .mi 上:flex 是“父控子”,必须找亲爸爸。想让 .left 和 .right 一行显示,就加在 .mi 上。
  • justify-content: space-between 让左右两个盒子分贴两边,中间自动留缝,不用写 margin-right 硬挤。
  • flex-wrap: wrap 写在 .right ul 上:想让 8 个 li 一行排,就得控制 li 的最近一级父亲是 ul,写成 .right 是无效的(跨层级控制不了)。
  • 不写 flex-wrap 时默认是 nowrap,8 个 li 会全挤在一行,宽度 234 被压缩变窄——这是新手最常见的现象。
  • 234 × 4 = 936 < 978,所以一行正好放 4 个,共两行;li 的 margin-bottom: 14px 用来挤开上下两行(也可给 ul 高度后用 align-content: space-between)。
  • * { margin: 0; padding: 0; } 必写,否则 ul 有默认内边距,盒子对不齐;list-style: none 去掉小圆点。

示例二:多行侧轴对齐(align-content) ​

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 {
      display: flex;
      /* 换行 */
      flex-wrap: wrap;
      /* 主轴对齐 */
      justify-content: space-between;
      /* 侧轴单行控制 */
      /* align-items: center; */
      /* 侧轴多行对齐 */

      /* align-content: center; */
      align-content: space-between;
      width: 1000px;
      /* 亲父亲得有高度 */
      height: 500px;
      border: 3px solid #000;
      margin: 100px auto;
    }

    .box div {
      width: 300px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div>
</body>

</html>

关键行与易错点

  • align-content 是侧轴、多行的对齐方式,取值和主轴很像:flex-start / flex-end / center / space-between / space-around。
  • 口诀:单行侧轴找 align-items,多行侧轴找 align-content。对单行弹性盒子写 align-content 是无效的。
  • align-content: space-between 让两行分别贴上边和下边,中间留出空隙,省掉给每个子盒子写 margin-bottom。
  • 父级 .box 必须有高度(这里 500px)。不写高度时盒子被内容撑开,高度 = 两行 200 + 200,根本没有多余空间可以“分缝”,效果看不出来。
  • 注意不要记成“X 轴 / Y 轴”,要记“主轴 / 侧轴”,轴是会被 flex-direction 改的。

示例三:弹性伸缩比 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>
    .box {
      display: flex;
      width: 80%;
      height: 200px;
      border: 1px solid #000;
    }

    .box span {
      /* 不会区分原来属于什么模式 */
      /* width: 100px;
      height: 100px;
      background-color: pink; */
      flex: 1;
      background-color: pink;
    }

    /* 圣杯布局两侧固定,中间自适应 */
    .left,
    .right {
      width: 100px;
      background-color: skyblue;
    }

    .center {
      flex: 1;
      background-color: purple;
    }

    .center1 {
      flex: 2;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>

  <div class="box">
    <div class="left">左</div>
    <div class="center">中</div>
    <div class="center1">中</div>
    <div class="right">右</div>
  </div>
</body>

</html>

关键行与易错点

  • flex 写在子盒子上(和 align-self 一样是给子盒子的属性),其余如 justify-content、align-items、align-content、flex-wrap、flex-direction 都是给父盒子的。
  • flex: 1 表示占父级剩余尺寸的份数,四个 span 各占一份 → 四等分,宽度会随父级 80% 宽度自动缩放,这就是“弹性”。
  • 第二组:左右固定 width: 100px,剩余宽度按 center : center1 = 1 : 2 分配,中间两块不等宽,用来做“两侧固定、中间自适应”。
  • 值必须是整数、不带单位(flex: 1,不能写 flex: 1px);写小数、写单位都是错的。
  • 有 margin 时,先扣掉所有外边距,剩下的宽度再按份数分。例如总宽 100px、左右各 10px 边距 → 先减 20 剩 80,再按 1:2:1 分成 20 / 40 / 20。
  • 子盒子不写高度时默认被拉伸(stretch)与父级等高,这是弹性盒子的便利之处;一旦手动给了高度就按自己的高度显示。

常见错误 ​

#现象原因修法
18 个 234×300 的卡片全挤在一行,宽度被压成 125pxflex 默认 flex-wrap: nowrap,子项只挤不换行给直接父级(这里是 ul)加 flex-wrap: wrap
2align-content: space-between 写了但毫无反应①子项还在单行;②父容器没有高度,容器高度=内容高度,没有"余量"可分配先 flex-wrap: wrap 制造多行,再给父容器显式高度
3想控制两行卡片的上下对齐,用 align-items 怎么调都不对align-items 只对单行有效,多行要找 align-content多行改用 align-content: flex-start / center / space-between
4加了 flex-direction: column 后,justify-content 变成了上下移动、align-items 变成了左右移动,全乱套仍按"X 轴 / Y 轴"记忆,而两个属性是跟着主轴 / 侧轴走的,轴一转方向就互换只记"justify-content 管主轴、align-items 管侧轴",写之前先确认当前主轴方向
5ul 里 8 个 li 怎么都不换行,display: flex 写在了 .right 上flex 只控制最近一级子元素,.right 的直接子元素是 ul,不是 lidisplay: flex 写到 ul 上(亲父级),不能跨层级
6子盒子写了 flex: 1 却没有等分效果①父级没写 display: flex,子项不是 flex item;②把 flex 写到了父容器身上display: flex 给父级,flex: n 给子元素
7三列 flex: 1 / 2 / 1 加了 margin: 0 10px 后,总宽超出父容器、出现横向溢出flex 分配的是扣掉 margin 之后的剩余空间,很多人误以为总宽不变无溢出问题:理解"先减间距再分份";确实需要严格控制时改用 gap 或 box-sizing + 内边距
8.wrapper { margin: 0 auto; } 版心不居中没给宽度,块元素默认撑满父级,没有"可居中的余量"必须同时给 width(如 1200px)
9页面基础样式被自己写的样式覆盖掉,重置失效<link> 引入顺序反了先 base.css 后 index.css

练习 ​

1. 卡片墙换行 容器宽 978px、高 614px,内部 8 张 234×300 的卡片,要求两行四列、左右两端对齐、行间距 14px。用最少属性完成,并说明为什么不能靠 margin-right 硬挤。

2. 三栏自适应 一行三块:左 100px、右 100px、中间自适应。要求拖动浏览器窗口时中间跟着缩放,左右不变。

3. 盒子居中(两种写法) 一个 300×300 的容器里放 2 个 100×100 的方块,要求竖着排列且整体水平垂直居中。分别用「改主轴」和「不改主轴」两种思路实现,并对比各自需要几条属性。

4. 多行上下对齐 把第 1 题改成:不用 margin-bottom,让第一行贴顶、第二行贴底。写出完整代码,并回答"如果去掉容器高度会发生什么"。

5. 单独移动一个子项 一行 3 个方块,前两个顶部对齐,只有第 3 个沉到底部。写出选择器和属性,并说明为什么这里不能用 align-items。

原视频对照 ​

#视频时长
1反馈复习和内容13:42
2flex自动换行06:02
3flex小米版本布局11:24
4flex小米版本布局结束06:35
5多行主轴对齐14:29
6align-self单独控制某个子盒子06:01
7更改主轴方向13:00
8伸缩比09:54

小结 ​

  1. flex 只认亲爹:display: flex 写在直接父级上,隔一层就完全无效——小米案例里 8 个 li 换行失败,几乎全是把 flex 写给了 .right 而不是 ul。
  2. 默认不换行是 flex 的"特性"而非"bug":nowrap 下子项会被挤压变形,只要出现"多个块挤在一行被压扁",第一反应就是补 flex-wrap: wrap。
  3. 单行找 align-items,多行找 align-content,这是两个不同的开关,写错了一个属性都不会报错、但完全不生效,排查成本极高。
  4. align-content 生效有两个前提:真的换行成了多行 + 父容器有明确高度。缺任意一个,属性写了等于没写。
  5. 不要记 X 轴 / Y 轴,只记主轴 / 侧轴。flex-direction: column 之后 justify-content 就管上下、align-items 就管左右,"水平垂直居中"的最短路径往往就是先扭轴。
  6. flex: n 分配的是扣掉 margin 之后的剩余空间,它天然带弹性(父容器变窄,子项等比缩小),所以圣杯布局"两侧固定、中间自适应"用 flex: 1 比算百分比稳得多。
  7. 布局顺序永远是先大后小、先外后内:先画盒子定宽高背景,再摆位置(flex + 内外边距),最后调内容样式——卡壳时多半是跳过第一步直接写细节了。
  8. 浮动是历史遗留,flex 是当前主力;只有在 flex 确实不适用的场景才考虑浮动,学习阶段不必纠结二者取舍。