原文连接:Everything You Need To Know About Alignment In Flexbox, by Rachel Andrewcss
在 本系列的第一篇文章 中,我解释了当在元素上声明 display: flex
的时候,发生了什么。这一次我将带领你们浏览一下对齐属性(alignment properties),看看它们是如何在 Flexbox 中起做用的。若是你曾困惑不知道该使用 align-*
属性仍是 justify-*
属性的话,我但愿本文可以帮你解决这个困惑。设计模式
在整个 CSS 布局历史中,如何能自如地在两个轴上对齐元素多是 Web 设计领域的最让人头大的问题了。所以第一次看见 Flexbox 中对齐项目的功能时,是很是使人兴奋的。好比,下面两行 CSS 便能轻松作到居中对齐:安全
See the Pen Smashing Flexbox Series 2: center an item by Rachel Andrew布局
你可能认为这些属性仅是做为 Flexbox 布局中的对齐属性使用的,事实上不是,这些属性如今都定义在了 Box Alignment 规范 中。这个规范描述了这些对齐属性是如何在不一样的布局上下文(layout contexts)中起做用的。也就是说,咱们能够在 CSS 网格(Grid)中使用在弹性布局中用到的这些对齐属性——固然,将来可能还会有其余的布局上下文出现。所以,将来 Flexbox 中新的对齐功能将会在 Box Alignment 规范中定义,而不是在 Flexbox 规范中。post
许多人跟我说在使用 Flexbox 过程当中,很容易被“这里该使用 align-
属性仍是 justify
属性?”的问题搞懵圈。这里告诉你一个简单的记忆方法:flex
justify-
操做的是主轴(main axis)对齐,对齐方向与 flex-direction
方向一致。align-
操做的是交叉轴(cross axis)对齐,对齐方向与 flex-direction
方向垂直。这里咱们使用的是“主轴”和“交叉轴”,而没有说“水平方向”或“垂直方向”,是由于前者(两根轴)的方向跟物理方向并非关联的。flexbox
咱们从主轴对齐开始讲起。在主轴上对齐,咱们使用的是 justify-content
属性。这个属性把全部的 Flex 项目当成一组,控制项目之间的空间分配。spa
justify-content
的初始值是 flex-start
。这就是为何,在声明 display: flex
以后,全部的 Flex 项目都是在弹性线(flex line) 的起始处对齐的。当 flex-direction
是 row
且处于从左到右的语言环境的时候(好比英语),这个起始处就位于左边。设计
Flex 项目在起始处对齐3d
须要注意的是,justify-content
仅在有剩余空间可供分配的状况下才起做用。若是在主轴上,Flex 项目分配完毕后,已无可供分配的剩余空间,justify-content
不会起任何做用。
无空间可供分配
若是咱们给 justify-content
使用的是 flex-end
,那么全部项目都是在弹性线末尾对齐,剩余空间位于头部。
Flex 项目在末尾处对齐
剩余空间的分配还有更多方式。好比,咱们能够空间在 Flex 项目之间平均分配,须要用到 justify-content: space-between
。这种状况下,第一个和最后一个 Flex 项目会靠在容器边缘,而后剩余空间会在项目之间均等分配。
剩余空间在项目之间平均分配
也可使用 ustify-content: space-around
。这种状况下,剩余空间会在每一个项目的两边分配。
剩余空间在每一个项目的两边分配
译注:由于每一个项目两边都分到了同样的空间。所以,项目间的间距会是项目与容器边缘间距的两倍。图中的容器设置了
padding
值,所以看出的效果可能没那么明显,在此告知你们。
Box Alignment 规范还为 justify-content
属性定义了一个新值 space-evenly
,它并未出如今 Flexbox 规范中。使用了这个值后,项目与容器之间、项目与项目之间的分配的空间大小是同样的。
项目均匀分布于容器内
下面的 demo 展现了在不一样取值状况下的项目分配:
See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: row by Rachel Andrew
flex-direction
取值 column
的时候,这些值的做用效果是同样的。固然了,除非你给 Flex 容器一个高度或者容器自己是 block-size 的,不然是没有额外空间可供非配的。请看下面的 demo:
See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: column by Rachel Andrew
若是 Flex 容器使用了 flex-wrap: wrap
,咱们就能获得多行(multiple flex lines) 显示的 Flex 项目,align-content
就是处理在交叉轴上行之间的剩余空间分配。固然,前提是在交叉轴上存在剩余空间可供分配。在下面的例子中,交叉轴以列的形式在块方向(block direction)上布局,我把容器的高度设置为 60vh
了,这比 Flex 项目所须要的空间要多,这样咱们就有空间在垂直方向上进行分配了。
咱们可使用下图里列举的值,布局交叉轴上的对齐:
See the Pen Smashing Flexbox Series 2: align-content with flex-direction: row by Rachel Andrew
若是 flex-direction
取值 column
,则 align-content
将按以下方式布局:
See the Pen Smashing Flexbox Series 2: align-content with flex-direction: column by Rachel Andrew
相似于 justify-content
,align-content
是把多行当作一个组来分配剩余空间的。
阅读 Box Alignment 规范,发现有一个简写属性 place-content
,这个属性是 justify-content
属性和 align-content
属性的简写形式。place-content
接收两个值,第一个值指定 align-content
,第二个值指定 justify-content
;若是只指定一个值的话,两个属性都设置为这个值。所以:
.container {
place-content: space-between stretch;
}
/* 等效于 */
.container {
align-content: space-between;
justify-content: stretch;
}
/* 若是是这样使用的 */
.container {
place-content: space-between;
}
/* 则等效于 */
.container {
align-content: space-between;
justify-content: space-between;
}
复制代码
咱们已经知道,能够将一组 Flex 项目或将多行弹性线(flex lines)做为组进行对齐。可是还有一个小小的需求,就是但愿在交叉轴上以彼此关联的方式对 Flex 项目作对齐。Flex 容器会有一个高度,这个高度多是由最高的那个 Flex 项目决定的。
容器的高度是由第三个项目的高度决定的
固然,也能够直接给 Flex 容器一个高度:
直接在容器上定义了高度
其余 Flex 项目之因此会伸展与最高项同样的高度,是由于 align-items
属性的初始值是 stretch
。项目在交叉轴上伸展,直到尺寸和 Flex 容器的尺寸同样。
咱们要注意到 align-items
的做用点是哪里。对于多行 Flex 容器,每一行都像是一个新的 Flex 容器,那一行里最高的 Flex 项目将决定改行其余项目的高度。
除了初始值 stretch
,还可使用 flex-start
,此属性会让 Flex 项目沿着容器的起点处对齐,不会伸展到与容器同样的高度了。
Flex 项目沿着交叉轴的起点处对齐
而 flex-end
则让 Flex 项目沿着交叉轴的终点处对齐。
Flex 项目沿着交叉轴的终点处对齐
若是使用的是 center
,则全部项目的沿着中心对齐。
在交叉轴上居中对齐项目
还能够基于基线对齐。与上面的基于项目中心线对齐不一样,这是根据文本的基线对齐的:
基线对齐
能够查看下图,发现不一样值产生的效果:
See the Pen Smashing Flexbox Series 2: align-items by Rachel Andrew
align-items
的意思是一次设置全部 Flex 项目的对齐方式。实际是把全部 Flex 项目的 align-self
属性作了统一的设置。你也能够在单个 Flex 项目上使用 align-self
属性,指定在行(flex line)内与其它 Flex 项目不一样的对齐方式。
在下例中,咱们在 Flex 容器上将 align-items
属性设置为 center
,而且为第一个和最后一个项目分别指定了单独的对齐方式。
See the Pen Smashing Flexbox Series 2: align-self by Rachel Andrew
译注:
原文做者这里的解释有点牵强。详细可参考 stackoverflow 上的回答:In CSS Flexbox, why are there no “justify-items” and “justify-self” properties?。
总结下来的话,就是没有必要,由于使用下面即将要说的 auto margin 方案就能解决。规范中也是介绍使用 auto margin 解决主轴上部分项目的个性化对齐问题的。
一个常见的问题是,如何在主轴对齐一个项目或者一组项目。为何 Flexbox 主轴上没有 -self
属性?若是你知道 justify-content
和 align-content
是用来分配剩余空间的,那么可能就能搞懂为何没有 self-alignment 属性了。咱们把 Flex 项目当作一组,并对可用空间进行分配——在组的头部或者尾部或者再项目之间。
咱们能够思考下 justify-content
和 align-content
属性在 CSS Grid 布局中的做用。这两个属性在 Grid 中是用来分配*网格轨迹之间(between grid tracks)*的间距的。它们把轨迹当作是一个组,这些属性就是用来分配这些轨迹之间的间距的。因为咱们同时在 Grid 和 Flexbox 中对一个组进行操做,所以咱们不能单独针对一个项目来作一些不一样的事情。然而,有一种方法能够实现当您在主轴上请求 self
属性时所要求的那种布局,那就是使用 auto margin。
若是你有过用 CSS 居中显示一个块元素的经验(经过给内容页设置左右 margin
为 auto
),你就已经理解 auto margin 实现居中的行为。若是咱们设置了一个方向上的 margin: auto
,那么这个 margin
会尽量的占据该方向的空间大小。在使用 margin
居中块元素的例子中,咱们将左右 margin
都设置为了 auto
,它们每一个都尽量的争夺空间,最终将块元素推倒了中间的位置。
auto margin 在主轴对齐上一样表现优秀,它能够实现单个项目或者一组项目的对齐。下例中,我实现了一个常见的设计模式——我使用 Flexbox 实现了一个导航栏,项目显示为一行,使用了初始值 justify-content: start
。我想让最后一个项目显示在弹性线(flex line)的末尾(固然,前提假设是这一行上有足够的空间)。
我选中了这个项目,而且给了它 margin-left: auto
。这就是说项目的左边会占据尽量多的空间,也就是说这个项目会被推倒了右边。
See the Pen Smashing Flexbox Series 2: alignment with auto margins by Rachel Andrew
若是在主轴上使用了 auto margin,justify-content
就会失去效果,由于 auto margin 会占据全部原本要给 justify-content
分配的空间。
每一个对齐方法都有一个详细的回退对齐,这是在请求的对齐不能实现的状况下发生的事。例如,若是在容器中只有一个项目,而且使用了 justify-content: space-between
,那么结果如何?答案是会使用回退对齐 flex-start
,而后发现这个项目在 Flex 容器的起点处对齐了;对 justify-conrtent: space-around
的状况,回退对齐是 center
。
当前规范中,咱们还没法修改回退对齐,若是你想让 space-between
的回退方案采用 center
而非 flex-start
的话,是作不到的。 规范中有一个 Note 提到将来的版本中可能会支持。
Box Alignment 规范最近新增了 Safe 和 Unsafe 对齐的概念,对应关键字 safe
和 unsafe
。
下面的代码中,最后一项对于 Flex 容器来讲太宽了,且对齐方式不安全。Flex 容器位于页面左侧,当溢出超出页面边界时,发现这一项被切断了。
.container {
display: flex;
flex-direction: column;
width: 100px;
align-items: unsafe center;
}
.item:last-child {
width: 200px;
}
复制代码
不安全的对齐方式致使的对齐结果可能致使数据丢失
而安全对齐方式会避免数据丢失的出现,将溢出转移到另外一边。
.container {
display: flex;
flex-direction: column;
width: 100px;
align-items: safe center;
}
.item:last-child {
width: 200px;
}
复制代码
安全对齐避免数据丢失
See the Pen Smashing Flexbox Series 2: safe or unsafe alignment by Rachel Andrew
对齐属性起源于 Flexbox,可是如今位于独立的规范中,并可用于其余布局上下文中。如下几个关键事实将帮助你记住如何在 Flexbox 中使用它们:
justify-
主轴对齐,align-
交叉轴对齐;align-content
和 justify-content
属性时须要有额外的剩余空间;align-content
和 justify-content
属性把 Flex 项目当作一组来处理。所以对这些属性而言,没有针对单个项目的 -self
对齐属性。align-items
用于统一设置 Flex 项目上的 align-self
属性。在 Flex 项目上使用 align-self
用于单独设置此项目的对齐方式。(完)