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

标签 css flexbox language-lawyer w3c

考虑伸缩容器的主轴和横轴:

enter image description here
资料来源:W3C

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


justify-content


要沿交叉轴对齐弹性项目,需要三个属性:


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;


(交叉轴始终垂直于主轴。)

在描述轴的工作方式时,我的观点是,这两个方向似乎都没有什么特别之处。主轴,横轴在重要性上都相同,并且flex-direction使其易于来回切换。

那么,为什么十字轴具有两个附加的对齐属性?

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

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



这些属性将有用的方案:


将flex项目放在flex容器的角落
#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)。

请注意,值space-aroundspace-between
如果相邻项目的宽度不同,则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



在撰写本文时,在flexbox spec中没有提到justify-selfjustify-items

但是,在CSS Box Alignment Module中(这是W3C尚未完成的建议,以建立一套通用的对齐方式属性以供所有盒型模型使用)是:

enter image description here
资料来源:W3C

您会注意到,正在考虑使用justify-selfjustify-items ...,但对于flexbox却没有考虑。



最后,我重申主要问题:


  为什么没有“证明项目”和“自我证明”属性?

最佳答案

沿主轴对齐弹性项目的方法

如问题中所述:


  要沿主轴对齐弹性项目,有一个属性:justify-content
  
  要沿横轴对齐弹性项目,需要三个属性:align-contentalign-items and align-self


然后问题问:


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


一个答案可能是:因为没有必要。

flexbox specification提供了两种沿主轴对齐弹性项目的方法:


justify-content关键字属性,以及
auto margins




证明内容

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
space-between〜Flex项目均匀间隔,第一个项目与容器的一个边缘对齐,最后一个项目与相对的边缘对齐。第一项和最后一项使用的边取决于flex-directionwriting modeltrrtl)。

enter image description here
space-around〜与space-between相同,但两端均留有半角空格。

enter image description here




自动保证金

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

与应用于弹性容器的justify-content不同,在弹性项目上使用auto边距。

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



将一组弹性项目向右对齐,但将第一项向左对齐

问题的场景:


  
  使一组弹性项目右对齐(justify-content: flex-end
  但第一项要左对齐(justify-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



将弹性项目放在角落

问题的场景:


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


enter image description here



将弹性项目垂直和水平居中

enter image description here

margin: autojustify-content: centeralign-items: center的替代。

代替在flex容器上的此代码:

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


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

.box56 {
    margin: auto;
}


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



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

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

因此,为了产生相等的平衡,以便中间的物品可以在容器中居中,旁边只有一个物品,必须引入平衡。

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

enter image description here

enter image description here

当然,就语义而言,此方法并不是什么好事。

另外,您可以使用伪元素代替实际的DOM元素。或者,您可以使用绝对定位。此处介绍了所有三种方法:Center and bottom-align flex items

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



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

问题的场景:


  
  在三个弹性项目的行中,将中间项目粘贴到容器(justify-content: center)的中心,并对齐相邻的
  容器边缘的项目(justify-self: flex-start
  justify-self: flex-end)。
  
  请注意,如果相邻项目的宽度(see demo)不同,则space-around属性上的space-betweenjustify-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;
}

<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规范允许absolute positioning of flex items。这使得中间项目可以完美地居中,而不考虑其同级大小。

请记住,与所有绝对定位的元素一样,这些项目也会从document flow中删除。这意味着它们不会占用容器中的空间,并且可以使它们的兄弟姐妹重叠。

在以下示例中,中间项目以绝对定位为中心,而外部项目保持流入。但是,可以通过相反的方式实现相同的布局:用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(.container)是flex容器。
现在,每个子div(.box)都是一个弹性项目。
为每个.box项目赋予flex: 1,以平均分配容器空间。
现在,这些项目占用了该行中的所有空间,并且宽度相等。
使每个项目成为一个(嵌套的)flex容器,并添加justify-content: center
现在,每个span元素都是一个居中的flex项目。
使用flex auto边距左右移动外部span


您也可以放弃justify-content并仅使用auto边距。

但是justify-content可以在这里工作,因为auto边距始终具有优先级。从规格:


  8.1. Aligning with auto margins
  
  在通过justify-contentalign-self对齐之前,任何
  正的可用空间将分配给该维度中的自动边距。




证明内容:空间相同(概念)

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


space-samespace-betweenspace-around的混合体。伸缩项的间距均匀(如space-between),除了两端没有半角空格(如space-around)外,两端还有全角空格。


可以使用flex容器上的::before::after伪元素来实现此布局。

enter image description here

(代码:@oriol表示标签,@crl表示标签)

更新:浏览器已开始实现space-evenly,从而完成了上述任务。有关详细信息,请参见此帖子:Equal space between flex items



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

关于css - 在CSS Flexbox中,为什么没有“justify-items”和“justify-self”属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42461276/

相关文章:

html - 悬停时的下拉菜单超出容器宽度

css - 我如何将图像设置在同一底层(仅使用 css 而不是 js)?

css - 使用 flexbox 之间的空间

c - 检测宏中的整数常量表达式

c++ - enable_if 的句法模式

html - 在html中拟合图像

html - 垂直对齐引导列内的文本

css - 为什么我的标签没有显示在选择的小部件下方

css - 拉伸(stretch) CSS Flexbox 网格中的元素

c++ - 关于对象指针的一些困惑