Skip to content

多列布局与伸缩盒布局 Flex(Day15 2/3) ​

本页对应 Day15_CSS3,共 7 段视频,约 1 小时 31 分。

学习目标 ​

  • 能使用 column-count、column-width、columns、column-gap、column-rule 等属性创建多列布局,并解释 column-count 与 column-width 冲突时的分列结果。
  • 能实现多列图片布局,正确设置图片宽度、box-sizing、列间距和底部间距,并说明多列容器内子元素百分比宽度参照所在列。
  • 能识别伸缩容器与伸缩项目,使用 display: flex 或 display: inline-flex 创建伸缩容器,并说明只有直接子元素会成为伸缩项目。
  • 能通过 flex-direction 设置主轴方向、通过 flex-wrap 设置换行方式,并使用 flex-flow 同时设置二者。
  • 能使用 justify-content 的六个值调整伸缩项目在主轴上的对齐方式,并说明不同主轴方向下起点与终点的变化。
  • 能区分单行与多行场景,使用 align-items 设置侧轴对齐、使用 align-content 设置多行行间对齐,并解释 stretch 的拉伸效果及换行后 align-items 的局限。

知识点 ​

回顾清单与使用方式 ​

本节是回顾课,先把清单原样保留,再按“变形—过渡—动画”三条线串起来。需要说明:转写稿讲的是多列布局、多列图片和伸缩盒布局,与本节笔记的 transform / transition / animation 不是同一主题;若把 flex 内容硬塞进本节会造成串章,因此下面严格按笔记回顾展开,不编造转写稿中没有的推导。

css
1. tranform 变换(变形)
   1.2 变换方法
       2D变换:translateX() translateY() translate() scaleX() scaleY() scale() rotate()
       3D变换:translateZ() translate3D() rotateX() rotateY() rotateZ() rotate3D()
   1.3 css属性
       需要给变换的元素: transform、transform-origin、backface-visibility
       需要给变换的元素的父元素:transform-style、perspective、perspective-origin

2. transition 过渡
   transition-duration
   transition-delay
   trnasition-property
   trnasition-timing-funciton
   transition
  
3. animation 动画
   3.1 关键帧
   3.2 css属性
       animation-name
       animation-duration
       animation-delay
       animatino-timing-function
       animation-iteration-count
       animation-direction
       animation-play-state
       animation-fill-mode
       animation

清单里个别拼写按原笔记保留,正文以正确属性名为准。为什么需要回顾?因为这三组属性名字相近、归属不同,初学最容易把 transform 当过渡、把 transition 当动画、把 3D 属性加错元素。怎么想?先问“我要一次变形、两次状态间过渡,还是多关键帧动画”,再选组。怎么做?先记归属:变换方法写在 transform 的值里;过渡四属性写在触发状态变化的元素上;动画先写关键帧,再在元素上挂 animation-*。易错点:拼写错误如 tranform、trnasition 会让整条声明失效;不要只看清单,要能在开发者工具里看到属性被划掉时判断是拼写还是优先级问题。

transform 变换:先分清方法和属性 ​

为什么需要?因为有些视觉效果(位移、缩放、旋转)不希望改变文档流,用 transform 比改 left/top/width/height 更直接。怎么想?把“方法”和“属性”分开:translateX()、scale()、rotate() 等是函数,写在 transform 的值里;transform-origin 控制变换原点;backface-visibility 控制 3D 翻转时背面是否可见。父元素则负责 3D 舞台:transform-style: preserve-3d 让子元素保留 3D 空间,perspective 和 perspective-origin 控制透视距离与视点。怎么做?2D 先练 translate()、scale()、rotate();3D 先给父元素加 perspective,再给子元素写 translateZ() 或 rotateX()。易错点:transform 不是过渡属性,它只描述“变成什么样”;3D 效果常因 perspective 加在子元素而不是父元素而失效;transform-origin 改变后,旋转和缩放的中心会变,调试时先恢复默认 50% 50% 对照。

transition 过渡:四个子属性与简写 ​

为什么需要?因为状态切换如果瞬间完成会很生硬,过渡让属性变化在时间内平滑发生。怎么想?只记四件事:持续多久 duration、延迟多久 delay、过渡哪些属性 property、用什么速度曲线 timing-function。怎么做?先写单项:transition-property: transform; transition-duration: .3s; transition-timing-function: ease; transition-delay: 0s; 再合并简写 transition: transform .3s ease 0s;。易错点:transition-property 默认是 all,但显式写 all 容易把不必要属性也过渡;简写顺序中第一个时间是 duration,第二个才是 delay;display: none 到 display: block 通常不产生过渡,因为元素不在渲染树中;属性拼写错一个字母,整条过渡不生效。

animation 动画:关键帧与属性 ​

为什么需要?过渡只能从 A 到 B,动画可以定义多个关键帧并循环、反向、暂停。怎么想?先写 @keyframes 名字 { from {...} to {...} } 或百分比关键帧,再把动画挂到元素上。怎么做?按清单记:animation-name 对应关键帧名;animation-duration 时长;animation-delay 延迟;animation-timing-function 速度曲线;animation-iteration-count 次数,常用 infinite;animation-direction 方向;animation-play-state 播放/暂停;animation-fill-mode 前后状态保留;最后用 animation 简写。易错点:关键帧名和 animation-name 不一致动画不跑;简写中两个时间同样先 duration 后 delay;fill-mode 不写时动画结束后可能回到初始状态;循环动画要检查 iteration-count 是否写成数字而不是关键字。

收束:回顾检查表 ​

最后用检查表收束:看到位移缩放旋转,先找 transform;看到状态切换平滑,先找 transition 四属性;看到多关键帧和循环,先找 @keyframes 与 animation-*。调试时先看拼写,再看属性加在“变换元素”还是“父元素”,最后看简写是否覆盖了子属性。本节无图片可保留;代码清单已按原笔记保留,正文中的正确拼写用于实际书写。

多列布局解决什么问题 ​

为什么需要:报纸式排版要求文字连续地从第一列流到第二列、第三列;如果用三个浮动元素硬分,就得手动数字数、分段落,字号一变就很难均分,还会出现高度不齐、卡住等问题。
怎么想:把“分列”交给浏览器,让内容在列之间自动流动,而不是自己拆成多个元素。
怎么做:给包裹元素设置多列属性,子元素仍按正常结构书写。转写稿先写一个 wrapper,设宽度、外边距、内边距和边框,看到内容把高度撑开;再加 column-count:3,段落会被“拦腰”分到不同列。
易错点:多列布局不是把每个段落单独放进一列,而是让整块内容按列流动;不要用浮动模拟连续分列。

css
.wrapper {
  width: 1000px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #ccc;
  column-count: 3;
}

包裹元素:先定列数与列宽 ​

为什么需要:列数和列宽决定分列结果。
怎么想:column-count 直接指定列数;column-width 指定理想列宽,由浏览器按可用空间折算列数;columns 是复合属性。
怎么做:笔记中的 8 个包裹元素属性如下:

CSS 属性名含义值
column-count列数数字
column-width列宽长度
columns同时设置列数和列宽空格分隔两个值
column-gap列间距长度
column-rule-style列分隔线风格同 border-style
column-rule-color列分隔线颜色颜色
column-rule-width列分隔线宽度长度
column-rule列分隔线复合属性空格分隔值

转写稿调试:总宽 1000、column-width:200 时,考虑列间距后实际分成 4 列,每列会略大于 200;同时写 column-count:3 和 column-width:200,结果按 3 列;再写 column-count:5 和 column-width:200,结果仍是 4 列。结论是:哪个属性分出来的列数少,就按哪一个。
易错点:两者同时设置没有优先级高低,实际开发没必要一起写;一般只设 column-count 更直观。

css
.wrapper { column-count: 3; }
.wrapper { column-width: 200px; }
.wrapper { columns: 3 200px; } /* 了解即可 */

列间距与列分隔线 ​

为什么需要:列与列之间需要呼吸感,报纸式排版还常要一条分隔线。
怎么想:column-gap 管间距;column-rule-* 管线,线的风格值同 border-style。
怎么做:转写稿把 column-gap 改成 0,列会挨在一起;再设 20px 恢复间距。列分隔线可写 column-rule: 1px dashed #c1c1c1;。
易错点:列分隔线不是普通边框,不要写到子元素上;间距设 0 时,文字因剩余空间不足仍可能看起来有空隙。

css
.wrapper {
  column-gap: 20px;
  column-rule: 1px dashed #c1c1c1;
}

子元素跨列与断列 ​

为什么需要:标题常需要横跨所有列;某些段落或图片不希望被从中间断开。
怎么想:跨列用 column-span;断列用带 -webkit- 前缀的 column-break-*,作了解。
怎么做:笔记中的 4 个子元素属性:

CSS 属性名含义值
column-span跨列none 默认;all 跨所有列
-webkit-column-break-before元素前面是否断列auto/always/avoid
-webkit-column-break-after元素后面是否断列auto/always/avoid
-webkit-column-break-inside元素内部是否断列auto/avoid

转写稿演示:给 h2 设 column-span:all,标题横跨所有列;不能只跨两列,只能不跨或跨所有列。给第 5 个 p 设 -webkit-column-break-inside:avoid,可让该段内部不断开。
易错点:断列属性需要私有前缀,主要作了解;break-inside 没有 always,因为“内部必须断”无法确定断在哪里。

css
.wrapper h2 { column-span: all; }
.wrapper p:nth-of-type(5) {
  -webkit-column-break-inside: avoid;
}

多列图片实战 ​

为什么需要:图片宽度相同、高度不同,用浮动或定位会出现底部对齐、缝隙、卡住;多列布局更稳。
怎么想:把包裹元素设成多列,图片宽度设 100%,让每列自然排图。
怎么做:转写稿设 column-count:5、column-gap:20px,图片 width:100%、加白色边框、box-sizing:border-box、margin-bottom:20px,包裹元素加灰底。图片数量要打乱,避免刚好对齐显得太整齐。
易错点:多列结构中子元素百分比宽度参照的是所在列,不是包裹元素;加边框不设 box-sizing 会把图片撑大;图片一般保持完整,不被从中间断开。

css
.wrapper {
  column-count: 5;
  column-gap: 20px;
  background: #ccc;
}
.wrapper img {
  width: 100%;
  box-sizing: border-box;
  border: 10px solid #fff;
  margin-bottom: 20px;
}

易错点小结 ​

多列属性大多写给包裹元素;column-span 和断列属性写给子元素。column-count 与 column-width 同时设置时按“分列少”的结果走,实际只设列数即可。列分隔线用 column-rule,不要和 border 混淆。多列图片中百分比宽度参照列宽,加边框记得 box-sizing:border-box。断列属性带 -webkit- 前缀,主要作了解,默认 auto 通常就够用。

伸缩容器与伸缩项目:先把身份分清 ​

为什么需要:浮动能排一行,但会脱离文档流,还要清浮动;行内块又容易被父元素当文字处理。伸缩盒布局(Flex)就是为“专门做布局”准备的,新页面、移动端页面优先用它,维护旧项目再考虑浮动。

怎么想:先别背属性,先认身份。给一个元素设 display:flex 或 display:inline-flex,它就成了伸缩容器;它的子元素才是伸缩项目。注意是子元素,不是所有后代。一个元素可以同时是“别人的伸缩项目”和“自己子元素的伸缩容器”。

怎么做:

html
<div class="wrapper">
  <div class="item item01">item01</div>
  <div class="item item02">item02</div>
  <div class="item item03">item03</div>
</div>
css
.wrapper{
  width: 1000px;
  margin: 20px auto;
  background: #ccc;
  display: flex;
}
.item{
  width: 220px;
  height: 100px;
  box-sizing: border-box;
}
.item01{ background:#900; }
.item02{ background:#009; }
.item03{ background:#090; }

易错点:display:flex 要设给容器,不是设给项目;项目会水平排列,但严格说是“沿主轴排列”。伸缩项目不脱离文档流,能撑开父元素高度;它也不会像行内块那样被父元素当文字。

主轴与侧轴:所有对齐都别想“横竖” ​

为什么需要:Flex 的属性名很多,如果只记“水平居中、垂直居中”,一改方向就乱。转写稿反复强调:主轴是项目排列的轴,侧轴与主轴垂直;主轴是核心,侧轴跟着主轴走。

怎么想:默认主轴从左到右,所以项目横向排;此时侧轴是竖向。若把主轴改成纵向,侧轴就变横向。所以 justify-content 管主轴对齐,align-items/align-content 管侧轴对齐,不要死记“水平/垂直”。

怎么做:用 flex-direction 改主轴方向,值有 row(默认,左到右)、row-reverse(右到左)、column(上到下)、column-reverse(下到上)。属性设给伸缩容器。

css
.wrapper{
  display:flex;
  flex-direction: row-reverse;
}

易错点:flex-direction 不是设给项目的;主轴反向不会改变项目顺序语义,只是排列方向变了。

换行方式:默认不换行,会压缩项目 ​

为什么需要:浮动一行放不下会自动换行,Flex 默认不是。转写稿调试:容器 1000px,项目宽 220px,放 5 个、6 个时,预期换行,结果全挤在一行;检查元素发现项目宽度被压到约 166px。这就是“伸缩”的默认行为。

怎么想:flex-wrap 默认 nowrap,宁可压缩也不换行;要像浮动那样换行,设 wrap。还有 wrap-reverse,换行并上下翻转,用得少。

怎么做:

css
.wrapper{
  display:flex;
  flex-wrap: wrap; /* 一行放不下就换行 */
}

复合属性 flex-flow 可同时写方向和换行:

css
.wrapper{
  flex-flow: row wrap;
}

易错点:不设 wrap 时别怪项目变窄;flex-flow 是 flex-direction 和 flex-wrap 的复合属性,只写一个值时另一个会回到默认值。

主轴对齐:justify-content 的 6 个值 ​

为什么需要:一排项目要靠左、靠右、居中、两端对齐、均匀分布,靠浮动和 margin 很麻烦;Flex 一个属性解决。

怎么想:它设给伸缩容器,控制项目在主轴上的对齐。默认 flex-start 是主轴起点;flex-end 是主轴终点;center 居中;space-between 两端无间距、中间有间距;space-around 两端间距是中间间距一半;space-evenly 两端与中间间距相等。

怎么做:

css
.wrapper{
  display:flex;
  justify-content: space-between;
}

易错点:justify-content:center 不是 flex-center;它管主轴,主轴改成纵向后就不是“水平居中”了。

侧轴对齐:单行用 align-items,多行用 align-content ​

为什么需要:项目在侧轴上也要对齐。转写稿强调:不换行时只有一条主轴线,用 align-items;换行后有多条主轴线,align-items 虽有效果但不理想,应使用 align-content 控制行与行之间怎么排。

怎么想:align-items 默认 stretch,项目没设侧轴长度时会被拉伸到容器侧轴长度;设了高度就看不到拉伸。值还有 flex-start、flex-end、center、baseline。换行后默认 stretch 会让两行各占一半,所以中间隔开;想让行挨着,用 align-content:flex-start,它也有 flex-end、center、space-between、space-around、space-evenly。

怎么做:

css
.wrapper{
  display:flex;
  flex-wrap: wrap;
  height: 400px;
  align-items: center;      /* 单行侧轴对齐 */
  align-content: flex-start;/* 多行时行与行靠上 */
}

易错点:align-content 只在多行(发生换行)时明显生效;单行不要拿它当 align-items 用。align-items:stretch 的前提是项目没设侧轴对应长度,别把“高度”说死,主轴一改,侧轴对应长度可能是宽度。

课堂画面 ​

课堂画面 1

课堂画面 2

课堂画面 3

课堂画面 4

课堂画面 5

课堂画面 6

代码示例 ​

示例一:多列布局(报纸式排版) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>多列布局</title>
<style>
    * { margin: 0; padding: 0; }
    .wrapper {
        width: 1000px;
        margin: 20px auto;
        padding: 20px;
        border: 1px solid #ccc;
        /* ① 分列:指定列数 */
        column-count: 3;
        /* column-width: 200px;  指定列宽,与列数冲突时"谁分出的列少听谁的" */
        /* ② 列间距 */
        column-gap: 20px;
        /* ③ 列分隔线(复合属性) */
        column-rule: 1px dashed #f00;
    }
    .wrapper h2 {
        padding: 20px 0;
        margin-top: 0;
        background: #ccc;
        text-align: center;
        /* ④ 跨列:只有 none / all 两个值 */
        column-span: all;
    }
    .wrapper p { text-indent: 2em; }
    .wrapper img {
        /* 多列容器内,百分比参照"所在列宽",不是 wrapper 宽度 */
        width: 100%;
        display: block;
    }
</style>
</head>
<body>
<div class="wrapper">
    <h2>如何一夜暴富</h2>
    <p>短一点的段落文字。</p>
    <p>长一点的段落文字,这里写很多很多字,多到可以跨越多列,甚至被拦腰截断到下一列去,这就是多列布局最厉害的地方,用三个浮动元素是绝对做不到的。</p>
    <img src="./images/db01.jpg" alt="">
    <p>再来一段很长的文字,同样会被拆到不同的列中显示。</p>
</div>
</body>
</html>

关键行与易错点

  • column-count / column-width / columns 都是**设置给包裹元素(多列容器)**的,写错位置无效。
  • 同时写列数和列宽时没有优先级,哪个分出来的列数少就按哪个,实际开发中只设 column-count 即可。
  • column-rule 的默认值跟边框一样:medium none,颜色取 color(文字颜色),不是黑色。
  • column-span 只有 none(默认,不跨列)和 all(跨所有列),**没有"跨 2 列"**这种值。
  • 图片、段落这类元素会被拦腰断开,图片默认保证完整;想让某个段落不断开,可用 -webkit-column-break-inside: avoid(需私有前缀,仅 Chrome 系有效,了解即可)。

示例二:伸缩容器与伸缩项目(主轴方向 + 换行 + 主轴对齐) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>伸缩盒布局</title>
<style>
    .wrapper {
        width: 1000px;
        height: 400px;
        margin: 20px auto;
        padding: 20px;
        box-sizing: border-box;
        background: #ccc;

        display: flex;              /* 设为伸缩容器,子元素成为伸缩项目 */
        flex-direction: row;        /* 主轴方向:从左到右(默认) */
        flex-wrap: wrap;            /* 换行方式:一行放不下就换行(默认 nowrap 会压缩) */
        justify-content: space-between; /* 伸缩项目在主轴上的对齐方式 */
    }
    .item {
        width: 220px;
        height: 100px;
        box-sizing: border-box;
        padding: 10px;
        color: #fff;
    }
    .item01 { background: #900; }
    .item02 { background: #009; }
    .item03 { background: #090; }
    .item04 { background: #099; }
    .item05 { background: #990; }
    .item06 { background: #909; }
</style>
</head>
<body>
<div class="wrapper">
    <div class="item item01">item01</div>
    <div class="item item02">item02</div>
    <div class="item item03">item03</div>
    <div class="item item04">item04</div>
    <div class="item item05">item05</div>
    <div class="item item06">item06</div>
</div>
</body>
</html>

关键行与易错点

  • 只有 display: flex(块级伸缩容器)或 display: inline-flex(行内伸缩容器)才成为伸缩容器;只有它的子元素才是伸缩项目,后代(孙子元素)不算。
  • 一个元素可以同时是"伸缩项目"和"伸缩容器":它是父元素的子元素时是项目,它自己设了 display: flex 时又是容器。
  • flex-direction 有 4 个值:row(默认,左→右)、row-reverse(右→左)、column(上→下)、column-reverse(下→上)。它必须写在伸缩容器上,写在项目上无效。
  • flex-wrap 默认是 nowrap:一行放不下时不会换行,而是把项目压扁(220px 被压成 166px)。想替代浮动、做商品列表,必须写 wrap。
  • justify-content 共 6 个值:flex-start(默认,主轴起点)、flex-end、center、space-between(两端对齐,中间有缝)、space-around(两端间距是中间间距的一半)、space-evenly(两端与中间间距相等)。
  • flex-flow 是 flex-direction + flex-wrap 的复合属性,实际开发中多数人仍分开写。

示例三:侧轴对齐(align-items / align-content) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>侧轴对齐</title>
<style>
    .wrapper {
        width: 1000px;
        height: 400px;              /* 侧轴方向必须有长度,否则看不出对齐效果 */
        margin: 20px auto;
        padding: 20px;
        box-sizing: border-box;
        background: #ccc;

        display: flex;
        flex-wrap: wrap;            /* 换行 → 出现多条主轴线 */

        align-items: center;        /* 侧轴对齐:单行、多行都有效 */
        align-content: space-around;/* 行与行之间的对齐:只在多行时有效 */
    }
    .item {
        width: 220px;
        height: 100px;              /* 写了高度,就看不到 stretch 的拉伸效果 */
        box-sizing: border-box;
        padding: 10px;
        color: #fff;
    }
    .item01 { background: #900; }
    .item02 { background: #009; }
    .item03 { background: #090; }
    .item04 { background: #099; }
    .item05 { background: #990; }
    .item06 { background: #909; }
</style>
</head>
<body>
<div class="wrapper">
    <div class="item item01">item01</div>
    <div class="item item02">item02</div>
    <div class="item item03">item03</div>
    <div class="item item04">item04</div>
    <div class="item item05">item05</div>
    <div class="item item06">item06</div>
</div>
</body>
</html>

关键行与易错点

  • 侧轴是与主轴垂直的那根轴:主轴横着,侧轴就竖着(此时侧轴方向对应的长度是 height);主轴竖着,侧轴就横着(对应 width)。
  • align-items 默认值是 stretch(拉伸):前提是伸缩项目没有设置侧轴方向的长度,一旦写了 height,拉伸效果就看不出来了。
  • 换行后会出现多条主轴线,此时 align-items 依然有效,但每行只在自己那块区域内对齐,两行之间会留缝、不挨着——想控制"行与行之间"的间距,要用 align-content。
  • align-content 只在多行时生效,单行不起作用;取值与 justify-content 对应(stretch / flex-start / flex-end / center / space-between / space-around / space-evenly)。
  • baseline(基线对齐)按文字底部对齐,实际开发基本不用,了解即可。
  • 这一整组属性(justify-content、align-items、align-content、flex-direction、flex-wrap)全部写在伸缩容器上,写在项目上不生效,这是最常见的错误。

常见错误 ​

  1. 现象: 多列容器里的图片设置 width:100% 后加边框就撑破列。 原因: 百分比宽度参照所在列,border 额外计入盒模型。 修法: 给图片加 box-sizing:border-box,必要时配 display:block; max-width:100%。
  2. 现象: 同时写 column-count 和 column-width,实际列数跟预期不一致。 原因: 两者没有优先级,按分出来列数更少的一方执行。 修法: 实际只设 column-count 或只设 column-width,不要自己跟自己较劲。
  3. 现象: 写 column-span:2 想让标题跨两列,但没有效果。 原因: column-span 只支持 none 和 all。 修法: 要么不跨列,要么 column-span:all 跨所有列;局部跨列需改结构。
  4. 现象: 列分隔线不显示或只有颜色没有线型。 原因: column-rule 复合属性缺少 style,或只写了颜色/宽度。 修法: 至少补线型,如 column-rule:1px dashed #999。
  5. 现象: 给子元素写 flex:1 或 flex-direction 完全无效。 原因: 子元素还不是伸缩项目;容器属性和项目属性写错对象。 修法: 先给父元素 display:flex,主轴、换行、对齐属性写给伸缩容器。
  6. 现象: 一行放不下时项目被压扁,而不是自动换行。 原因: flex-wrap 默认是 nowrap。 修法: 需要换行时给容器显式设置 flex-wrap:wrap。
  7. 现象: 换行后用 align-items 调行与行间距,效果不理想。 原因: 多行行间分布应使用 align-content,align-items 管的是项目在各自行内的侧轴对齐。 修法: 单行侧轴对齐用 align-items,多行行间分布用 align-content。
  8. 现象: align-items:center 设置后侧轴居中不明显。 原因: 容器在侧轴方向没有可用长度,如主轴水平但父容器未设高度。 修法: 先给容器设置侧轴方向长度,再设置侧轴对齐。

练习 ​

  1. 用多列布局把一篇文章分成 3 列,列间距 30px,列间加 1px dashed #999 分隔线,并让文章标题跨所有列。写出关键 CSS,并标注哪些属性给容器、哪些给子元素。
  2. 容器宽 1000px,先设 column-width:220px、column-gap:20px,预测列数并验证;再同时加 column-count:3,观察最终按谁分列,并说明原因。
  3. 用 12 张不同高度图片做多列图片流:分 5 列,列间距 20px,图片宽 100%、白边 10px,要求图片不撑破列、底部有 20px 间距。写出关键 CSS。
  4. 父容器宽 1000px,6 个项目各宽 220px。分别设置 flex-wrap:nowrap 和 flex-wrap:wrap,观察项目宽度变化;再分别用 justify-content:space-between / space-around / space-evenly 比较间距差异。
  5. 做一个单行与多行侧轴对齐对比:容器高 400px,项目固定高 100px。不换行时用 align-items:center;换行后分别测试 align-items:center 与 align-content:center,记录差异并解释应选哪个属性。

原视频对照 ​

#视频时长
1多列布局27:13
2多列图片05:11
3伸缩容器和伸缩项目18:51
4设置主轴方向06:27
5设置换行方式08:29
6设置伸缩项目在主轴上的对齐方式08:30
7设置伸缩项目在侧轴上的对齐方式17:11

小结 ​

  1. 连续文本、不等高图片流优先考虑多列布局;需要一维排列和精细对齐时优先用 Flex。
  2. 多列布局的属性要分清对象:列数、列宽、列间距、列分隔线给容器;跨列、断列控制给子元素。
  3. 同时设置列数和列宽没有优先级,结果取分列更少者;实际项目优先只设列数。
  4. Flex 的项目身份由父容器 display:flex/inline-flex 建立,且只有直接子元素成为伸缩项目。
  5. Flex 排布顺序应先定主轴方向和换行方式,再处理主轴对齐与侧轴对齐。
  6. 单行侧轴对齐看 align-items,多行行间分布看 align-content,且容器要有侧轴方向长度。
  7. 默认 nowrap 会压缩项目而不是换行;要替代浮动式列表布局,必须显式开启 flex-wrap:wrap。
  8. 多列中断列类属性了解即可,兼容性和实用性有限,不应作为主要布局方案。