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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32551291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 11:28:10  来源:igfitidea点击:

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

cssflexboxlanguage-lawyerw3c

提问by Michael Benjamin

Consider the main axis and cross axis of a flex container:

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

enter image description here                                                                                                                                                   Source: W3C

在此处输入图片说明                                                                                                                                                   资料来源:W3C

To align flex items along the main axis there is one property:

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

To align flex items along the cross axis there are three properties:

要沿交叉轴对齐 flex 项目,有三个属性:

In the image above, the main axis is horizontal and the cross axis is vertical. These are the default directions of a flex container.

在上图中,主轴是水平的,横轴是垂直的。这些是 flex 容器的默认方向。

However, these directions can be easily interchanged with the flex-directionproperty.

但是,这些方向可以很容易地与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 cross axis is always perpendicular to the main axis.)

(横轴总是垂直于主轴。)

My point in describing how the axes' work is that there doesn't seem to be anything special about either direction. Main axis, cross axis, they're both equal in terms of importance and flex-directionmakes it easy to switch back and forth.

我在描述轴如何工作时的观点是,这两个方向似乎都没有什么特别之处。主轴,交叉轴,它们在重要性方面都是相同的,并且flex-direction可以轻松地来回切换。

So why does the cross axis get two additional alignment properties?

那么为什么交叉轴会获得两个额外的对齐属性呢?

Why are align-contentand align-itemsconsolidated into one property for the main axis?

为什么align-contentalign-items合并为主轴的一个属性?

Why does the main axis not get a justify-selfproperty?

为什么主轴没有得到justify-self属性?



Scenarios where these properties would be useful:

这些属性有用的场景:

  • placing a flex item in the corner of the flex container
    #box3 { align-self: flex-end; justify-self: flex-end; }

  • making a group of flex items align-right (justify-content: flex-end) but have the first item align left (justify-self: flex-start)

    Consider a header section with a group of nav items and a logo. With justify-selfthe logo could be aligned left while the nav items stay far right, and the whole thing adjusts smoothly ("flexes") to different screen sizes.

  • in a row of three flex items, affix the middle item to the center of the container (justify-content: center) and align the adjacent items to the container edges (justify-self: flex-startand justify-self: flex-end).

    Note that values space-aroundand space-betweenon justify-contentproperty will not keep the middle item centered about the container if the adjacent items have different widths.

  • 在 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-startjustify-self: flex-end)对齐。

    请注意,如果相邻项目具有不同的宽度,则 valuesspace-aroundspace-betweenon justify-content属性不会使中间项目以容器为中心。

#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 version

jsFiddle 版本



As of this writing, there is no mention of justify-selfor justify-itemsin the flexbox spec.

在撰写本文时,有没有提及justify-selfjustify-itemsFlexbox的规范

However, in the CSS Box Alignment Module, which is the W3C's unfinished proposal to establish a common set of alignment properties for use across all box models, there is this:

但是,在CSS Box Alignment Module 中,这是 W3C 未完成的提议,旨在建立一组通用的对齐属性以供所有框模型使用,其中包含以下内容:

enter image description here                                                                                                                                                   Source: W3C

在此处输入图片说明                                                                                                                                                   资料来源:W3C

You'll notice that justify-selfand justify-itemsare being considered... but not for flexbox.

您会注意到,justify-self并且justify-items正在考虑...但不适用于 flexbox



I'll end by reiterating the main question:

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

Why are there no "justify-items" and "justify-self" properties?

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

回答by Michael Benjamin

Methods for Aligning Flex Items along the Main Axis

沿主轴对齐 Flex 项目的方法

As stated in the question:

如问题所述:

To align flex items along the main axis there is one property: justify-content

To align flex items along the cross axis there are three properties: align-content, align-itemsand align-self.

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

要沿横轴对齐 flex 项,有三个属性:align-content,align-itemsalign-self

The question then asks:

然后问题问:

Why are there no justify-itemsand justify-selfproperties?

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

One answer may be: Because they're not necessary.

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

The flexbox specificationprovides twomethods for aligning flex items along the main axis:

所述Flexbox的规范提供2点用于对准沿主轴弯曲的物品的方法:

  1. The justify-contentkeyword property, and
  2. automargins
  1. justify-content关键字属性,
  2. auto边距


justify-content

证明内容

The justify-contentproperty aligns flex items along the main axis of the flex container.

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

It is applied to the flex container but only affects flex items.

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

There are five alignment options:

有五个对齐选项:

  • flex-start~ Flex items are packed toward the start of the line.

    enter image description here

  • flex-end~ Flex items are packed toward the end of the line.

    enter image description here

  • center~ Flex items are packed toward the center of the line.

    enter image description here

  • space-between~ Flex items are evenly spaced, with the first item aligned to one edge of the container and the last item aligned to the opposite edge. The edges used by the first and last items depends on flex-directionand writing mode(ltror rtl).

    enter image description here

  • space-around~ Same as space-betweenexcept with half-size spaces on both ends.

    enter image description here

  • flex-start~ Flex 项目被打包到生产线的开头。

    在此处输入图片说明

  • flex-end~ Flex 项目被打包到行尾。

    在此处输入图片说明

  • center~ Flex 项目被包装到线的中心。

    在此处输入图片说明

  • space-between~ Flex 项目均匀分布,第一个项目与容器的一个边缘对齐,最后一个项目与相对的边缘对齐。第一个和最后一个项目使用的边取决于flex-direction书写模式ltrrtl)。

    在此处输入图片说明

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

    在此处输入图片说明



Auto Margins

自动保证金

With automargins, flex items can be centered, spaced away or packed into sub-groups.

使用automargins,弹性项目可以居中、间隔开或打包成子组。

Unlike justify-content, which is applied to the flex container, automargins go on flex items.

justify-content应用于 flex 容器的 不同,auto边距适用于 flex 项目。

They work by consuming all free space in the specified direction.

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



Align group of flex items to the right, but first item to the left

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

Scenario from the question:

问题中的场景:

  • making a group of flex items align-right (justify-content: flex-end) but have the first item align left (justify-self: flex-start)

    Consider a header section with a group of nav items and a logo. With justify-selfthe logo could be aligned left while the nav items stay far right, and the whole thing adjusts smoothly ("flexes") to different screen sizes.

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

    考虑带有一组导航项目和徽标的标题部分。当 justify-self导航项目保持在最右侧时,徽标可以向左对齐,并且整个事情可以平滑地调整(“弯曲”)以适应不同的屏幕尺寸。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明



Other useful scenarios:

其他有用的场景:

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明



Place a flex item in the corner

在角落放置一个弹性项目

Scenario from the question:

问题中的场景:

  • placing a flex item in a corner .box { align-self: flex-end; justify-self: flex-end; }
  • 在角落里放置一个弹性项目 .box { align-self: flex-end; justify-self: flex-end; }

enter image description here

在此处输入图片说明



Center a flex item vertically and horizontally

垂直和水平居中一个弹性项目

enter image description here

在此处输入图片说明

margin: autois an alternative to justify-content: centerand align-items: center.

margin: auto是可替换的justify-content: centeralign-items: center

Instead of this code on the flex container:

而不是 flex 容器上的这段代码:

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

You can use this on the flex item:

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

.box56 {
    margin: auto;
}

This alternative is useful when centering a flex item that overflows the container.

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



Center a flex item, and center a second flex item between the first and the edge

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

A flex container aligns flex items by distributing free space.

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

Hence, in order to create equal balance, so that a middle item can be centered in the container with a single item alongside, a counterbalance must be introduced.

因此,为了创造相等的平衡,使一个中间项目可以在容器中居中,一个项目在旁边,必须引入平衡。

In the examples below, invisible third flex items (boxes 61 & 68) are introduced to balance out the "real" items (box 63 & 66).

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

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

Of course, this method is nothing great in terms of semantics.

当然,这种方法在语义上没什么了不起。

Alternatively, you can use a pseudo-element instead of an actual DOM element. Or you can use absolute positioning. All three methods are covered here: Center and bottom-align flex items

或者,您可以使用伪元素而不是实际的 DOM 元素。或者您可以使用绝对定位。这里涵盖了所有三种方法:Center and bottom-align flex items

NOTE: The examples above will only work – in terms of true centering – when the outermost items are equal height/width. When flex items are different lengths, see next example.

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



Center a flex item when adjacent items vary in size

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

Scenario from the question:

问题中的场景:

  • in a row of three flex items, affix the middle item to the center of the container (justify-content: center) and align the adjacent items to the container edges (justify-self: flex-startand justify-self: flex-end).

    Note that values space-aroundand space-betweenon justify-contentproperty will not keep the middle item centered in relation to the container if the adjacent items have different widths (see demo).

  • 在三个 flex 项目的一行中,将中间项目固定到容器的中心 ( justify-content: center) 并将相邻的项目与容器边缘 (justify-self: flex-startjustify-self: flex-end)对齐。

    请注意,如果相邻项目具有不同的宽度,则 valuesspace-aroundspace-betweenonjustify-content属性不会使中间项目相对于容器居中(参见演示)。

As noted, unless all flex items are of equal width or height (depending on flex-direction), the middle item cannot be truly centered. This problem makes a strong case for a justify-selfproperty (designed to handle the task, of course).

如前所述,除非所有 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>

Here are two methods for solving this problem:

这里有两种方法可以解决这个问题:

Solution #1: Absolute Positioning

解决方案#1:绝对定位

The flexbox spec allows for absolute positioning of flex items. This allows for the middle item to be perfectly centered regardless of the size of its siblings.

flexbox 规范允许对flex items进行绝对定位。这允许中间项目完全居中,而不管其兄弟姐妹的大小。

Just keep in mind that, like all absolutely positioned elements, the items are removed from the document flow. This means they don't take up space in the container and can overlap their siblings.

请记住,与所有绝对定位的元素一样,项目将从文档流中删除。这意味着它们不占用容器中的空间并且可以重叠它们的兄弟。

In the examples below, the middle item is centered with absolute positioning and the outer items remain in-flow. But the same layout can be achieved in reverse fashion: Center the middle item with justify-content: centerand absolutely position the outer items.

在下面的示例中,中间项目以绝对定位居中,而外部项目保持流入。但是可以以相反的方式实现相同的布局:将中间项目与justify-content: center外部项目居中并绝对定位。

enter image description here

在此处输入图片说明

Solution #2: Nested Flex Containers (no absolute positioning)

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

Here's how it works:

这是它的工作原理:

  • The top-level div (.container) is a flex container.
  • Each child div (.box) is now a flex item.
  • Each .boxitem is given flex: 1in order to distribute container space equally.
  • Now the items are consuming all space in the row and are equal width.
  • Make each item a (nested) flex container and add justify-content: center.
  • Now each spanelement is a centered flex item.
  • Use flex automargins to shift the outer spans left and right.
  • 顶层 div ( .container) 是一个 flex 容器。
  • 每个子 div ( .box) 现在都是一个弹性项目。
  • .box给出每个项目是flex: 1为了平均分配容器空间。
  • 现在这些项目消耗了行中的所有空间并且宽度相等。
  • 使每个项目成为(嵌套的)弹性容器并添加justify-content: center.
  • 现在每个span元素都是一个居中的弹性项目。
  • 使用 flex automargins 左右移动外部spans。

You could also forgo justify-contentand use automargins exclusively.

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

But justify-contentcan work here because automargins always have priority. From the spec:

justify-content可以在这里工作,因为auto利润率总是优先的。从规范:

8.1. Aligning with automargins

Prior to alignment via justify-contentand align-self, any positive free space is distributed to auto margins in that dimension.

8.1. 与auto边距对齐

在通过justify-content和对齐之前align-self,任何正自由空间都会分配到该维度的自动边距。



justify-content: space-same (concept)

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

Going back to justify-contentfor a minute, here's an idea for one more option.

回到justify-content一分钟,这里有一个更多选择的想法。

  • space-same~ A hybrid of space-betweenand space-around. Flex items are evenly spaced (like space-between), except instead of half-size spaces on both ends (like space-around), there are full-size spaces on both ends.
  • space-same〜的混合space-betweenspace-around。Flex 项目是均匀间隔的(如space-between),除了两端的半尺寸空间(如space-around)之外,两端都有全尺寸的空间。

This layout can be achieved with ::beforeand ::afterpseudo-elements on the flex container.

这种布局可以用能够实现::before::after柔性容器上伪元素。

enter image description here

在此处输入图片说明

(credit: @oriolfor the code, and @crlfor the label)

(信用:@oriol代码,@crl标签)

UPDATE:Browsers have begun implementing space-evenly, which accomplishes the above. See this post for details: Equal space between flex items

更新:浏览器已经开始实施space-evenly,它完成了上述工作。有关详细信息,请参阅此帖子:弹性项目之间的等距



PLAYGROUND(includes code for all examples above)

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

回答by Mark

I know this is not an answer, but I'd like to contribute to this matter for what it's worth. It would be great if they could release justify-selffor flexbox to make it truly flexible.

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

It's my belief that when there are multiple items on the axis, the most logical way for justify-selfto behave is to align itself to its nearest neighbours (or edge) as demonstrated below.

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

I truly hope, W3C takes notice of this and will at least consider it. =)

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

enter image description here

在此处输入图片说明

This way you can have an item that is truly centered regardless of the size of the left and right box. When one of the boxes reaches the point of the center box it will simply push it until there is no more space to distribute.

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

enter image description here

在此处输入图片说明

The ease of making awesome layouts are endless, take a look at this "complex" example.

制作很棒的布局的难易是无穷无尽的,看看这个“复杂”的例子。

enter image description here

在此处输入图片说明

回答by dholbert

This was asked on the www-style list, and Tab Atkins (spec editor) provided an answer explaining why. I'll elaborate on that a bit here.

这是在 www 样式列表中提出的问题,Tab Atkins(规范编辑器)提供了解释原因的答案。我将在这里详细说明。

To start out, let's initially assume our flex container is single-line (flex-wrap: nowrap). In this case, there's clearly an alignment difference between the main axis and the cross axis -- there are multiple items stacked in the main axis, but only one item stacked in the cross axis. So it makes sense to have a customizeable-per-item "align-self" in the cross axis (since each item is aligned separately, on its own), whereas it doesn't make sense in the main axis (since there, the items are aligned collectively).

首先,让我们首先假设我们的 flex 容器是单行的 ( flex-wrap: nowrap)。在这种情况下,主轴和横轴之间显然存在对齐差异——主轴上堆叠了多个项目,但横轴上仅堆叠了一个项目。所以在横轴上有一个可定制的每项“align-self”是有意义的(因为每个项目都是单独对齐的,单独对齐),而在主轴上没有意义(因为那里,项目集体对齐)。

For multi-line flexbox, the same logic applies to each "flex line". In a given line, items are aligned individually in the cross axis (since there's only one item per line, in the cross axis), vs. collectively in the main axis.

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



Here's another way of phrasing it: so, allof the *-selfand *-contentproperties are about how to distribute extra space around things. But the key difference is that the *-selfversions are for cases where there's only a single thing in that axis, and the *-contentversions are for when there are potentially many things in that axis. The one-thing vs. many-things scenarios are different types of problems, and so they have different types of options available -- for example, the space-around/ space-betweenvalues make sense for *-content, but not for *-self.

这是另一种表述方式:因此,所有*-self*-content属性都是关于如何在事物周围分配额外空间。但关键的区别在于,*-self版本适用于该轴上只有一个事物的情况,而*-content版本适用于该轴上可能有很多事物的情况。one-thing vs. many-things 场景是不同类型的问题,因此它们有不同类型的可用选项——例如,space-around/space-between值对 有意义*-content,但对 无效*-self

SO: In a flexbox's main axis, there are many things to distribute space around. So a *-contentproperty makes sense there, but not a *-selfproperty.

SO:在 flexbox 的主轴上,有很多东西可以分配空间。所以*-content属性在那里有意义,但不是*-self属性。

In contrast, in the cross axis, we have both a *-selfand a *-contentproperty. One determines how we'll distribute space around the manyflex lines (align-content), whereas the other (align-self) determines how to distribute space around individualflex items in the cross axis, within a given flex line.

相反,在交叉轴上,我们同时拥有 a*-self和 a*-content属性。一个决定我们如何在许多弹性线 ( align-content)周围分配空间,而另一个 ( align-self) 决定如何在给定的弹性线​​内在横轴上的单个弹性项目周围分配空间。

(I'm ignoring *-itemsproperties here, since they simply establish defaults for *-self.)

(我在*-items这里忽略了属性,因为它们只是为 建立默认值*-self。)

回答by Venryx

I know this doesn't use flexbox, but for the simple use-case of three items (one at left, one at center, one at right), this can be accomplished easily using display: gridon the parent, grid-area: 1/1/1/1;on the children, and justify-selffor positioning of those children.

我知道这不使用 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>

回答by Leif Messinger LOAF

I just found my own solution to this problem, or at least my problem.
I was using justify-content: space-aroundinstead of justify-content: space-between;.

我刚刚找到了我自己的解决方案,或者至少是我的问题。
我正在使用justify-content: space-around而不是justify-content: space-between;.

This way the end elements will stick to the top and bottom, and you could have custom margins if you wanted.

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