【重学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>


相关文章
|
6天前
|
开发者 容器
flex 布局属性在实际项目中的应用场景有哪些?
flex 布局属性在实际项目中的应用场景有哪些?
flex布局属性简介
flex布局属性简介
|
8天前
|
前端开发 容器
css布局-弹性布局学习笔记
这篇文章是关于CSS弹性布局的学习笔记,详细介绍了flex容器和元素的相关属性,包括flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content以及order、flex-grow、flex-shrink、flex-basis、flex和align-self等,解释了这些属性在弹性盒子布局中的作用和用法。
|
23天前
|
弹性计算 前端开发 容器
【前端web入门第六天】02 flex布局
Flex布局是一种现代CSS布局模式,通过给父元素设置`display: flex`,其子元素可自动挤压或拉伸。它包含弹性容器和弹性盒子,主轴默认为水平方向,侧轴为垂直方向。主轴对齐方式由`justify-content`属性控制,侧轴对齐方式包括`align-items`(针对所有子元素)和`align-self`(针对单个子元素)。修改主轴方向使用`flex-direction`属性,`flex`属性用于控制子元素在主轴上的伸缩比例。此外,`flex-wrap`属性允许子元素换行,而`align-content`属性则定义多行对齐方式。
|
8天前
|
JavaScript 前端开发
网页前端课程设计-【模仿】香港中文大学官网,轮播图及div+css布局,js的dom操作
这篇文章介绍了如何模仿香港中文大学官网进行网页前端课程设计,包括使用div+css布局、js的DOM操作以及实现轮播图等技术细节。
|
2月前
|
前端开发 安全 容器
CSS如何优雅实现卡片多行排列布局?
【8月更文挑战第24天】CSS如何优雅实现卡片多行排列布局?
42 3
|
2月前
|
前端开发 开发者 容器
探索现代Web开发中的CSS Grid布局技术
【8月更文挑战第29天】在数字时代的浪潮中,网页设计不断进化以适应日新月异的用户需求。CSS Grid布局技术作为一项革新性的前端工具,为设计师和开发者提供了前所未有的布局能力。本文旨在通过深入浅出的方式介绍CSS Grid的核心概念、基本用法以及在实际项目中的应用,帮助读者快速掌握这一强大的网页布局工具。
41 3
|
2月前
|
JavaScript
Vue3弹性布局(Flex)
这是一个基于 Vue 的弹性布局组件库,提供了丰富的参数配置,如宽度、方向、换行等,支持自定义对齐方式和间隙设置。在线预览展示了不同布局效果,包括单选、按钮和滑动输入条等组件的使用示例。
Vue3弹性布局(Flex)
|
2月前
|
前端开发 开发者 容器
【Web布局的革命】探索CSS Grid栅格系统,打造未来网页设计!
【8月更文挑战第25天】在网页设计领域,布局至关重要。传统的布局方法难以满足复杂需求,CSS Grid 栅格系统因此诞生。它是一种二维布局模式,能直接控制行和列,简化复杂网格的设计。通过定义 `display: grid;` 创建网格容器,并利用 `grid-template-columns` 和 `grid-template-rows` 设置行列尺寸,轻松实现响应式布局。此外,CSS Grid 支持高级功能,如网格区域划分和对齐设置,极大提升了布局的灵活性和创意空间。随着浏览器兼容性的增强,CSS Grid 必将成为未来网页设计的关键技术之一。
52 1