在 CSS Flexbox 中,为什么没有 “justify-items” 和 “justify-self” 属性?

In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?

提问人:Michael Benjamin 提问时间:9/13/2015 最后编辑:TylerHMichael Benjamin 更新时间:5/26/2023 访问量:407183

问:

考虑柔性容器的主轴和十字轴:

An illustration of the various directions and sizing terms as applied to a row flex container 来源:W3C

要沿主轴对齐 flex 项目,有一个属性:

要沿十字轴对齐弯曲项目,有三个属性:

在上图中,主轴是水平的,十字轴是垂直的。这些是 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-contentalign-items 合并为主轴的一个属性?

为什么主轴没有获得对齐自属性?


这些属性有用的方案:

  • 将 Flex 物品放在 Flex 容器的一角
    #box3 { align-self: flex-end; justify-self: flex-end; }

  • 使一组 Flex 项目向右对齐 (),但将第一项向左对齐 (justify-content: flex-endjustify-self: flex-start)

考虑包含一组导航项和徽标的标题部分。使用 justify-self,徽标可以向左对齐,而导航项保持在最右边,并且整个东西可以平滑地调整(“弯曲”)以适应不同的屏幕尺寸。

  • 在一行三个柔性项目中,将中间项目固定在容器的中心 (),并将相邻项目与容器边缘 ( 和 ) 对齐。justify-content: centerjustify-self: flex-startjustify-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>

jsFiddle 版本


在撰写本文时,Flexbox 规范中没有提到 或。justify-selfjustify-items

但是,在 CSS Box Alignment Module(这是 W3C 未完成的提案,旨在建立一组通用的对齐属性以用于所有 Box 模型)中,有如下内容:

enter image description here                                                                                                                                                    来源:W3C

你会注意到这一点,并且正在考虑......但不适用于 Flexboxjustify-selfjustify-items


最后,我将重申一个主要问题:

为什么没有“justify-items”和“justify-self”属性?

CSS Flexbox 语言律师

评论

12赞 dholbert 9/19/2015
您期望如何为弹性项目工作?假设您有项目 a,b,c,d,它们周围有额外的空间分布,并且 flex 容器有 ,所以它们最终类似于 |a b c d|。添加例如意味着什么 还是“justify-self: flex-end”只是为了那里的“b”项?你期望它去哪里?(我在这里的一个答案中看到了一些演示,但我没有看到它通常工作的明确方式。justify-selfjustify-content: space-betweenjustify-self: center
5赞 Michael Benjamin 11/23/2015
@dholbert,你写道:你如何期望 justify-self 为 flex 项目工作?我想说的是,边距已经适用于弹性项目没有太大区别。在您的第二个示例中,在项目 d 上将其移动到远边缘。这本身就是一个很棒的功能,利润率已经可以做到。我发布了一个带有演示的答案。autojustify-self: flex-endauto
2赞 dholbert 12/1/2015
我在这里看到的主要是更多的用例,用例很棒——但棘手的一点是如何将其硬塞进实际的方式,并被指定,以便有冲突的情况(如我问的场景)被清晰和合理地定义。正如我在这里的回答中所指出的,是关于在一个更大的盒子里对齐项目,这个盒子的大小与 {justify|align} -self 值无关——在主轴上没有这样的盒子,用于对齐一个 flex 项目。justify-contentjustify-self{justify|align}-self
3赞 dholbert 12/1/2015
RE“与自动保证金没有什么不同”——我实际上是在问你如何想象和互动,在它们发生冲突的情况下(就像我列出的场景一样)。自动保证金根本不与它相互作用 - 它们在有机会使用它之前窃取了所有的包装空间。因此,自动利润率并不是一个很好的模拟工作方式。justify-selfjustify-contentjustify-contentjustify-content
1赞 gogo 8/6/2023
因为这将是一致的,并且会打破CSS长期以来的不一致传统。

答:

32赞 dholbert 9/15/2015 #1

这个问题在 www-style 列表中被问到,Tab Atkins(规范编辑器)给出了一个答案,解释了原因。我将在这里详细阐述这一点。

首先,我们首先假设我们的 flex 容器是单行 ()。在这种情况下,主轴和十字轴之间明显存在对齐差异 - 在主轴上堆叠了多个项目,但只有一个项目堆叠在十字轴上。因此,在十字轴中有一个可自定义的每个项目的“对齐自我”是有意义的(因为每个项目都是单独对齐的,单独对齐),而在主轴中没有意义(因为在那里,项目是集体对齐的)。flex-wrap: nowrap

对于多行 flexbox,相同的逻辑适用于每条“flex line”。在给定的行中,项目在十字轴中单独对齐(因为在十字轴中每行只有一个项目),而不是在主轴中整体对齐。


这是另一种表述方式:所以,所有的 和 属性都是关于如何在事物周围分配额外的空间。但关键的区别在于,版本适用于该轴中只有一个事物的情况,而版本适用于该轴中可能存在许多事物的情况。单事物方案与多事物方案是不同类型的问题,因此它们有不同类型的可用选项 -- 例如,/ 值对 有意义,但对 没有意义。*-self*-content*-self*-contentspace-aroundspace-between*-content*-self

SO:在弹性盒子的主轴中,有很多东西可以分配空间。因此,属性在那里有意义,但不是属性。*-content*-self

相比之下,在十字轴上,我们同时具有 a 和 a 属性。一个确定我们如何在许多弯曲线 () 周围分配空间,而另一个 () 确定如何在给定弯曲线内的十字轴中分配单个弯曲项目周围的空间。*-self*-contentalign-contentalign-self

(我在这里忽略了属性,因为它们只是为 .*-items*-self

评论

2赞 Mark 9/15/2015
我理解 a 在具有多个项目而不是一个项目的轴上如何成为问题。但是,我真的希望他们能进一步研究它,在多项目的情况下会如何表现,因为在某些情况下这可能非常有用。例如(stackoverflow.com/questions/32378953/...)。justify-selfjustify-self
0赞 Michael Benjamin 9/15/2015
在那个邮件列表上找到不错的结果。试图把我的头包裹起来,因为我仍然看到了很好的用例可能性。justify-self
0赞 dholbert 9/15/2015
我补充了更多的澄清,解释了我们只有一件事要对齐的情况,而关于我们有很多事情要对齐的情况。这是否使它更清楚一些?*-self*-content
0赞 Michael Benjamin 11/23/2015
是的,这更清楚。我很欣赏这个解释。但这似乎都归结为规范作者的简单偏好,而不是基于逻辑的特定需求。从您引用的邮件列表中*-self 属性仅在子项在该轴上独自一人时才起作用。为什么?似乎没有必要这样做。这是一个武断的决定。偏好。事实上,边距也是规范的一部分,它支持与行中的多个项目进行 *-自对齐。也没有明确的原因说明为什么关键字属性也不能。auto
230赞 Mark 9/15/2015 #2

我知道这不是一个答案,但我想为这件事做出贡献,因为它是值得的。如果他们能发布 flexbox 以使其真正灵活,那就太好了。justify-self

我相信,当轴上有多个项目时,最合乎逻辑的行为方式是将自身与其最近的邻居(或边缘)对齐,如下所示。justify-self

我真的希望 W3C 注意到这一点,并且至少会考虑它。=)

enter image description here

这样,无论左右框的大小如何,您都可以拥有真正居中的项目。当其中一个盒子到达中心盒子的点时,它只会推动它,直到没有更多的空间可以分配。

enter image description here

制作令人敬畏的布局的难易程度是无穷无尽的,看看这个“复杂”的例子。

enter image description here

评论

29赞 Zaqx 10/15/2015
@Mark这太棒了!感谢您抽出宝贵时间起草本文。我希望你不介意,但我在这里提交了:discourse.wicg.io/t/flexbox-justify-self-property/1146
4赞 Mark 10/19/2015
@Zaqx当然,曝光越多越好。真的希望他们能找到一种方法来实现这一目标,很想让我亲自动手。
1赞 Michael Benjamin 11/23/2015
嗨,马克,@Zaqx,我发布了一个答案,可能涵盖了这个答案中提到的一些用例。我发现在主轴上仍然可以做很多事情,而不需要和.justify-selfjustify-items
4赞 Zaqx 11/23/2015
@Michael_B 很高兴您正在了解有关 flexbox 的更多信息,并感谢您花时间将笔记格式化为答案。边距:auto 确实很酷(尽管您会发现实现 2009 年和 2012 年版 flexbox 规范的浏览器没有等效功能,这大大降低了在生产站点使用它的能力)。但是,即使使用支持 margin:auto 的浏览器,如果没有 justify-self 属性或类似属性,这里的主要用例仍然不可能在空间存在时相对于其容器居中。
1赞 Michael Benjamin 11/24/2015
@Zaqx,感谢您的反馈。是的,我同意你的看法,保证金不能完全替代.我小心翼翼地表达了我之前的评论,说边距将涵盖一些用例。如您所指出的,当相邻项目的大小不同时,它无法将项目居中。但是,它确实提供了更多用于对齐 flex 项目的选项。当我第一次开始学习 flexbox 时,我认为隐形垫片是唯一的方法。autojustify-selfautojustify-content
0赞 Simon_Weaver 10/30/2021
关于在另外两个项目之间居中某些内容,我最近不得不做同样的事情,并想出了使用 css 网格并将某些内容居中在固定边距内。随着页面的展开,第 1 列和第 3 列的大小相同(一旦页面宽度大于 1200+50+100),这意味着第 2 列是死中心。我将其用于“弹性”边距,但第 1 列和第 3 列同样可以包含实际内容,然后您可能会使用 .grid-template-columns: minmax(50px, 1fr) 1200px minmax(100px, 1fr)min-content
1894赞 Michael Benjamin 11/22/2015 #3

沿主轴对齐 Flex 项目的方法

如问题所述:

要沿主轴对齐 flex 项目,有一个属性:justify-content

要沿十字轴对齐 flex 项目,有三个属性:align-content、align-itemsalign-self

然后问题问:

为什么没有和属性?justify-itemsjustify-self

一个答案可能是:因为它们不是必需的。

flexbox 规范提供了两种沿主轴对齐 flex 项目的方法:

  1. 关键字属性,以及justify-content
  2. 自动保证金

对齐内容

justify-content 属性沿 flex 容器的主轴对齐 flex 项。

它应用于 flex 容器,但仅影响 flex 项目。

有五个对齐选项:

  • flex-start ~ Flex 物品被打包到生产线的起点。

    enter image description here

  • flex-end ~ Flex 物品被包装在生产线的末端。

    enter image description here

  • center ~ Flex 物品被打包到队伍的中心。

    enter image description here

  • 间距 ~ Flex 项目是均匀分布的,第一个项目与容器的一个边缘对齐,最后一个项目与相反的边缘对齐。第一项和最后一项使用的边缘取决于弯曲方向书写模式( 或 )。ltrrtl

    enter image description here

  • space-around ~ 除了两端有一半大小的空间外,与此相同。space-between

    enter image description here


自动边距

使用自动页边距,弹性项目可以居中、间隔或打包到子组中。

与应用于 flex 容器的 不同,flex 项目有边距。justify-contentauto

它们通过在指定方向上消耗所有可用空间来工作。


将一组 flex 项目向右对齐,但将第一个项目向左对齐

问题中的场景:

  • 使一组 Flex 项目右对齐 () 但让第一项向左对齐 (justify-content: flex-endjustify-self: flex-start)

    考虑包含一组导航项和徽标的标题部分。使用 justify-self,徽标可以左对齐,而导航项保持不变 最右边,整个事情平滑地调整(“弯曲”)到 不同的屏幕尺寸。

enter image description here

enter image description here


其他有用的方案:

enter image description here

enter image description here

enter image description here


在角落放置一个柔性项目

问题中的场景:

  • 将 Flex 项目放在角落.box { align-self: flex-end; justify-self: flex-end; }

enter image description here


垂直和水平居中 Flex 项目

enter image description here

margin: auto是 和 的替代项。justify-content: centeralign-items: center

而不是 flex 容器上的此代码:

.container {
    justify-content: center;
    align-items: center;
}

您可以在 flex 项目上使用它:

.box56 {
    margin: auto;
}

当将溢出容器的 flex 项居中时,此替代方法非常有用。


将一个 flex 项目居中,并在第一个项目和边缘之间将第二个 flex 项目居中

弹性容器通过分配可用空间来对齐弹性项目。

因此,为了创造相等的平衡,以便中间物品可以在容器中居中,而单个物品并排,必须引入平衡。

在下面的例子中,引入了不可见的第三柔性项目(方框61和68),以平衡“真实”项目(方框63和66)。

enter image description here

enter image description here

当然,这种方法在语义方面并不是什么好事。

或者,您可以使用伪元素而不是实际的 DOM 元素。或者您可以使用绝对定位。此处介绍了所有三种方法: 居中和对齐的柔性项目

注意:上面的示例仅在最外层的物品高度/宽度相等时才有效 - 就真正的居中而言。当弹性项目长度不同时,请参阅下一个示例。


当相邻项目的大小不同时,将 Flex 项目居中

问题中的场景:

  • 在一排三个柔性项目中,将中间项目固定在容器的中心 () 并将相邻的 项添加到容器边缘( 和 )。justify-content: centerjustify-self: flex-startjustify-self: flex-end

    请注意,如果相邻项具有不同的宽度,则 justify-content 属性上的值 space-around 和 space-between 不会使中间项相对于容器保持居中(请参阅演示)。

如前所述,除非所有 flex 项目都具有相等的宽度或高度(取决于 ),否则中间项目无法真正居中。这个问题为属性(当然是为处理任务而设计的)提供了强有力的理由。flex-directionjustify-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

enter image description here

解决方案#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>

其工作原理如下:

  • 顶级 div () 是一个 flex 容器。.container
  • 每个子 div () 现在都是一个 flex 项。.box
  • 给出每个项目是为了平均分配容器空间。.boxflex: 1
  • 现在,这些项目占用了行中的所有空间,并且宽度相等。
  • 将每个项目设置为一个(嵌套的)flex 容器,并添加 .justify-content: center
  • 现在,每个元素都是一个居中的 flex 项目。span
  • 使用弯曲边距左右移动外部 s。autospan

您也可以放弃并专门使用边距。justify-contentauto

但可以在这里工作,因为利润率总是有优先权。从规格:justify-contentauto

8.1. 与自动边距对齐

在通过 和 对齐之前,任何 正自由空间分布到该维度中的自动边距。justify-contentalign-self


justify-content:空间相同(概念)

回到 justify-content 一分钟,这里有一个关于另一个选项的想法。

  • space-same ~ 和 的混合体。Flex 项目是均匀间隔的 (like ),除了两端的半大小空间 (like ) 之外,两端都有全尺寸的空间。space-betweenspace-aroundspace-betweenspace-around

这种布局可以通过 flex 容器上的 ::before 和 ::after 伪元素来实现。

enter image description here

(来源:代码为 @oriol,标签为 @crl

更新:浏览器已经开始实现空间均匀,从而实现了上述目标。有关详细信息,请参阅此帖子: 弹性项目之间的空间相等


PLAYGROUND(包含上述所有示例的代码)

评论

4赞 Michael Benjamin 3/21/2017
上面的答案涵盖了主轴和边距。对于硬币的另一面 - 十字轴,和 - 请参阅此帖子: stackoverflow.com/q/42613359/3597276justify-contentautoalign-itemsalign-selfalign-content
5赞 Michael Benjamin 3/28/2017
@MarkW,您正在为该物业辩护...... 边距是有帮助的,但也是理想的。解决您提出的问题的方法是在另一侧创建不可见的重复项。在这里查看我的答案:stackoverflow.com/q/38948102/3597276justify-selfautojustify-self: center
8赞 benface 8/3/2017
你的概念现在是真实的。它被称为 ,但目前只有 Firefox 支持:developer.mozilla.org/en-US/docs/Web/CSS/justify-contentspace-samespace-evenly
1赞 Michael Benjamin 8/3/2017
@benface,是的,你是对的。感谢您指出这一点。实际上,我一直在其他答案中写过:stackoverflow.com/q/45134400/3597276space-evenly
3赞 MMMM 10/23/2020
我真的希望 CSS Consortium 的人(或者他们如何称呼自己)能够考虑 justify-self 的想法......我有时觉得很荒谬,你有时必须做多么复杂的变通办法来实现问题解决方案......好像有人真的知道你上面提到的那些“伎俩”;)
1赞 Venryx 7/21/2019 #4

我知道这不使用 flexbox,但对于三个项目(一个在左边,一个在中间,一个在右边)的简单用例,这可以很容易地在父项、子项上使用以及用于定位这些子项。display: gridgrid-area: 1/1/1/1;justify-self

<div style="border: 1px solid red; display: grid; width: 100px; height: 25px;">
  <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: left;"></div>
  <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: center;"></div>
  <div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: right;"></div>
</div>

评论

0赞 Michael Benjamin 7/21/2019
感谢您的回答,但它并没有真正解决问题。此外,还有一种更简单的方法来完成布局:jsfiddle.net/fga89m2o
1赞 Leif Messinger LOAF 4/17/2020 #5

我刚刚找到了我自己解决这个问题的方法,或者至少是我的问题。
我用而不是.
justify-content: space-aroundjustify-content: space-between;

这样,结束元素将粘在顶部和底部,如果需要,您可以自定义边距。

评论

0赞 TylerH 12/19/2023
这并不能回答这个问题。请仅提供直接解决 OP 所提问题的答案。
5赞 Wenfang Du 7/5/2020 #6

这是由于 flexbox 的一维性质,并且沿主轴可能有多个项目,因此无法证明单个项目的合理性。若要在 flexbox 中沿主内联轴对齐项目,请使用该属性。justify-content

参考:CSS 网格布局中的框对齐方式

评论

0赞 TylerH 12/19/2023
除了迈克尔·本杰明 (Michael Benjamin) 5 年前的回答之外,这似乎没有提供任何东西。在回答时,请确保您正在添加现有答案已经涵盖的内容之外的新信息。