Flexbox 完全指南

0 股票
0
0
0
0

介绍

我们提供了一份全面的 CSS Flexbox 布局指南。这份指南详细解释了 Flexbox 的方方面面,重点介绍了父元素(Flex 容器)和子元素(Flex 项目)的所有属性。此外,它还包含 Flexbox 的历史记录、示例、模板以及浏览器支持列表。.

语境

Flexbox 布局模块(W3C 于 2017 年 10 月提出的候选建议)旨在提供一种更高效的方式来排列、对齐和分配容器内项目之间的空间,即使它们的大小未知和/或动态变化(因此得名“flex”)。.

弹性布局的核心思想是允许容器根据可用空间调整其元素的宽度、高度(以及顺序),从而更好地利用空间(主要是为了适应各种显示设备和屏幕尺寸)。弹性容器会扩展元素以填充可用空间,或缩小元素以防止溢出。.

最重要的是,Flexbox 布局具有方向性,这与常规布局(基于水平布局的垂直对齐和内联的块级元素)不同。虽然常规布局适用于页面,但它们缺乏灵活性(此处并非双关),无法支持大型或复杂的应用程序(尤其是在改变方向、调整大小、拉伸、缩小等方面)。.

注意:Flexbox 布局更适合应用程序组件和小规模布局,而 Grid 布局则适用于大规模布局。.

基础知识和术语

由于 Flexbox 是一个完整的模块,而非单一功能,因此它包含很多内容,包括其全部属性。其中一些属性需要设置在容器(父元素,称为“flex 容器”)上,而另一些属性则需要设置在子元素(称为“flex 项目”)上。.

如果说“常规”布局基于块级和行内两种流方向,那么灵活布局则基于“灵活的流方向”。请查看此规范,它解释了灵活布局背后的主要思想。.

https://css-tricks.com/wp-content/uploads/2018/11/00-basic-terminology.svg
物品沿主轴(从主轴起点到主轴终点)或交叉轴(从交叉起点到交叉终点)放置。.

  • 主轴 – 弹性容器的主轴是弹性元素放置的主要轴线。请注意,它不一定是水平的,而是取决于 flex-direction 属性(见下文)。.
  • 主起点 | 主终点 – 柔性物品从主起点开始放置在容器内,一直放置到主终点。.
  • 原始尺寸——弹性项目的宽度或高度(以原始尺寸中的值为准)即为该项目的原始尺寸。弹性项目的原始尺寸属性是“宽度”或“高度”属性,取其原始尺寸中的值。.
  • 横轴——垂直于主轴的轴称为横轴。它的方向取决于主轴的方向。.
  • 交叉起始 | 交叉结束 – 弹性线填充了项目,并从弹性容器的交叉起始侧开始,向交叉结束侧移动,放置在容器中。.
  • 横向尺寸 – 弹性项目的宽度或高度(以横向尺寸中的值为准)即为该项目的横向尺寸。横向尺寸属性的值取自横向尺寸中的“宽度”或“高度”。.

Flexbox 功能

https://css-tricks.com/wp-content/uploads/2018/10/01-container.svg父母的财产
(容器)

展示

这定义了一个灵活的容器。根据给定的值,它可以是行内容器或块级容器。它为其所有直接子元素提供灵活的上下文。.

.container {
display: flex; /* or inline-flex */
}
弯曲方向

https://css-tricks.com/wp-content/uploads/2018/10/flex-direction.svg
这便创建了主轴,从而决定了弹性元素在弹性容器内的放置方向。Flexbox(除了可选的换行之外)是一种单向布局概念。可以将弹性元素想象成主要排列在水平行或垂直列中。.

.container {
flex-direction: row | row-reverse | column | column-reverse;
}
  • 行(默认):从左到右(ltr),从右到左(rtl)。
  • 行方向反转:ltr 表示从右到左,rtl 表示从左到右。
  • 列:类似于行,但方向是从上到下
  • 列反转:类似于行反转,但方向是从下到上。
柔性包装

https://css-tricks.com/wp-content/uploads/2018/10/flex-wrap.svg
默认情况下,所有弹性项目都会尝试显示在一行中。您可以根据需要更改此设置,并允许使用此属性将项目闭合。.

.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
  • nowrap(默认):所有弹性项目都将换行显示在同一行。
  • 包装:柔性物品从上到下跨多行包装。.
  • 反向环绕:柔性物品从下到上环绕在多行上。.
柔性流

这是 flex-direction 和 flex-width 属性的简写形式,它们共同指定 flex 容器的主轴和横轴。默认值为 row nowrap。.

.container {
flex-flow: column wrap;
}
内容正当性

https://css-tricks.com/wp-content/uploads/2018/10/justify-content.svg
这指定了沿主轴的对齐方式。当一行中的所有可伸缩元素都不可伸缩,或者可伸缩但已达到最大尺寸时,此设置有助于分配多余的空白。此外,当元素超出行高时,此设置还可以控制元素的对齐方式。.

.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
  • flex-start(默认):项目沿弹性方向的起始位置进行打包。.
  • 弹性末端:物品包装朝向弹性方向的末端。.
  • 开始:物品被打包到写作模式方向的开头。.
  • 结束:物品被打包到写入模式方向的末尾。.
  • 左侧:物品会向容器的左边缘打包,除非与弹性方向不符,在这种情况下,它会像起始位置一样工作。.
  • 正确:物品会堆放在容器的右边缘,除非向该方向保持灵活性有意义,那么它就相当于容器的末端。.
  • 居中:物品沿线居中排列。
  • 间距:物品均匀分布在队伍中。第一个物品位于起点,最后一个物品位于终点。
  • 环绕式布局:元素均匀分布成一行,周围留有等距空间。请注意,视觉上这些空间并不完全相等,因为所有元素两侧的空间都相等。第一个元素在容器边缘处留有一个单位的空间,但与下一个元素之间会留出两个单位的空间,因为下一个元素本身也应用了间距。.
  • 空间均匀分布:物品的分布方式使得任意两个物品之间的距离(以及到边缘的距离)相等。.

您还可以将两个额外的关键词与这些值搭配使用:safe 和 insecure。使用 safe 可以确保无论您如何进行此类定位,都不会将元素推离页面太远(例如,超出页面顶部),以至于内容无法滚动浏览(称为«数据丢失»)。.

对齐项目

https://css-tricks.com/wp-content/uploads/2018/10/align-items.svg
这定义了当前行中灵活项沿交叉轴排列的默认行为。可以将其理解为交叉轴(垂直于主轴)的内容对齐方式。.

.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
  • 拉伸(默认):拉伸以填充容器(仍遵循最小/最大宽度)
  • flex-start / start / self-start:元素放置在十字轴的起始位置。这些设置之间的区别很细微,主要在于是否遵循 flex 方向规则或编写模式规则。.
  • flex-end / end / self-end:元素放置在交叉轴的末端。区别很细微,在于遵循 flex 方向规则还是写入模式规则。.
  • 中心:物品位于十字轴上
  • 基线:项目与其基线对齐
ALign-Content

https://css-tricks.com/wp-content/uploads/2018/10/align-content.svg
当交叉轴上有额外空间时,它会将内部的柔性容器线对齐,类似于 justify-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;
}
  • 正常(默认):物品按默认位置打包,就像没有设置任何值一样。.
  • flex-start / start:元素被包裹到容器的开头。flex-start(支持更完善)指示 flex 方向,而 start 遵循写入模式方向。.
  • flex-end / end:环绕到容器末尾的元素。(更多支持)flex-end 指示 flex 方向,而 end 遵循写入模式方向。.
  • 中心:位于容器中心的物品
  • 间距:项目之间均匀分布。第一行位于容器的开头,最后一行位于容器的结尾。
  • 留白式:元素均匀分布,每行周围留有相等的空间。
  • 空间均匀分布:物品均匀分布,周围空间相等。
  • 拉伸:线条被拉伸以占据剩余空间。
间隙、行间隙、列间隙

https://css-tricks.com/wp-content/uploads/2021/09/gap-1.svg
gap 属性明确控制柔性元素之间的间距。此间距仅适用于元素之间,不适用于元素边缘。.

.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}

可以把这种行为看作是最小间距,这样,如果间距比较大(由于类似 justify-content: spacing-between; 之类的原因),那么只有当间距变小时,这个间隙才会产生影响。.

这并非 flexbox 独有,网格布局和多列布局也支持间距。.

Flexbox 前缀

为了支持尽可能多的浏览器,Flexbox 需要一些浏览器厂商前缀。这不仅仅是在属性前添加厂商前缀,而是需要使用完全不同的属性名称和值。这是因为 Flexbox 规范随着时间的推移而不断变化,产生了«旧版»、«过渡版»和«新版»。.

或许处理这个问题的最佳方法是使用新的(也是最终的)语法编写代码,然后通过 Autoprefixer 处理 CSS,它可以很好地利用退格键。.

或者,这里有一个 Sass @mixin 可以帮助你使用一些前缀,它还可以让你了解可以做什么:

@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val; 
-moz-box-ordinal-group: $val; 
-ms-flex-order: $val; 
-webkit-order: $val; 
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}

示例

让我们从一个非常非常简单的例子开始,解决一个几乎每天都会遇到的问题:完美聚焦。如果你使用 Flexbox 布局,那就再简单不过了。.

<ul class="navigation">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Contact</a></li>
</ul>
.parent {
display: flex;
height: 300px; /* Or whatever */
}
.child {
width: 100px; /* Or whatever */
height: 100px; /* Or whatever */
margin: auto; /* Magic! */
}

这是因为在弹性容器中,自动设置的边距会占用额外的空间。因此,设置自动边距会使元素在两个轴上完美居中。.

现在我们再来使用一些其他属性。假设有一个包含 6 个项目的列表,每个项目的尺寸都是固定的,但可以自动调整大小。我们希望它们在水平方向上均匀分布,这样当我们调整浏览器窗口大小时,所有项目都能平滑缩放,而无需任何媒体请求。.

.flex-container {
/* We first create a flex layout context */
display: flex;
/* Then we define the flow direction 
and if we allow the items to wrap 
* Remember this is the same as:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Then we define how is distributed the remaining space */
justify-content: space-around;
}

搞定了。剩下的只是样式方面的问题。下面是一个示例。请务必前往 CodePen 并调整窗口大小,看看会发生什么。.

我们再试试别的办法。假设我们的网站顶部有一个右对齐的导航元素,但我们希望它在中等尺寸的屏幕上居中显示,而在小尺寸设备上则显示为单列。这很简单。.

/* Large */
.navigation {
display: flex;
flex-flow: row wrap;
/* This aligns items to the end line on main-axis */
justify-content: flex-end;
}
/* Medium screens */
@media all and (max-width: 800px) {
.navigation {
/* When on medium sized screens, we center it by evenly distributing empty space around items */
justify-content: space-around;
}
}
/* Small screens */
@media all and (max-width: 500px) {
.navigation {
/* On small screens, we are no longer using row direction but column */
flex-direction: column;
}
}

让我们尝试一些更好的方法,充分利用灵活元素的优势!比如,采用移动优先的三栏布局,带有全宽的页眉和页脚,而且不受源顺序的影响。.

<div class="wrapper">
<header class="header">Header</header>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p> 
</article>
<aside class="aside aside-1">Aside 1</aside>
<aside class="aside aside-2">Aside 2</aside>
<footer class="footer">Footer</footer>
</div>
.wrapper {
display: flex;
flex-flow: row wrap;
}

/* We tell all items to be 100% width, via flex-basis */
.wrapper > * {
flex: 1 100%;
}

/* We rely on source order for mobile-first approach
* in this case:
* 1. header
* 2. article
* 3. aside 1
* 4. aside 2
* 5. footer
*/
/* Medium screens */
@media all and (min-width: 600px) {
/* We tell both sidebars to share a row */
.aside { flex: 1 auto; }
}
/* Large screens */
@media all and (min-width: 800px) {
/* We invert order of first sidebar and main
* And tell the main element to take twice as much width as the other two sidebars
*/
.main { flex: 3 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

您可能也喜欢