css - working - vue flex
在CSS Flexbox中,为什么没有“ justify-items”和“ justify-self”属性? (4)
沿主轴对齐弹性项目的方法
如问题所述:
要沿主轴对齐弹性项目,有一个属性:
justify-content
要使弹性项沿横轴
align-content
,有三个属性:align-content
, align-items 。
然后问题问:
为什么没有
justify-items
和justify-self
属性?
一个答案可能是: 因为没有必要。
flexbox规范 提供了 两种 沿主轴对齐弹性项目的方法:
-
justify-content
关键字属性,以及 -
auto
边距
证明内容
justify-content
属性将flex项目沿flex容器的主轴对齐。
它应用于flex容器,但仅影响flex项目。
有五个对齐选项:
-
flex-start
start〜Flex项目包装在行的开头。 -
flex-end
end〜Flex项目包装在行尾。 -
center
〜柔性物品被包装到生产线的中心。 -
〜Flex项目之间应均匀间隔,第一个项目与容器的一个边缘对齐,最后一个项目与相对的边缘对齐。 第一项和最后一项使用的边缘取决于
flex-direction
和 写入模式 (ltr
或rtl
)。 -
space-around
〜与space-between
相同,但两端均留有一半大小的间隔。
自动保证金
使用
auto
边距
,可以将弹性项目居中,隔开或打包成子组。
与应用于flex容器的
justify-content
不同,flex项具有
auto
边距功能。
它们通过消耗指定方向上的所有可用空间来工作。
将一组弹性项目向右对齐,但将第一项向左对齐
问题的场景:
使一组flex项右对齐(
justify-content: flex-end
),但使第一个justify-content: flex-end
项向左对齐(justify-self: flex-start
)考虑带有一组导航项和徽标的标题部分。 通过
justify-self
,徽标可以在左侧对齐,而导航项保持在最右侧,并且整个对象可以平滑调整(“弯曲”)以适应不同的屏幕尺寸。
其他有用的方案:
将弹性项目放在角落
问题的场景:
- 将flex项目放置在角落
.box { align-self: flex-end; justify-self: flex-end; }
.box { align-self: flex-end; justify-self: flex-end; }
将弹性项目垂直和水平居中
margin: auto
是
justify-content: center
和
align-items: center
的替代方法。
代替在flex容器上的此代码:
.container {
justify-content: center;
align-items: center;
}
您可以在flex项目上使用它:
.box56 {
margin: auto;
}
当 居中溢出容器的flex项目居中 时,此替代方法很有用。
将弹性项目居中,将第二个弹性项目居中于第一个和边缘之间
flex容器通过分配可用空间来对齐flex项目。
因此,为了创建 平衡 ,以便中间物品可以在容器中居中放置单个物品,必须引入平衡。
在下面的示例中,引入了不可见的第三柔性项目(框61和68)以平衡“真实”项目(框63和66)。
当然,就语义而言,此方法并不是什么好事。
另外,您可以使用伪元素代替实际的DOM元素。 或者,您可以使用绝对定位。 此处介绍了所有三种方法: 居中对齐和底部对齐的弹性项目
注意:仅当最外层项目的高度/宽度相等时,以上示例才有效(就真正居中而言)。 如果弹性商品的长度不同,请参见下一个示例。
当相邻项目的大小不同时,将弹性项目居中
问题的场景:
在三个flex项目的行中,将中间项目粘贴到容器的中心(
justify-content: center
),并将相邻的项目与容器边缘对齐(justify-self: flex-start
和justify-self: flex-end
)。请注意,如果相邻项目的宽度不同,则
justify-content
属性上的space-around
和space-between
值将不会使中间项目相对于容器居中( 请参见demo )。
如前所述,除非所有flex项目的宽度或高度相同(取决于
flex-direction
),否则中间项目无法真正居中。
这个问题为
justify-self
属性(当然是设计用来处理任务)提供了强有力的
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规范允许 弹性项目的绝对定位 。 这使得中间项目可以完美地居中,而不考虑其同级大小。
请记住,与所有绝对定位的元素一样,这些项目也会从 文档流 中删除。 这意味着它们不会占用容器中的空间,并且可以使它们的兄弟姐妹重叠。
在以下示例中,中间项目以绝对定位为中心,而外部项目保持流入。
但是,可以通过相反的方式实现相同的布局:将中间项目
justify-content: center
并
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;
}
<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项目。 -
使用弹性
auto
边距左右移动外部span
。
您也可以放弃
justify-content
而仅使用
auto
边距。
但是
justify-content
可以在这里工作,因为
auto
边距始终是优先事项。
从规格:
在通过
justify-content
和align-self
之前,任何正的自由空间都会分配给该维度中的自动边距。
证明内容:空间相同(概念)
回到正
justify-content
一分钟,这里是一个更多选择的想法。
-
space-same
same〜space-between
和space-around
。 Flex项目的间距是均匀的(例如space-between
),除了两端没有半角空格(如space-around
)外,两端都有全角空格。
可以使用flex容器上的
::before
和
::after
伪元素来实现此布局。
(信用: @oriol 代表代码, @crl 代表标签)
更新:
浏览器已开始实现
space-evenly
,从而完成了上述任务。
有关详细信息,请参见此帖子:
伸缩项目之间的间距相等
PLAYGROUND (包括上面所有示例的代码)
考虑伸缩容器的主轴和横轴:
资料来源: W3C
要沿主轴对齐弹性项目,有一个属性:
要沿十字轴对齐弹性项目,需要三个属性:
在上图中,主轴是水平的,而横轴是垂直的。 这些是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-content
和
align-items
合并为主轴的一个属性?
为什么主轴没有获得“
justify-self
属性?
这些属性将有用的方案:
-
将flex项目放在flex容器的角落
#box3 { align-self: flex-end; justify-self: flex-end; }
-
使一组flex项右对齐(
justify-content: flex-end
),但使第一个justify-content: flex-end
项向左对齐(justify-self: flex-start
)考虑带有一组导航项和徽标的标题部分。 通过
justify-self
,徽标可以在左侧对齐,而导航项保持在最右侧,并且整个对象可以平滑调整(“弯曲”)以适应不同的屏幕尺寸。 -
在三个flex项目的行中,将中间项目粘贴到容器的中心(
justify-content: center
),并将相邻的项目与容器边缘对齐(justify-self: flex-start
和justify-self: flex-end
)。请注意,如果相邻项目的宽度不同,则
justify-content
属性上的space-around
和space-between
值将不会使中间项目相对于容器居中。
#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 middle box will only be truly centered if adjacent boxes are equal width</p>
在撰写本文时,在
flexbox规范中
还没有提及
justify-self
或
justify-items
。
但是,在 CSS Box Alignment Module中 ,这是W3C尚未完成的建议,用于建立一套通用的对齐属性以供所有Box模型使用,其中包括:
资料来源: W3C
您会注意到,考虑了
justify-self
和
justify-items
...
但对于flexbox却没有
。
最后,我重申一个主要问题:
为什么没有“证明项目”和“自我证明”属性?
我知道这不使用flexbox,但是对于三个项目的简单用例(一个在左边,一个在中心,一个在右边),可以使用
display: grid
轻松实现
display: grid
父
display: grid
上的
grid-area: 1/1/1/1;
,
grid-area: 1/1/1/1;
在孩子
justify-self
,并
justify-self
这些孩子
justify-self
定位
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>
这是在www样式列表中提出的,Tab Atkins(规范编辑器) 提供了一个解释原因的答案 。 我会在这里详细说明。
首先,让我们首先假设我们的flex容器是单行的(
flex-wrap: nowrap
)。
在这种情况下,主轴和横轴之间显然存在对齐差异-主轴上堆叠了多个项目,但在横轴上仅堆叠了一个项目。
因此,在横轴上有一个可自定义的“ align-self”项是有意义的(因为每个项目都是单独对齐的),而在主轴上则没有意义(因为在那里,项目统一排列)。
对于多行flexbox,相同的逻辑适用于每个“ flex line”。 在给定的行中,项目在横轴上单独对齐(因为在横轴上每行只有一个项目),而在主轴上则是统一排列。
这是短语的另一种表达方式:因此,
所有
*-self
和
*-content
*-self
属性都与如何在事物周围分配额外的空间有关。
但是关键的区别是,
*-self
版本用于
该轴上只有一个事物的
情况,而
*-self
版本用于
该轴上
可能存在
许多事物的情况
。
单物与多物场景是不同类型的问题,因此它们具有不同类型的可用选项,例如,
*-content
space-around
值/
space-between
值对
*-content
有意义,但对于
*-self
却不适用
*-self
。
SO:在flexbox的主轴上,有很多东西可以分配空间。
因此,
*-self
属性在那里有意义,而
*-self
属性
*-self
。
相反,在交叉轴上,我们同时具有
*-self
和
*-self
属性。
一个决定了我们如何在
许多
弯曲线(
align-content
)周围分配空间,而另一个(
align-self
)确定了如何在给定的弯曲线内在交叉轴上的
各个
弯曲项目周围分配空间。
(我在这里忽略
*-items
属性,因为它们只是为
*-self
建立默认值。)