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

Mic*_*l_B 602 css w3c language-lawyer flexbox

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

在此输入图像描述                                                                                                                        资料来源:W3C

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

要沿横轴对齐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;
Run Code Online (Sandbox Code Playgroud)

(横轴始终垂直于主轴.)

我在描述轴的工作方式时的观点是,任何一个方向似乎都没有什么特别之处.主轴,横轴,它们在重要性方面都是相同的,并且flex-direction可以方便地来回切换.

那么为什么横轴有两个额外的对齐属性呢?

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

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


这些属性有用的场景:

  • 将flex项放在flex容器的角落
    #box3 { align-self: flex-end; justify-self: flex-end; }

  • 制作一组flex项目align-right(justify-content: flex-end)但是让第一个项目对齐left(justify-self: flex-start)

    考虑带有一组导航项和徽标的标题部分.随着justify-self徽标可以左对齐,而导航项目保持最右边,整个事物平滑地调整("弯曲")到不同的屏幕尺寸.

  • 在一排三个柔性物品中,将中间物品粘贴到容器的中心(justify-content: center)并将相邻的物品对齐到容器边缘(justify-self: flex-startjustify-self: flex-end).

    请注意,如果相邻项具有不同的宽度,则值space-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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

jsFiddle版本


在撰写本文时,没有提及justify-selfjustify-itemsflexbox规范中.

但是,在CSS Box Alignment Module中,这是W3C未完成的建议,用于建立一套通用的对齐属性,以便在所有盒子模型中使用,这有:

在此输入图像描述                                                                                                                         资料来源:W3C

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


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

为什么没有"理由 - 物品"和"自我辩护"属性?

Mic*_*l_B 1128

沿主轴对齐Flex项的方法

如问题所述:

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

要对齐沿横轴弯曲项目有三个属性:align-content,align-itemsalign-self.

然后问题是:

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

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

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

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

证明内容

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

它适用于Flex容器,但仅影响flex项目.

有五种对齐选项:

  • flex-start ~Flex项目在行的开头打包.

    在此输入图像描述

  • flex-end ~Flex项目在行尾填充.

    在此输入图像描述

  • center ~Flex项目朝向线条的中心打包.

    在此输入图像描述

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

    在此输入图像描述

  • space-around〜与space-between两端的半尺寸空间相同.

    在此输入图像描述


自动保证金

利用auto边距,弹性项目可以居中,间隔或打包成子组.

justify-content应用于弹性容器的auto边缘不同,边距是柔性项目.

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


将一组弹性项目对齐到右侧,但是左侧的第一个项目

问题的情景:

  • 制作一组flex项目align-right(justify-content: flex-end)但是让第一个项目对齐left(justify-self: flex-start)

    考虑带有一组导航项和徽标的标题部分.随着 justify-self徽标可以左对齐,而导航项目保持最右边,整个事物平滑地调整("弯曲")到不同的屏幕尺寸.

在此输入图像描述

在此输入图像描述


其他有用的场景:

在此输入图像描述

在此输入图像描述

在此输入图像描述


将弯曲项目放在角落里

问题的情景:

  • 将弯曲物品放在角落里 .box { align-self: flex-end; justify-self: flex-end; }

在此输入图像描述


垂直和水平居中放置柔性项目

在此输入图像描述

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

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

.container {
    justify-content: center;
    align-items: center;
}
Run Code Online (Sandbox Code Playgroud)

您可以在flex项上使用它:

.box56 {
    margin: auto;
}
Run Code Online (Sandbox Code Playgroud)

以溢出容器的flex项为中心时,此替代方法很有用.


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

Flex容器通过分配可用空间来对齐Flex项目.

因此,为了产生相等的平衡,使得中间物品可以在容器中居中并且单个物品旁边,必须引入平衡.

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

在此输入图像描述

在此输入图像描述

当然,这种方法在语义方面并不算什么.

或者,您可以使用伪元素而不是实际的DOM元素.或者你可以使用绝对定位.这里介绍了所有三种方法:居中和底部对齐弹性项目

注意:上述示例仅适用于真正居中 - 当最外面的项目高度/宽度相等时.当flex项目的长度不同时,请参阅下一个示例.


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

问题的情景:

  • 在一排三个柔性物品中,将中间物品粘贴到容器的中心(justify-content: center)并将相邻的物品对齐到容器边缘(justify-self: flex-startjustify-self: flex-end).

    请注意,如果相邻项具有不同的宽度,则值space-aroundspace-betweenon justify-content属性不会使中间项相对于容器居中(请参阅演示).

如上所述,除非所有弹性项目的宽度或高度相等(取决于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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

以下是解决此问题的两种方法:

解决方案#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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

以下是它的工作原理:

  • 顶级div(.container)是一个flex容器.
  • 每个子div(.box)现在都是一个flex项.
  • .box给出每个项目flex: 1以便平均分配容器空间.
  • 现在这些项目消耗了行中的所有空间并且宽度相等.
  • 使每个项目成为(嵌套的)Flex容器并添加justify-content: center.
  • 现在每个span元素都是一个居中的flex项.
  • 使用弹性auto边距span向左和向右移动外侧.

您也可以放弃justify-contentauto专门使用保证金.

但是justify-content可以在这里工作,因为auto利润总是优先考虑.从规格:

8.1.与auto 边距对齐

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


辩解内容:空间相同(概念)

回过头justify-content来看,这是另一个选择的想法.

  • space-same〜的混合space-betweenspace-around.Flex项目间隔均匀(如space-between),除了两端的半角空格(如space-around),两端都有全尺寸空格.

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

在此输入图像描述

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

更新:浏览器已经开始实现space-evenly,完成上述操作.有关详细信息,请参阅此帖子:Flex项目之间的相等空间


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

  • 上面的答案涵盖了 *main-axis*、`justify-content` 和 `auto` 边距。对于硬币的另一面——*cross-axis*、`align-items`、`align-self` 和`align-content`——参见这篇文章:http://stackoverflow.com/q/42613359 /3597276 (4认同)
  • @MarkW,你正在为'justify-self`属性做出判断......'auto`的边距是有帮助的,但是`justify-self:center`将是理想的.解决您提出的问题的方法是在对面创建不可见的重复项.请参阅我的回答:http://stackoverflow.com/q/38948102/3597276 (4认同)
  • 你的"太空相同"概念现在是真实的.它被称为"空间均匀",但目前只支持Firefox:https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content (4认同)
  • 我真的希望CSS联盟的人们(或者他们如何称呼自己)能够考虑到自我辩护的想法......我有时觉得很荒谬,有时你必须采取复杂的解决方法来解决问题......就好像任何人都真正了解您上面提到的那些“技巧”;) (3认同)

Mar*_*ark 125

我知道这不是一个答案,但我想为这个问题做出贡献.如果他们能够发布justify-selfflexbox以使其真正灵活,那将是很棒的.

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

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

在此输入图像描述

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

在此输入图像描述

制作精美布局的难易程度是无穷无尽的,看看这个"复杂"的例子.

在此输入图像描述

  • @Mark这太棒了!感谢您抽出宝贵时间来草拟这个.我希望你不介意,但我已经在这里提交了它:https://discourse.wicg.io/t/flexbox-justify-self-property/1146 (11认同)
  • @Zaqx 当然,曝光越多越好。真的希望他们能找到一种方法来实现这一点,我很想弄脏我的手。 (4认同)
  • @Michael_B很高兴您正在学习更多有关flexbox的知识,并感谢您花时间将笔记格式化为答案.保证金:auto确实很酷(尽管你会发现实现2009和2012版本的flexbox规范的浏览器没有相同的功能,这大大降低了在生产网站上使用它的能力).但是,即使使用支持margin:auto的浏览器,如果没有自我属性或类似的东西,这里的主要用例是相对于其容器居中的项目,而空间存在仍然是不可能的. (3认同)

dho*_*ert 19

这是在www风格列表中提出的,Tab Atkins(规范编辑)提供了解释原因的答案.我会在这里详细说明一下.

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

对于多线flexbox,相同的逻辑适用于每个"柔性线".在给定的行中,项目在横轴上单独对齐(因为每行只有一个项目,在横轴上),而不是在主轴上.


这里的措辞它的另一种方式:所以,所有*-self*-content性能有关如何乾坤分配额外空间.但关键的区别在于*-self版本适用于该轴中只有一个东西的情况,而且*-content版本适用于该轴中可能有很多东西的情况.单事与多情事件是不同类型的问题,因此他们有不同类型的选项可用 - 例如,space-around/ space-between值有意义*-content,但不适用于*-self.

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

相反,在横轴上,我们既有a *-self又有*-content属性.一个确定我们如何在许多柔性线(align-content)周围分配空间,而另一个(align-self)确定如何在给定柔性线内的横轴上的各个柔性项周围分布空间.

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

  • 我理解“justify-self”如何在具有多个项目而不是一个项目的轴上成为问题。然而,我真的希望他们能进一步研究它,在多个项目的情况下,`justify-self` 会如何表现,因为在某些情况下这可能非常有用。例如(http://stackoverflow.com/questions/32378953/how-can-you-keep-the-center-box-central-in-a-flex-box-layout)。 (2认同)

归档时间:

查看次数:

144651 次

最近记录:

5 年,9 月 前