在 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
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
提问by Michael Benjamin
Consider the main axis and cross axis of a flex container:
考虑 flex 容器的主轴和横轴:
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-direction
property.
但是,这些方向可以很容易地与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-direction
makes it easy to switch back and forth.
我在描述轴如何工作时的观点是,这两个方向似乎都没有什么特别之处。主轴,交叉轴,它们在重要性方面都是相同的,并且flex-direction
可以轻松地来回切换。
So why does the cross axis get two additional alignment properties?
那么为什么交叉轴会获得两个额外的对齐属性呢?
Why are align-content
and align-items
consolidated into one property for the main axis?
为什么align-content
和align-items
合并为主轴的一个属性?
Why does the main axis not get a justify-self
property?
为什么主轴没有得到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-self
the 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-start
andjustify-self: flex-end
).Note that values
space-around
andspace-between
onjustify-content
property 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-start
和justify-self: flex-end
)对齐。请注意,如果相邻项目具有不同的宽度,则 values
space-around
和space-between
onjustify-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>
As of this writing, there is no mention of justify-self
or justify-items
in the flexbox spec.
在撰写本文时,有没有提及justify-self
或justify-items
在Flexbox的规范。
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 未完成的提议,旨在建立一组通用的对齐属性以供所有框模型使用,其中包含以下内容:
Source: W3C
资料来源:W3C
You'll notice that justify-self
and justify-items
are 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-items
andalign-self
.
要沿主轴对齐 flex 项目,有一个属性:
justify-content
要沿横轴对齐 flex 项,有三个属性:
align-content
,align-items
和align-self
。
The question then asks:
然后问题问:
Why are there no
justify-items
andjustify-self
properties?
为什么没有
justify-items
和justify-self
属性?
One answer may be: Because they're not necessary.
一个答案可能是:因为它们不是必需的。
The flexbox specificationprovides twomethods for aligning flex items along the main axis:
所述Flexbox的规范提供2点用于对准沿主轴弯曲的物品的方法:
- The
justify-content
keyword property, and auto
margins
- 该
justify-content
关键字属性, auto
边距
justify-content
证明内容
The justify-content
property 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.flex-end
~ Flex items are packed toward the end of the line.center
~ Flex items are packed toward the center of the line.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 onflex-direction
and writing mode(ltr
orrtl
).space-around
~ Same asspace-between
except with half-size spaces on both ends.
flex-start
~ Flex 项目被打包到生产线的开头。flex-end
~ Flex 项目被打包到行尾。center
~ Flex 项目被包装到线的中心。space-between
~ Flex 项目均匀分布,第一个项目与容器的一个边缘对齐,最后一个项目与相对的边缘对齐。第一个和最后一个项目使用的边取决于flex-direction
和书写模式(ltr
或rtl
)。space-around
~space-between
除了两端有一半大小的空格外,相同。
Auto Margins
自动保证金
With auto
margins, flex items can be centered, spaced away or packed into sub-groups.
使用auto
margins,弹性项目可以居中、间隔开或打包成子组。
Unlike justify-content
, which is applied to the flex container, auto
margins 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-self
the 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
导航项目保持在最右侧时,徽标可以向左对齐,并且整个事情可以平滑地调整(“弯曲”)以适应不同的屏幕尺寸。
Other useful scenarios:
其他有用的场景:
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; }
Center a flex item vertically and horizontally
垂直和水平居中一个弹性项目
margin: auto
is an alternative to justify-content: center
and align-items: center
.
margin: auto
是可替换的justify-content: center
和align-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)。
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-start
andjustify-self: flex-end
).Note that values
space-around
andspace-between
onjustify-content
property 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-start
和justify-self: flex-end
)对齐。请注意,如果相邻项目具有不同的宽度,则 values
space-around
和space-between
onjustify-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-self
property (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: center
and absolutely position the outer items.
在下面的示例中,中间项目以绝对定位居中,而外部项目保持流入。但是可以以相反的方式实现相同的布局:将中间项目与justify-content: center
外部项目居中并绝对定位。
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
.box
item is givenflex: 1
in 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
span
element is a centered flex item. - Use flex
auto
margins to shift the outerspan
s left and right.
- 顶层 div (
.container
) 是一个 flex 容器。 - 每个子 div (
.box
) 现在都是一个弹性项目。 .box
给出每个项目是flex: 1
为了平均分配容器空间。- 现在这些项目消耗了行中的所有空间并且宽度相等。
- 使每个项目成为(嵌套的)弹性容器并添加
justify-content: center
. - 现在每个
span
元素都是一个居中的弹性项目。 - 使用 flex
auto
margins 左右移动外部span
s。
You could also forgo justify-content
and use auto
margins exclusively.
您也可以放弃justify-content
并auto
专门使用边距。
But justify-content
can work here because auto
margins always have priority. From the spec:
但justify-content
可以在这里工作,因为auto
利润率总是优先的。从规范:
8.1. Aligning with
auto
marginsPrior to alignment via
justify-content
andalign-self
, any positive free space is distributed to auto margins in that dimension.
在通过
justify-content
和对齐之前align-self
,任何正自由空间都会分配到该维度的自动边距。
justify-content: space-same (concept)
justify-content:空间相同(概念)
Going back to justify-content
for a minute, here's an idea for one more option.
回到justify-content
一分钟,这里有一个更多选择的想法。
space-same
~ A hybrid ofspace-between
andspace-around
. Flex items are evenly spaced (likespace-between
), except instead of half-size spaces on both ends (likespace-around
), there are full-size spaces on both ends.
space-same
〜的混合space-between
和space-around
。Flex 项目是均匀间隔的(如space-between
),除了两端的半尺寸空间(如space-around
)之外,两端都有全尺寸的空间。
This layout can be achieved with ::before
and ::after
pseudo-elements on the flex container.
这种布局可以用能够实现::before
和::after
柔性容器上伪元素。
(credit: @oriolfor the code, and @crlfor the label)
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-self
for flexbox to make it truly flexible.
我知道这不是一个答案,但我想为这件事做出贡献。如果他们能够发布justify-self
flexbox 以使其真正灵活,那就太好了。
It's my belief that when there are multiple items on the axis, the most logical way for justify-self
to 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 会注意到这一点,并且至少会考虑一下。=)
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.
这样,无论左右框的大小如何,您都可以获得真正居中的项目。当其中一个盒子到达中心盒子的点时,它会简单地推动它,直到没有更多的空间可以分配。
The ease of making awesome layouts are endless, take a look at this "complex" example.
制作很棒的布局的难易是无穷无尽的,看看这个“复杂”的例子。
回答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 *-self
and *-content
properties are about how to distribute extra space around things. But the key difference is that the *-self
versions are for cases where there's only a single thing in that axis, and the *-content
versions 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-between
values 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 *-content
property makes sense there, but not a *-self
property.
SO:在 flexbox 的主轴上,有很多东西可以分配空间。所以*-content
属性在那里有意义,但不是*-self
属性。
In contrast, in the cross axis, we have both a *-self
and a *-content
property. 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 *-items
properties 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: grid
on the parent, grid-area: 1/1/1/1;
on the children, and justify-self
for 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-around
instead 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.
这样,结束元素将粘在顶部和底部,如果需要,您可以自定义边距。