【重学CSS】图文并茂!一次性搞懂 Flex 布局,实现“布局自由”~(上)

简介: 【重学CSS】图文并茂!一次性搞懂 Flex 布局,实现“布局自由”~(上)

1、flexbox 简介

Flexible Box Module,通常简称为 flexbox,被设计为一维布局模型,是一种可以提供界面中项目之间空间分配和强大对齐能力的方法。当我们将 flexbox 描述为一维时,我们是在描述 flexbox 一次处理一维布局的事实——无论是作为行还是作为列。这可以与CSS Grid Layout的二维模型进行对比,后者将列和行一起控制。   —— Mozilla mdn

传统的布局方案基于盒状模型,依赖 display 属性 + position 属性 + float 属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。Flexbox 布局(Flexible Box) 提供一种更有效的方式来布置、对齐和分配容器中项目的空间,即使它们的尺寸是未知的、动态的(因此有 "flex" 一词)。

弹性布局背后的主要思想是让容器有能力改变其项目的宽度/高度(和顺序),以更好地填充可用空间(主要是为了适应各种显示设备和屏幕尺寸)。一个灵活的容器可以扩展项目以填充可用的自由空间,也可以收缩项目以防止溢出。

相对于常规布局(基于垂直方向的block和基于水平方向的inline),flexbox布局是不分方向的。虽然这些常规布局对页面来说效果很好,但它们缺乏灵活性,无法支持大型或复杂的应用(尤其是在改变方向、调整大小、拉伸、缩小等方面)。

注意Flexbox 布局最适合于应用程序的组件,以及小规模的布局,而网格布局则是为了大规模的布局。

如果常规布局是基于块状和内联的流动方向,弹性布局则是基于 "弹性流动方向"。其中主要的概念如下图中所示:

image.png
图片来:flex-grammar - ruanyifeng

项目将按照主轴或交叉轴进行布局:

  • main axis: 弹性容器的主轴。
  • main-start | main-end: 弹性项目在容器的主轴方向上从 main-start 开始,到 main-end 进行排列。
  • main size: 弹性项目(flex item)的宽度或高度,以主尺寸中的那个为准,是项目的主要尺寸。弹性项目的主要尺寸属性是“宽度”或“高度”属性,以主要尺寸中的那个为准。
  • cross axis: 垂直于主轴的轴被称为交叉轴。它的方向取决于主轴的方向。
  • cross-start | cross-end: 弹性项目在容器的交叉轴方向上从 cross-start 开始,到 cross-end 进行排列。
  • cross size: 交叉轴的宽度或高度。

浏览器支持方面,可以在 Caniuse 中看到,主流浏览器几乎都对它有很好的支持了~

image.png

2、Flex 容器(Container)属性
image.png

2.1 display

设置容器为 Flex布局,可以取值为 flexinline-flex

.container {
  display: flex; /* or inline-flex */
}

2.2 flex-direction

flex-direction 用来确定弹性容器中主轴的方向。Flexbox 是单向布局,主要以水平行布局或垂直列布局。

.container {
  flex-direction: row | row-reverse | column | column-reverse;
}
  • row(默认): 水平方向为主轴,方向为从左至右
  • row-reverse: 水平方向为主轴,方向为从右至左
  • column: 垂直方向为主轴,方向为从上至下
  • column-reverse: 垂直方向为主轴,方向为从下至上
    image.png
    主轴和交叉轴是Flex布局中的两个重要概念。主轴是Flex容器中子元素排列的方向,交叉轴是垂直于主轴的方向。例如,如果你设置了flex-direction: row,那么主轴就是水平方向,交叉轴就是垂直方向。如果你设置了flex-direction: column,那么主轴就是垂直方向,交叉轴就是水平方向。可以通过不同的属性来控制子元素在主轴和交叉轴上的对齐方式。例如,justify-content用于设置主轴上的对齐方式,align-items用于设置交叉轴上的对齐方式。

2.3 flex-wrap

默认情况下,弹性项目会默认尝试将全部的项目放在一行中。flex-wrap 用来设置是否换行,可以取值为nowrap(不换行)wrap(换行)wrap-reverse(反向换行)

.container {
    flex-wrap: nowrap | wrap | wrap-reverse;
}
  • nowrap(默认):所有弹性项目都在一行上,可能导致容器溢出
  • wrap: 弹性项目将换行到多行,从上到下,方向由 flex-direction 定义
  • wrap-reverse: 弹性项目将从下到上换行到多行,与 flex-direction 定义的方向相反


image.png
下面看一个demo,来实际感受这三个属性值的区别:

<ul class="flex-container nowrap">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
  <li class="flex-item">7</li>
  <li class="flex-item">8</li>
</ul>
<ul class="flex-container wrap">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
  <li class="flex-item">7</li>
  <li class="flex-item">8</li>
</ul>
<ul class="flex-container wrap-reverse">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
  <li class="flex-item">7</li>
  <li class="flex-item">8</li>
</ul>

会发现 wrapwrap-reverse 其实是镜像的,你只要记得 wrap 是怎么换行,那就知道 wrap-reverse 是怎么换行的。

2.4 flex-flow

flex-flowflex-directionflex-wrap 属性的简写,默认值是 row nowrap

.container {
  flex-flow: column wrap;
}

2.5 justify-content

justify-content 定义了主轴上子元素的对齐方式。

.container {
    justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
    /* Positional alignment */
    justify-content: center;     /* 居中排列 */
    justify-content: start;      /* Pack items from the start */
    justify-content: end;        /* Pack items from the end */
    justify-content: flex-start; /* 从行首起始位置开始排列 */
    justify-content: flex-end;   /* 从行尾位置开始排列 */
    justify-content: left;       /* Pack items from the left */
    justify-content: right;      /* Pack items from the right */
    /* Baseline alignment */
    justify-content: baseline;
    justify-content: first baseline;
    justify-content: last baseline;
    /* Distributed alignment */
    justify-content: space-between;  /* 均匀排列每个元素
                                       首个元素放置于起点,末尾元素放置于终点 */
    justify-content: space-around;  /* 均匀排列每个元素
                                       每个元素周围分配相同的空间 */
    justify-content: space-evenly;  /* 均匀排列每个元素
                                       每个元素之间的间隔相等 */
    justify-content: stretch;       /* 均匀排列每个元素
                                       'auto'-sized 的元素会被拉伸以适应容器的大小 */
    /* Overflow alignment */
    justify-content: safe center;
    justify-content: unsafe center;
    /* Global values */
    justify-content: inherit;
    justify-content: initial;
    justify-content: unset;
}
  • flex-start(默认):从行首开始排列。每行第一个弹性元素与行首对齐,同时所有后续的弹性元素与前一个对齐。
  • flex-end:从行尾开始排列。每行最后一个弹性元素与行尾对齐,其他元素将与后一个对齐。
  • start:从行首开始排列。每行第一个元素与行首对齐,同时所有后续的元素与前一个对齐。
  • end: 从行尾开始排列。每行第一个元素与行尾对齐,同时所有后续的元素与前一个对齐。
  • left:伸缩元素一个挨一个在对齐容器得左边缘,如果属性的轴与内联轴不平行,则left的行为类似于start
  • right:元素以容器右边缘为基准,一个挨着一个对齐,如果属性轴与内联轴不平行,则right的行为类似于end
  • center:伸缩元素向每行中点排列。每行第一个元素到行首的距离将与每行最后一个元素到行尾的距离相同。
  • space-between:在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。
  • space-around:在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半。。
  • space-evenly:flex 项都沿着主轴均匀分布在指定的对齐容器中。相邻 flex 项之间的间距,主轴起始位置到第一个 flex 项的间距,主轴结束位置到最后一个 flex 项的间距,都完全一样。
  • baseline / first baseline / last baseline:指定参与第一或最后基线对齐:将盒子的第一或最后基线集的对齐基线与它的基线共享组中所有盒子的第一或最后基线集中的相应基线对齐。第一条基线的回退对齐是开始,最后一条基线的回退对齐是结束。
  • stretch:如果项目的总和尺寸小于对齐容器的尺寸,任何自动尺寸的项目都会被平均增加(而不是按比例增加),同时仍然受到max-height/max-width(或同等功能)所施加的限制,这样总和尺寸就会沿着主轴完全充满对齐容器。
  • safe:与对齐关键字一起使用,如果选定的关键字会导致元素溢出容器造成数据丢失,那么将会使用 start 代替它。
  • unsafe:无论项目和对齐容器的相对大小如何,给定的对齐值都会得到遵守。

image.png
image.png
请注意,主流浏览器对这些值的支持还不是那么完善的。例如,space-between从未得到某些版本的 Edge 的支持。MDN有详细的图表。最安全的值是flex-startflex-endcenter

还有两个额外的关键字可以与这些值配对:safeunsafe。使用safe可确保无论您如何进行此类定位,都不能将元素推送到屏幕外(例如,从顶部),从而使内容无法滚动(称为“数据丢失”) .

2.6 align-items

align-items 定义了交叉轴上的子元素的对齐方式。

.container {
  align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
    /* Basic keywords */
    align-items: normal;
    align-items: stretch;
    /* Positional alignment */
    align-items: center; /* Pack items around the center */
    align-items: start; /* Pack items from the start */
    align-items: end; /* Pack items from the end */
    align-items: flex-start; /* Pack flex items from the start */
    align-items: flex-end; /* Pack flex items from the end */
    align-items: self-start;
    align-items: self-end;
    /* Baseline alignment */
    align-items: baseline;
    align-items: first baseline;
    align-items: last baseline; /* Overflow alignment (for positional alignment only) */
    align-items: safe center;
    align-items: unsafe center;
    /* Global values */
    align-items: inherit;
    align-items: initial;
    align-items: unset;
}

image.png

  • normal:这个关键字的效果取决于我们处在什么布局模式中:
  • 在绝对定位的布局中,对于被替代的绝对定位盒子,这个效果和start?的效果的一样;对于其他所有绝对定位的盒子,这个效果和stretch的效果一样。
  • 在绝对定位布局的静态位置上,效果和stretch一样。
  • 对于那些弹性项目而言,效果和stretch一样。
  • 对于那些网格项目而言,效果和stretch一样,除了有部分比例或者一个固定大小的盒子的效果像start
  • 这个属性不适用于块级盒子和表格。
  • stretch(默认):弹性项包含外边距的交叉轴尺寸被拉升至行高
  • flex-start / start / self-start:元素向侧轴起点对齐。
  • flex-end / end / self-end:元素向侧轴终点对齐。
  • center:元素在侧轴居中。如果元素在侧轴上的高度高于其容器,那么在两个方向上溢出距离相同。
  • baseline / first baseline / last baseline:所有元素向基线对齐。侧轴起点到元素基线距离最大的元素将会于侧轴起点对齐以确定基线。

2.7 align-content

align-content 用来定义多根轴线的对齐方式,可以取值与justify-content相同,但是只在有多根轴线时生效。

注意: 该属性只对多行 flex 容器有效,其中flex-wrap设置为 或wrap) wrap-reverse。单行 flex 容器(即 flex-wrap 设置为其默认值 no-wrap)不会存在 align-content

.container {
    align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
    /* 基本位置对齐 */
    /*align-content 不采用左右值 */
    align-content: center;     /* 将项目放置在中点 */
    align-content: start;      /* 最先放置项目 */
    align-content: end;        /* 最后放置项目 */
    align-content: flex-start; /* 从起始点开始放置 flex 元素 */
    align-content: flex-end;   /* 从终止点开始放置 flex 元素 */
    /* 默认对齐 */
    align-content: normal;
    /*基线对齐*/
    align-content: baseline;
    align-content: first baseline;
    align-content: last baseline;
    /* 分布式对齐 */
    align-content: space-between; /* 均匀分布项目
                                     第一项与起始点齐平,
                                     最后一项与终止点齐平 */
    align-content: space-around;  /* 均匀分布项目
                                     项目在两端有一半大小的空间*/
    align-content: space-evenly;  /* 均匀分布项目
                                     项目周围有相等的空间 */
    align-content: stretch;       /* 均匀分布项目
                                     拉伸‘自动’ - 大小的项目以充满容器 */
    /* 溢出对齐 */
    align-content: safe center;
    align-content: unsafe center;
    /* 全局属性 */
    align-content: inherit; /* 继承 */
    align-content: initial;  /* 初始值 */
    align-content: unset; /* 未设置 */
}
  • normal(默认):这些项按默认位置填充,就像没有设置对齐内容值一样。
  • flex-start: 所有行从垂直轴起点开始填充。第一行的垂直轴起点边和容器的垂直轴起点边对齐。接下来的每一行紧跟前一行。
  • flex-end: 所有行从垂直轴末尾开始填充。最后一行的垂直轴终点和容器的垂直轴终点对齐。同时所有后续行与前一个对齐。
  • start: 所有行从容器的起始边缘开始填充。
  • end: 所有行从容器的结束边缘开始填充。
  • baseline / first baseline / last baseline:指定参与第一或最后基线对齐:将盒子的第一或最后基线集的对齐基线与它的基线共享组中所有盒子的第一或最后基线集中的相应基线对齐。第一条基线的回退对齐是开始,最后一条基线的回退对齐是结束。
  • center:所有行朝向容器的中心填充。每行互相紧挨,相对于容器居中对齐。容器的垂直轴起点边和第一行的距离相等于容器的垂直轴终点边和最后一行的距离。
  • space-between:所有行在容器中平均分布。相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的边对齐。
  • space-around:所有行在容器中平均分布,相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的距离是相邻两行间距的一半。
  • space-evenly:所有行沿垂直轴均匀分布在对齐容器内。每对相邻的项之间的间距,主开始边和第一项,以及主结束边和最后一项,都是完全相同的。
  • stretch: 拉伸所有行来填满剩余空间。剩余空间平均地分配给每一行。
  • safe:与对齐关键字一起使用。如果所选的关键字意味着项溢出对齐容器(data loss),则将采用备用策略对项进行对齐,就像启动了 start 对齐模式一样。
  • unsafe:与对齐关键字一起使用。无论元素和对齐容器的相对大小如何、是否会导致一些元素溢出可见范围(data loss),都使用给定的对齐值。

image.png

<ul class="flex-container flex-start">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>
<ul class="flex-container flex-end">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>
<ul class="flex-container center">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>
<ul class="flex-container space-between">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>
<ul class="flex-container space-around">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>
<ul class="flex-container stretch">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>


相关文章
|
23天前
|
容器
Bootstrap5 Flex(弹性)布局4
排序:.order 类可设置弹性子元素的排序,范围从 .order-1 至 .order-12,数字越小优先级越高。外边距:.ms-auto 和 .me-auto 分别用于设置子元素的右侧和左侧外边距为 auto。包裹:.flex-nowrap(默认)、.flex-wrap 和 .flex-wrap-reverse 用于控制弹性容器中的子元素是否换行及换行方向。
|
21天前
|
容器
Bootstrap5 Flex(弹性)布局6
使用 `.align-self-*` 类可控制指定子元素的对齐方式,包括 `.align-self-start`, `.align-self-end`, `.align-self-center`, `.align-self-baseline`, 和 `.align-self-stretch`。示例代码展示了如何在一个弹性布局中应用这些类,以实现不同设备上的响应式设计。
|
21天前
Bootstrap5 Flex(弹性)布局5
使用 .align-content-* 控制多行子元素在垂直方向上的堆叠方式,如 .align-content-start、.align-content-center 等。对于单行子元素,使用 .align-items-* 控制对齐,例如 .align-items-start、.align-items-center 等。示例代码展示了不同对齐效果的应用。
|
23天前
Bootstrap5 Flex(弹性)布局2
介绍Flex布局的水平和垂直方向控制。`.flex-row`使子元素水平排列,默认左对齐;`.flex-row-reverse`则右对齐。`.flex-column`让子元素垂直排列;`.flex-column-reverse`则反向排列。示例展示了不同类的效果,通过改变类名实现布局调整。
|
23天前
Bootstrap5 Flex(弹性)布局3
`.justify-content-*` 类用于调整弹性子元素的对齐方式,支持 start、end、center、between、around 等值。`.flex-fill` 类使所有子元素等宽,而 `.flex-grow-1` 则让指定子元素占据剩余空间。这些类在布局设计中非常实用。
|
1月前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。
|
1月前
|
前端开发 JavaScript 开发者
掌握 CSS 弹性布局(Flexbox):构建复杂页面布局的高效秘籍与实战案例
CSS弹性布局(Flexbox)是现代网页设计中构建复杂页面布局的高效工具。本文将深入浅出地介绍Flexbox的核心概念、使用技巧及实际应用案例,帮助读者快速掌握这一强大布局方法。
|
1月前
|
容器
HTML中使用Flex布局实现双行夹批效果
在HTML中,还可以用table元素来实现双行夹批效果,但比flex布局代码更复杂,效果也不见得更理想。
41 10
|
1月前
|
开发者 UED 容器
鸿蒙next版开发:ArkTS组件通用属性(Flex布局)
在HarmonyOS next中,ArkTS的Flex布局是一种强大且灵活的布局方式,支持水平或垂直方向排列元素,并能动态调整大小和位置以适应不同屏幕。主要属性包括justifyContent、alignItems、direction和wrap,适用于导航栏、侧边栏和表单等多种场景。示例代码展示了如何使用这些属性创建美观的布局。
77 10