考虑伸缩容器的主轴和横轴:
资料来源: W3C
要沿主轴对齐弹性项目,有一个属性:
要沿横轴对齐弹性项目,请使用以下三个属性:
在上图中,主轴是水平的,而横轴是垂直的。这些是 flex 容器的默认方向。
但是,这些方向可以很容易地与flex-direction
属性互换。
/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
(交叉轴始终垂直于主轴。)
在描述轴的工作方式时,我的观点是,这两个方向似乎都没有什么特别之处。主轴,横轴在重要性方面均相等,并且flex-direction
使其可以轻松地来回切换。
那么,为什么十字轴具有两个附加的对齐属性?
为什么将align-content
和align-items
合并为主轴的一个属性?
主轴为什么没有获得 “ justify-self
属性?
这些属性将有用的方案:
将 flex 项目放在 flex 容器的角落#box3 { align-self: flex-end; justify-self: flex-end; }
使一组 flex 项右对齐( justify-content: flex-end
),但使第一个justify-self: flex-start
)
考虑带有一组导航项和徽标的标题部分。通过justify-self
,徽标可以在左侧对齐,而导航项则保持在最右侧,并且整个对象可以平滑调整(“弯曲度”)以适应不同的屏幕尺寸。
在三个 flex 项目的行中,将中间项目粘贴到容器的中心( justify-content: center
),并将相邻的项目与容器边缘对齐( justify-self: flex-start
和justify-self: flex-end
)。
请注意,如果相邻项目的宽度不同,则justify-content
space-around
和space-between
值将不会使中间项目保持在容器中心。
#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>note that the middlebox will only be truly centered if adjacent boxes are equal width</p>
在撰写本文时,在flexbox 规范中justify-self
或justify-items
。
但是,在CSS 框对齐模块(这是 W3C 尚未完成的建议中,以建立一套通用的对齐属性供所有框模型使用)中,是这样的:
资料来源: W3C
您会注意到,考虑了justify-self
和justify-items
...但对于 flexbox 却没有。
最后,我重申一个主要问题:
为什么没有 “证明项目” 和 “自我证明” 属性?
如问题中所述:
要沿主轴对齐弹性项目,有一个属性:
justify-content
要使弹性项沿横轴
align-content
,align-items
和align-self
。
然后问题问:
为什么没有
justify-items
和justify-self
属性?
一个答案可能是:因为它们不是必需的。
flexbox 规范提供了两种沿主轴对齐弹性项目的方法:
justify-content
关键字属性,以及auto
边距justify-content
属性将 flex 项目沿 flex 容器的主轴对齐。
它应用于 flex 容器,但仅影响 flex 项目。
有五个对齐选项:
flex-start
start〜Flex 项目被包装到行的开头。
flex-end
end〜Flex 项目包装在行尾。
center
〜柔性物品被包装到生产线的中心。
space-between
〜Flex 的项都均匀地隔开,具有对齐到容器的一个边缘对准到相对的边缘的最后一个项目的第一项。第一项和最后一项使用的边缘取决于flex-direction
和写入模式( ltr
或rtl
)。
space-around
〜与space-between
相同,但两端均留有一半大小的间隔。
使用auto
边距,可以将弹性项目居中,隔开或打包成子组。
与应用于 flex 容器的justify-content
不同,flex 项具有auto
它们通过消耗指定方向上的所有可用空间来工作。
问题的场景:
使一组 flex 项右对齐(
justify-content: flex-end
),但使第一个justify-self: flex-start
)考虑带有一组导航项和徽标的标题部分。通过
justify-self
,徽标可以在左侧对齐,而导航项则保持在最右侧,并且整个对象可以平滑调整(“弯曲度”)以适应不同的屏幕尺寸。
其他有用的方案:
问题的场景:
- 将 flex 项目放置在角落
.box { align-self: flex-end; justify-self: flex-end; }
margin: auto
justify-content: center
和align-items: center
的替代方法。
代替在 flex 容器上的此代码:
.container {
justify-content: center;
align-items: center;
}
您可以在 flex 项目上使用它:
.box56 {
margin: auto;
}
当居中溢出容器的 flex 项目居中时,此替代方法很有用。
flex 容器通过分配可用空间来对齐 flex 项目。
因此,为了创建平衡,以便使中间物料可以在容器中居中放置单个物料,必须引入平衡。
在下面的示例中,引入了不可见的第三柔性项目(框 61 和 68)以平衡 “真实” 项目(框 63 和 66)。
当然,就语义而言,此方法并不是什么好事。
另外,您可以使用伪元素代替实际的 DOM 元素。或者,您可以使用绝对定位。此处介绍了所有三种方法:居中和底部对齐的弹性项目
注意:仅当最外面的项目的高度 / 宽度相等时,以上示例才有效(就真正居中而言)。当弹性项目的长度不同时,请参见下一个示例。
问题的场景:
在三个 flex 项目的行中,将中间项目粘贴到容器的中心(
justify-content: center
),并将相邻的项目与容器边缘对齐(justify-self: flex-start
和justify-self: flex-end
)。请注意,如果相邻项目的宽度不同,则
justify-content
space-around
和space-between
值将不会使中间项目相对于容器居中(请参见 demo )。
如前所述,除非所有 flex 项目的宽度或高度相同(取决于flex-direction
),否则中间项目无法真正居中。这个问题为justify-self
属性(当然是为了处理任务而设计)提供了有力的依据。
#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
这是解决此问题的两种方法:
解决方案 1:绝对定位
flexbox 规范允许弹性项目的绝对定位。这使得中间项目可以完美地居中,而不考虑其同级大小。
请记住,与所有绝对定位的元素一样,这些项目也会从文档流中删除。这意味着它们不会占用容器中的空间,并且可以使它们的兄弟姐妹重叠。
在以下示例中,中间项目以绝对定位为中心,而外部项目保持流入。但是,可以通过相反的方式实现相同的布局:将中间项目justify-content: center
并绝对定位外部项目。
解决方案 2:嵌套式 Flex 容器(无绝对定位)
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box71 > span { margin-right: auto; }
.box73 > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="container">
<div class="box box71"><span>71 short</span></div>
<div class="box box72"><span>72 centered</span></div>
<div class="box box73"><span>73 loooooooooooooooong</span></div>
</div>
运作方式如下:
.container
)是一个 flex 容器。.box
)都是一个弹性项目。.box
项都指定了flex: 1
,以便平均分配容器空间。justify-content: center
。span
元素都是一个居中的 flex 项目。auto
边距左右移动外部span
s。您也可以放弃justify-content
而仅使用auto
边距。
但是justify-content
可以在这里工作,因为auto
边距始终是优先事项。从规格:
在通过
justify-content
和align-self
之前,任何正的自由空间都会分配给该维度中的自动边距。
回到正justify-content
一分钟,这里是一个更多选择的想法。
space-same
same〜 space-between
和space-around
。 Flex 项的间距是均匀的(例如space-between
间距),除了两端没有半角的间距(例如, space-around
)以外,两端还有全角的间距。可以使用 flex 容器上的::before
和::after
伪元素来实现此布局。
更新:浏览器已开始实现space-evenly
,从而完成了上述任务。有关详细信息,请参见此帖子:伸缩项目之间的间距相等
PLAYGROUND (包括上面所有示例的代码)
这是在 www 样式列表中提出的,Tab Atkins(规范编辑器)提供了解释原因的答案。我会在这里详细说明。
首先,让我们首先假设我们的 flex 容器是单行的( flex-wrap: nowrap
)。在这种情况下,主轴和横轴之间显然存在对齐差异 - 主轴上堆叠了多个项目,但在横轴上仅堆叠了一个项目。因此,在横轴上有一个可自定义的 “align-self” 项是有意义的(因为每个项目都是单独对齐的),而在主轴上则没有意义(因为在那里,项目统一排列)。
对于多行 flexbox,相同的逻辑适用于每个 “flex line”。在给定的行中,项目在横轴上单独对齐(因为在横轴上每行只有一个项目),而在主轴上则是统一排列。
这是短语的另一种表达方式:因此,所有*-self
和*-content
-content 属性都与如何在事物周围分配额外的空间有关。但关键的区别是, *-self
版本的情况下,只能有一个在该轴一个单一的东西,而*-content
版本时,有在轴可能很多事情。单物与多物场景是不同类型的问题,因此它们具有不同类型的可用选项,例如, space-around
值 / space-between
值对*-content
有意义,但对于*-self
。
SO:在 flexbox 的主轴上,有很多东西可以分配空间。因此,一个*-content
属性是有道理的有,但不是*-self
属性。
相反,在交叉轴,我们既是*-self
和*-content
属性。一个决定了我们如何在许多弯曲线( align-content
)周围分配空间,而另一个( align-self
)确定了如何在给定的弯曲线内在交叉轴上的各个弯曲项目周围分配空间。
(我在*-items
属性,因为它们只是为*-self
建立默认值。)