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

3htmauhk  于 2023-01-03  发布在  其他
关注(0)|答案(6)|浏览(144)

考虑Flex容器的主轴和横轴:


来源:W3C语言
要沿主轴对齐挠性项目,有一个属性:

  • 第一个月

要沿横轴对齐挠性项目,有三个属性:

  • align-content
  • align-items
  • align-self

在上图中,主轴是水平的,横轴是垂直的。这是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;

(The横轴始终垂直于主轴。)
在描述坐标轴的工作原理时,我的观点是,两个方向似乎都没有什么特别之处,主轴、横轴,它们在重要性上都是相等的,flex-direction使它很容易来回切换。

  • 那么为什么横轴会有两个额外的对齐属性呢?*
  • 为什么align-contentalign-items合并为主轴的一个属性?*
  • 为什么主轴没有justify-self属性?*

这些属性有用的场景:

  • 将柔性物品放置在柔性容器的角落中

#box3 { align-self: flex-end; justify-self: flex-end; }

  • 使一组弹性项目右对齐(justify-content: flex-end),但使第一个项目左对齐(justify-self: flex-start
  • 考虑一个带有一组导航项和一个徽标的页眉部分。使用justify-self,徽标可以左对齐,而导航项保持最右,整个内容可以平滑地调整("灵活")以适应不同的屏幕大小。*
  • 在一行三个柔性部件中,将中间部件粘贴到容器中心(justify-content: center),并将相邻部件与容器边缘对齐(justify-self: flex-startjustify-self: flex-end)。
  • 请注意,如果相邻项的宽度不同,则justify-content属性的值space-aroundspace-between不会使中间项保持在容器的中心。*

x一个一个一个一个x一个一个二个x
jsFiddle version
在撰写本文时,flexbox spec中还没有提到justify-selfjustify-items
然而,在CSS Box Alignment Module中,W3C未完成的建议是建立一组通用的对齐属性,以供所有盒子模型使用,其中有:


资料来源:W3C
您会注意到,我们正在考虑justify-selfjustify-items ... * 但不考虑Flexbox *。
最后,我要重申一个主要问题:
为什么没有"正当项目"和"正当自我"属性?

vmjh9lq9

vmjh9lq91#

沿主轴对齐Flex项目的方法

正如问题所述:
要沿主轴对齐挠性项目,有一个属性:第一个月
要沿横轴对齐挠性项目,有三个属性:x一米一纳米一x、x一米二纳米一x和x一米三纳米一x。
然后,问题是:
为什么没有justify-itemsjustify-self属性?
一个答案可能是:* 因为他们没有必要 *
flexbox specification提供了 * 两种 * 沿主轴对齐flex项目的方法:

  1. justify-content关键字属性,以及
  2. auto利润

* 调整内容 *

justify-content属性沿flex容器的主轴对齐flex项。
它应用于Flex容器,但仅影响Flex项。
有五个对齐选项:

      • flex-start**~弹性物料朝向生产线的起点装箱。

      • flex-end**~Flex项目在接近行的末尾处打包。

      • center**~弹性物料朝向生产线中心 Package 。

      • space-between**~Flex项间距相等,第一项与容器的一边对齐,最后一项与容器的另一边对齐。第一项和最后一项使用的边取决于flex-directionwriting modeltrrtl)。

      • space-around**~与space-between相同,只是两端的空格减半。

自动边距

使用auto边距,Flex项目可以居中、隔开或打包成子组。
与应用于flex容器的justify-content不同,auto边距应用于flex项。
它们的工作原理是消耗指定方向上的所有可用空间。

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

问题中的情景:

  • 使一组弹性项目右对齐(justify-content: flex-end),但使第一个项目左对齐(justify-self: flex-start
  • 考虑一个带有一组导航项和一个徽标的页眉部分。使用justify-self,徽标可以左对齐,而导航项保持最右,整个内容可以平滑地调整("灵活")以适应不同的屏幕大小。*

其他有用的情景:

将Flex项目放在角落

问题中的情景:

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

将Flex项目垂直和水平居中

margin: autojustify-content: centeralign-items: center的替代产品。
代替flex容器上的以下代码:

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

您可以在弹性项目上使用此选项:

.box56 {
    margin: auto;
}

此替代方法在centering a flex item that overflows the container时很有用。

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

Flex容器通过分配可用空间来对齐Flex项。
因此,为了创造"相等的平衡",使中间的物品能够与旁边的单个物品一起放在容器的中心,必须引入平衡物。
在下面的例子中,引入不可见的第三弹性项目(框61和68)以平衡"真实"项目(框63和66)。

当然,这种方法在语义方面没什么了不起。
或者,您可以使用伪元素来代替实际的DOM元素。或者您可以使用绝对定位。下面将介绍所有这三种方法:* * 一个月三次**

  • 注意:以上示例仅在最外面的项目高度/宽度相等时才能正确居中。当Flex项目长度不同时,请参见下一示例。*

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

问题中的情景:

  • 在一行三个柔性部件中,将中间部件固定在容器中心(justify-content: center),并将相邻部件与容器边缘对齐(justify-self: flex-startjustify-self: flex-end)。
  • 请注意,如果相邻项具有不同的宽度(see demo),则justify-content属性上的值space-aroundspace-between不会使中间项相对于容器居中。*

如前所述,除非所有flex项的宽度或高度相同(取决于flex-direction),否则中间项无法真正居中。这个问题为justify-self属性(当然是为了处理任务而设计的)提供了一个强有力的理由。
一个二个一个一个

  • 以下是解决此问题的两种方法:*
    溶液#1:绝对定位

Flexbox规范允许Flex项目的绝对定位。这允许中间项目完全居中,而不管其兄弟项目的大小。
请记住,像所有绝对定位的元素一样,这些项将从文档流中移除,这意味着它们不会占用容器中的空间,并且可以与它们的兄弟元素重叠。
在下面的示例中,中间项使用绝对定位居中,而外部项保持在流中。但是,可以使用相反的方式实现相同的布局:用justify-content: center将中间项目居中,并绝对定位外部项目。

溶液#2:嵌套灵活容器(无绝对定位)

.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(.container)是一个flex容器。

  • 每个子div(.box)现在都是一个flex项。

  • 为每个.box项指定flex: 1,以便平均分配容器空间。

  • 现在,这些项占用了行中的所有空间,并且宽度相等。

  • 使每个项目成为一个(嵌套的)flex容器,并添加justify-content: center

  • 现在,每个span元素都是一个居中的Flex项目。

  • 使用flex auto边距左右移动外部span

您还可以放弃justify-content,而专门使用auto边距。
但是justify-content可以在这里工作,因为auto保证金总是优先的。

8.1.按auto边距对齐

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

* 理由-内容:空间相同(概念)*

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

*space-same~ space-betweenspace-around的混合体。Flex项的间距是均匀的(如space-between),只是两端不是一半大小的间距(如space-around),而是全大小的间距。

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

  • (署名:@oriol代表代码,@crl代表标签)*
    更新:浏览器已经开始实现space-evenly,它完成了上述任务。详情请看这篇文章:Equal space between flex items

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

sqyvllje

sqyvllje2#

我知道这不是一个答案,但我想为这件事做出贡献,如果他们能为flexbox发布justify-self,使其真正灵活,那就太好了。
我相信,当轴上有多个项目时,justify-self最合乎逻辑的行为方式是将其自身与最近的邻居(或边)对齐,如下所示。
我真的希望,W3C注意到这一点,至少会考虑一下。

这样,您就可以拥有一个真正居中的项目,而不管左框和右框的大小。当其中一个框到达中心框的点时,它将简单地推动它,直到没有更多的空间可供分配。

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

mutmk8jj

mutmk8jj3#

这是在www风格的列表和Tab阿特金斯(规范编辑器)provided an answer explaining why中提出的,我将在这里详细说明。
首先,我们假设Flex容器是单行的在这种情况下,主轴和横轴之间明显存在对齐差异--主轴中堆叠了多个项,但横轴中仅堆叠了一个项,因此在横轴中具有可定制的每项“align-self”是有意义的(因为每个项都是单独对齐的),而在主轴上则没有意义(因为在主轴上,项是集体对齐的)。
对于多行弹性框,相同的逻辑适用于每个“弹性行”。在给定行中,项目在横轴中单独对齐(因为在横轴中每行只有一个项目),而在主轴中统一对齐。
这里有另一种说法:因此,*-self*-content的所有属性都是关于如何分配物体周围的额外空间,但关键的区别在于*-self版本是针对"在该轴上只有一个物体“的情况,而*-content版本则适用于 * 该轴上可能存在许多事物 * 的情况。一个事物与许多事物-things场景是不同类型的问题,因此它们具有不同类型的可用选项--例如,space-around/space-between值对于*-content有意义,但对于*-self没有意义。
SO:在Flexbox的主轴上,有很多东西需要分配空间,所以*-content属性在这里是有意义的,但*-self属性就没有意义了。
相反,在横轴中,我们同时具有*-self*-content属性。其中一个属性确定如何在“许多”伸缩线(align-content)周围分配空间,而另一个属性(align-self)确定如何在给定伸缩线内的横轴中“单个”伸缩项周围分配空间。
(这里我忽略了*-items属性,因为它们只是为*-self建立默认值。)

dfuffjeb

dfuffjeb4#

    • 这是由于弹性框的一维特性,并且轴上可能有多个项目,因此无法对齐单个项目**。要沿弹性框中的主内联轴对齐项目,请使用justify-content属性。

参考:Box alignment in CSS Grid Layout

bybem2ql

bybem2ql5#

我知道这不使用flexbox,但是对于三个项目(一个在左边,一个在中间,一个在右边)的简单用例,这可以很容易地完成,在父级上使用display: grid,在子级上使用grid-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>
vnzz0bqm

vnzz0bqm6#

我刚刚找到了自己解决这个问题的方法,或者至少是我的问题。
我使用的是justify-content: space-around,而不是justify-content: space-between;
这样,结束元素将粘在顶部和底部,如果需要,您可以自定义边距。

相关问题