资讯专栏INFORMATION COLUMN

「译」Flexbox 基本原理

Forest10 / 374人阅读

摘要:对这两个值添加,则主轴将反转,而交叉轴保持不变。顺序是以组为单位进行分配的。默认情况下所有的弹性项目都设置为,这意味着所有的项目位于同一组,并且它们会按照原始顺序进行定位。这是通过文件完成的,它负责跟踪依赖项及其版本。

原文地址:Flexbox Fundamentals

原文作者:Marina-ferreira

整理自 MDN web docs 的笔记,同时参考了 Web Bos 上的什么是 Flexbox系列视频。

介绍

Flexbox 是 Flexible Box Module 的缩写。 它是一种布局模型,允许我们方便地控制 html 元素之间的空间分布和对齐 [2]。

Flexbox 一次只能控制一个维度的定位(行或者列)。二维定位的控制需要依靠网格布局 [2]。

给出以下模板:


    
1
2
3
4
5
6
7
8
9
10

上面 div 的行为默认遵循正常的 html 文档流,因此从上到下、从左到右进行渲染,并且会占据整个 body 的宽度,因为它们的 display 属性默认是 block

弹性项目

当为 .containerdiv 设置 display: flex 时,所有的直接子 div 将成为弹性项目,并且获得新的行为 [2]:

由于 flex-direction 默认值为 row,因此它们会呈一行排列

它们将会从左到右排列

项目不会依靠伸展来适应整个宽度(主轴),相反,它们采用收缩的方式

项目将会伸展以适应交叉轴(在这个例子中是高度)。如果各个项目的高度不同,它们将会伸展至与最高的那个项目等高。

flex-basis 默认值为 auto(项目宽度将取决于其自身的内容)

flex-wrap 默认值为 nowrap(如果容器的宽度不足以囊括所有的项目,则项目不会换行,只会溢出)

出于可视化的目的,我们拉伸容器以占据整个高度。

弹性容器

display: flex 使容器拓展整个可用宽度;与之相对的,display: inline-flex 使容器宽度塌陷至与内容宽度相等。

弹性方向

一旦声明为弹性容器,我们就可以将元素看作位于两条轴中。一条是由 flex-direction 定义的主轴,一条是与前者垂直的交叉轴 [2]。

flex-direction 属性有四个值: row, row-reverse, columncolumn-reverse.

默认值是 row,它将主轴设置为从左到右的水平方向,而交叉轴从上到下与之垂直相交。同理,column 将主轴设置为从上到下的垂直方向,而交叉轴则是从左到右。对这两个值添加 reverse ,则主轴将反转 180°,而交叉轴保持不变 1。

可以通过下图观察这些值对应的弹性项目行为:

弹性换行

当容器空间不足以容纳全部弹性项目时,利用 flex-wrap 属性处理弹性项目 [3]。

flex-wrap 的默认值为 nowrap,这意味着如果容器不能在保留项目原始宽度的同时将它们排列成一行的话,项目将会收缩以进行适应。如果由于某些原因无法收缩,则项目会溢出容器外 1。

通过给项目设置 300px 的宽度,nowrap 选项输出下面这个结果:

其中,每个项目收缩到大约 70px 以适应容器。

当属性值更新为 wrap 时,项目的宽度将等于原先的值,300px。当第一行的宽度不足以容纳 300px 时,项目不再溢出容器外,而是会换行 [3]。每一行都应该被视为是一个独立的弹性容器,任何一个容器内的空间分布均不会影响与之相邻的其他容器 [2]。

但是为什么弹性项目会占据整个屏幕的高度呢?在第一部分,容器高度被设置为 100vh,因此可用空间被这四行平分以适应 300px 的项目。假如我们没有设置 100vh,则容器高度将等于项目内容的高度,如下图所示 [1]:

另一个选项是 wrap-reverse,它将会反转交叉轴。通过属性 flex-direction 设置的从上到下的方向会被 wrap-reverse 转化为从下到上 [1]。

通过 flex-direction: column 反转主轴,容纳不下的元素将会换行至另一列,同时剩余空间会被平分 [1]。

wrap-reverse 选项与 column 方向搭配使用,则将反转交叉轴的方向为从右到左,产生如下输出:

弹性布局是一维布局,虽然在反转换行的时候,项目会从下到上排列(在方向为 row 的情况下),但是依然保持着从左到右的结构。改变的只有交叉轴。

弹性流

flex-directionflex-wrap 可以在一个单属性中进行声明: flex-flow: [direction] [wrap] [2]。

.flex-container {
    flex-flow : column wrap;
}
项目之间的空隙

回到主轴方向为 row 且进行换行的情况。通过给项目设置 width: 33.3333%,容器能够完全被填满。

但是当你让子 div 之间有空隙时,它们将不会像预期的那样进行换行:

可以通过使用 CSS 函数 calc() 解决这个问题 [1]:

.flex-item {
    width: calc(33.33333% - 40px);
    margin: 20px;
}

为了消除容器边缘的空间,这里对容器设置负外边距 [3]:

.flex-container {
    margin: -20px;
}
顺序

order 属性允许修改项目的呈现顺序。顺序是以组为单位进行分配的。默认情况下所有的弹性项目都设置为 order:0 ,这意味着所有的项目位于同一组,并且它们会按照原始顺序进行定位。如果有两个或者两个以上的组,那么各组将会相对于它们的整数值进行排序 [4]。

在下面的例子中,有三个顺序组-101,它们按照如下顺序排列。

.box-3 { order:  1; }
.box-7 { order:  1; }
.box-8 { order: -1; }

表面上,这个属性重新分配了项目,但在诸如使用 tab 键对它们进行遍历的交互中则依然保留它们的原始位置。如果项目顺序与可访问性有关的话,这一点是需要考虑的。同理, flex-direction 也是这样 [4]。

对齐

在弹性布局中,沿着轴的项目对齐和空间分布可以通过四个属性控制 [5]:

justify-content:将所有项目在主轴上对齐

align-items :将所有项目在交叉轴上对齐

align-self:将单个项目在主轴上对齐

align-content:控制交叉轴上各条线之间的空间

justify-content

justify-content 是一个在主轴上处理项目的容器属性。最常用的 6 个值是: flex-startflex-endcenterspace-aroundspace-betweenspace-evenly。其中,默认值为 flex-start

align-items

align-items 同样是一个容器属性,它在交叉轴上处理项目的对齐。 默认值是 stretch ,其他值是 flex-startflex-endcenterbaseline [5]。

如果设置了容器高度,则 stretch 属性值会使所有的项目伸展至与容器等高;如果没有设置,则所有项目与最高的项目等高 [5]。上面第一张图片中容器高度设置为 100vh,第二张图片则没有设置高度。

align-content

align-content 是第四个也是最后一个容器属性,它在交叉轴上分配各条线之间的空间。作为最后一个属性,它的初始值为 stretch ,并且和 justify-content 一样接受以下几个属性值:flex-startflex-endcenterspace-aroundspace-betweenspace-evenly [5]。

align-self

align-items 属性实际上是通过给容器内的所有项目设置 align-self 而生效的。通过多带带设置 align-self,可以覆盖先前设置的总的属性值。该属性和 align-items 拥有相同的可选值,但是还多了一个 ‘auto’ [5]。

auto 会重置 align-self 的值,使之重新等于通过 align-items 给容器全局定义的值 [5]。

弹性项目大小

项目的大小和弹性可以通过三个属性控制:flex-growflex-shrinkflex-basis。这些属性都在主轴上发挥作用 [2]。

flex-grow:如果有额外空间,每个项目应该如何伸展

flex-shrink:如果空间不足,每个项目应该如何收缩

flex-basis:在设置以上两个属性之前项目的大小

flex-grow

该属性设置的是弹性增长系数,这是一个用于处理项目之间相对大小的比率 [7]。

默认值是 0,这意味着如果有剩余空间,就把这个空间放在最后一个项目的后面 [1]。

在上面的例子中,direction 设置为 row,每个弹性项目的宽度是 60px。由于容器的宽度是 980px ,因此有 680px 的可用空间,这个空间称为 正向自由空间 [7]。

通过将 flex-grow 设置为 1,正向自由空间将会被弹性项目平分。每个项目的宽度都会增加 136px,总的宽度是 196px [7]。

通过给第三个项目设置 flex-grow: 2 ,它获得的可用正向自由空间是其他项目的两倍,即比起其他项目的 173px ,它的总宽度为 286px [7]。

下图中,项目的 flex-grow 属性设置为自身的内容值。

flex-shrink

当容器没有足够空间来容纳所有项目时,使用 flex-shrink 处理项目大小。因此,它通过收缩项目来处理它们的负向自由空间 [7]。

如下图所示,980px 的容器存放着 5 个 300px 宽度的容器。由于没有足够空间来容纳所需要的 1500px,默认的弹性收缩系数 1 会使每个项目收缩至 196px

通过给第三个项目设置 2 的比率,它会比其它项目小两倍。

下图中,每个项目以自身内容值作为弹性收缩比率。

flex-basis

flex-basis 属性会在实际设置可用空间之前检查每个项目应该具有的大小。默认值是 auto,项目宽度要么通过 width 显式设置,要么等于内容宽度。它同样也接受像素值 [7]。

下面的 gif 展示了一个 800px 宽度的容器和 5 个设置了 flex-basis: 160px 的弹性项目。这告诉浏览器:理想情况下有足够的空间放置所有的项目,项目的 160px 宽度将会得到保留,并且没有正向/负向自由空间。如果没有足够的空间,由于 flex-shrink 默认为 1,所有的项目会均匀地收缩。如果有剩余的空间,由于 flex-grow 默认为 0,剩余空间会放置在最后一个项目的后面。

下面的 gif 中,项目 1 设置为 flex-shrink: 10,项目 4 设置为 flex-grow: 10。对于负向自由空间,项目 1 减小的宽度是其它项目减小宽度的 10 倍;对于正向自由空间,项目 4 增加的宽度是其它项目增加宽度的 10 倍。

flex-basis 还可以接受值 content。此时,无论有没有设置 width,自由空间计算都只会基于项目内容去计算宽度。如果你不打算在计算时考虑项目宽度,则将其设置为 0

flex

flexflex-growflex-shrinkflex-basis 的简写属性 [2]。

它接受下面的预定于值:

initial:重置为弹性布局的默认值,与 flex: 0 1 auto 效果一样

auto:弹性项目可以根据需要伸展/收缩,与 flex: 1 1 auto 效果一样

none:使项目失去弹性,与 flex: 0 0 auto 效果一样

flex: 1:弹性项目可以伸展/收缩,并且 flex-basis 设置为 0 ,与 flex: 1 1 0 效果一样

Autoprefixer

考虑到跨浏览器兼容性,给属性加上所有必要的前缀很重要,这可以确保提供全面的支持 [1]。

手动给每个属性添加前缀是一项非常繁琐的任务,并且还会徒增样式维护的难度。作为替代方法,Gulp 可以自动化地完成这些任务。

要使用 Gulp,我们需要将其作为依赖项添加到项目中。这是通过 package.json 文件完成的,它负责跟踪依赖项及其版本。通过终端创建文件类型 [1]:

               
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/114768.html

相关文章

  • CSS及布局

    摘要:经过半年的打磨,正式发布,主要是新增了一些常用组件,并使用命名,为接下来的微信小程序开发做好准备。这两种方式实现的瀑布流式布局均支持首屏和网页窗口大小改变时的列数自适应。主要是对于标准里的布局方式草案中的布局方式进行一些总结。 一劳永逸的搞定 flex 布局 寻根溯源话布局 一切都始于这样一个问题:怎样通过 CSS 简单而优雅的实现水平、垂直同时居中。记得刚开始学习 CSS 的时候,看...

    jaysun 评论0 收藏0
  • []CSS 居中(Center)方法大合集

    摘要:并排显示,要求相同高度如果要求多个块级元素并排居中且高度相同,则要为其父元素设置属性。成一列显示如果只是需要让多个块级元素整体水平居中,并且按默认的方式纵向排列,那直接设置左右边距为即可。 原文出处:Centering in CSS: A Complete Guide 本文只给出了不同条件下的实现方式,未对原理做探讨。PS:原来要显示 jsfiddle 和 CodePen 之类网站的代...

    wayneli 评论0 收藏0
  • Flexbox完全指南(

    摘要:本文译自这里,针对本文介绍的属性列个提纲伸缩容器属性伸缩项目属性以后再布局时可以考虑用啦背景布局模块目前上一次工作草案的叫法旨在提供一种更高效的方式来布局排列及分配容器中项目的空间,即便容器大小是未知或动态变化的因此称为。 本文译自 A Complete Guide to Flexbox这里,针对本文介绍的属性列个提纲: 伸缩容器属性: display flex-direction...

    pekonchan 评论0 收藏0
  • 】如何,以及何时使用CSS多列布局

    摘要:示例链接核心代码要知道,目前的规范,的取值只有或者。最近,片段模块规范定义了如何为各种片段模块上下文设计的碎片化的属性,规范包括,和处于停滞状态的区域样式区域也会支持展示被分解碎片化连续的内容。 原文:When And How To Use CSS Multi-Column Layout作者:Rachel Andrew译者:博轩 当我们把注意力都放在 CSS Grid 布局和 CSS ...

    fancyLuo 评论0 收藏0

发表评论

0条评论

Forest10

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<