居中和底部对齐弹性项目
Center and bottom-align flex items
我有一个具有以下属性的弹性容器(蓝色方块):
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
因此,它的子项(浅蓝色方块)会按如下所示自行排列。但是,我想在正常流程之外添加另一个子项(绿色方块)并将其相对于其父项定位。如下图所示,我最好写成 bottom: 20px;
和 margin: auto;
.
我试过 z-index
但无济于事。我应该如何处理这个问题?我应该求助于创建另一个父元素吗?
以下是实现此布局的五个选项:
- CSS定位
- 具有不可见 DOM 元素的 Flexbox
- 具有隐形伪元素的 Flexbox
- 具有
flex: 1
的 Flexbox
- CSS 网格布局
方法 #1:CSS 定位属性
将 position: relative
应用于弹性容器。
将 position: absolute
应用于绿色弹性项目。
现在绿色方块绝对定位在 flex 容器内。
更具体地说,绿色方块已从文档流中移除,但仍在 nearest positioned ancestor 的范围内。
使用 CSS 偏移属性 top
、bottom
、left
和 right
移动绿色方块。
flex-container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
position: relative;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
display: flex;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
flex-container > flex-item:last-child {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%); /* fine tune horizontal centering */
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
一个警告:一些浏览器可能不会从正常流程中完全删除绝对定位的弹性项目。这会以一种非标准的、意想不到的方式改变对齐方式。更多详情:
方法 #2:Flex 自动边距和不可见的 Flex 项目(DOM 元素)
结合使用 和一个新的、不可见的 flex 项目,可以实现布局。
新的弹性项目与底部项目相同,并放置在另一端(顶部)。
更具体地说,因为 flex 对齐是基于自由 space 的分配,所以新项目是保持三个蓝色框垂直居中的必要平衡。新项目必须与现有绿色项目的高度相同,否则蓝色框不会精确居中。
新项目已从视图中删除 visibility: hidden
。
简而言之:
- 创建绿框的副本。
- 将其放在列表的开头。
- 使用弹性
auto
边距使蓝色框保持居中,两个绿色框从两端创造相等的平衡。
- 将
visibility: hidden
应用到重复的绿色框。
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
margin-top: auto;
visibility: hidden;
}
flex-container > flex-item:nth-child(2) {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
}
flex-container > flex-item:first-child,
flex-container > flex-item:last-child {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:nth-child(2) > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item></flex-item>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
方法#3:Flex Auto Margins & Invisible Flex Item(伪元素)
此方法与 #2 类似,只是它在语义上更清晰,并且必须知道绿色框的高度。
- 创建一个与现有绿色框高度相同的伪元素。
- 将它放在容器的开头
::before
。
- 使用弹性
auto
边距使蓝色框保持居中,绿色伪元素和 DOM 元素在两端创造相等的平衡。
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container::before {
content: "";
margin-top: auto;
height: calc(50px + 8px); /* height + borders */
visibility: hidden;
}
flex-container > flex-item:first-child {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
方法 #4:将 flex: 1
添加到顶部和底部项目
从上面的方法 #2 或 #3 开始,不用担心顶部和底部项目的高度相等以保持相等的平衡,只需给每一个 flex: 1
。这将迫使他们都消耗可用的 space,从而使中间项居中。
然后您可以将 display: flex
添加到底部项目以对齐内容。
方法 #5:CSS 网格布局
这可能是最干净、最有效的方法。不需要绝对定位、假元素或其他 hackery。
只需创建一个三行网格。然后将第二行和第三行中的项目居中对齐。第一行可以留空。
grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
align-items: center;
justify-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
grid-item:nth-child(2) {
display: flex;
}
grid-item:nth-child(2)>flex-item {
width: 50px;
height: 50px;
margin: 0 5px;
border: 4px solid aqua;
}
grid-item:nth-child(3) {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<grid-container>
<grid-item></grid-item>
<grid-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</grid-item>
<grid-item></grid-item>
</grid-container>
让容器position: relative
和绿色方块position:absolute;
body {
margin: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
width: 192px;
height: 192px;
border: 4px solid indigo;
position: relative;
background: lavender;
}
.blue {
margin: 10px;
width: 30px;
height: 30px;
outline: 4px solid skyblue;
background: honeydew;
}
#green {
position: absolute;
width: 30px;
height: 30px;
left: 0;
right: 0;
margin: auto;
bottom: 20px;
outline: 4px solid yellowgreen;
background: greenyellow;
}
<div id=container>
<div class=blue></div><div class=blue></div><div class=blue></div>
<div id=green></div>
</div>
您可以使用伪指令将前三个容器向下移动一行,然后将 margin:auto
应用到最后一个
div {
display:flex;
flex-wrap:wrap;
border:#0066FD solid;;
width:200px;
height:200px;
justify-content:space-around;
/* show me box center */
background:linear-gradient(to top,rgba(0,0,0,0.2) 50%, transparent 50%),linear-gradient(to left,rgba(0,0,0,0.2) 50%, transparent 50%)
}
span, div:before {
width:50px;
height:50px;
border:solid #01CDFF;
margin:0 auto 0;
}
span:last-of-type , div:before{
margin: 12px auto;
border:solid #01FE43;
}
div:before {
content:'';
width:100%;
border:none;
}
span {
/* show me box center */
background:linear-gradient(45deg,rgba(0,0,0,0.1) 50%, transparent 50%),linear-gradient(-45deg,rgba(0,0,0,0.1) 50%, transparent 50%)
}
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
我有一个具有以下属性的弹性容器(蓝色方块):
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
因此,它的子项(浅蓝色方块)会按如下所示自行排列。但是,我想在正常流程之外添加另一个子项(绿色方块)并将其相对于其父项定位。如下图所示,我最好写成 bottom: 20px;
和 margin: auto;
.
我试过 z-index
但无济于事。我应该如何处理这个问题?我应该求助于创建另一个父元素吗?
以下是实现此布局的五个选项:
- CSS定位
- 具有不可见 DOM 元素的 Flexbox
- 具有隐形伪元素的 Flexbox
- 具有
flex: 1
的 Flexbox
- CSS 网格布局
方法 #1:CSS 定位属性
将 position: relative
应用于弹性容器。
将 position: absolute
应用于绿色弹性项目。
现在绿色方块绝对定位在 flex 容器内。
更具体地说,绿色方块已从文档流中移除,但仍在 nearest positioned ancestor 的范围内。
使用 CSS 偏移属性 top
、bottom
、left
和 right
移动绿色方块。
flex-container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
position: relative;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
display: flex;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
flex-container > flex-item:last-child {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%); /* fine tune horizontal centering */
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
一个警告:一些浏览器可能不会从正常流程中完全删除绝对定位的弹性项目。这会以一种非标准的、意想不到的方式改变对齐方式。更多详情:
方法 #2:Flex 自动边距和不可见的 Flex 项目(DOM 元素)
结合使用
新的弹性项目与底部项目相同,并放置在另一端(顶部)。
更具体地说,因为 flex 对齐是基于自由 space 的分配,所以新项目是保持三个蓝色框垂直居中的必要平衡。新项目必须与现有绿色项目的高度相同,否则蓝色框不会精确居中。
新项目已从视图中删除 visibility: hidden
。
简而言之:
- 创建绿框的副本。
- 将其放在列表的开头。
- 使用弹性
auto
边距使蓝色框保持居中,两个绿色框从两端创造相等的平衡。 - 将
visibility: hidden
应用到重复的绿色框。
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
margin-top: auto;
visibility: hidden;
}
flex-container > flex-item:nth-child(2) {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
}
flex-container > flex-item:first-child,
flex-container > flex-item:last-child {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:nth-child(2) > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item></flex-item>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
方法#3:Flex Auto Margins & Invisible Flex Item(伪元素)
此方法与 #2 类似,只是它在语义上更清晰,并且必须知道绿色框的高度。
- 创建一个与现有绿色框高度相同的伪元素。
- 将它放在容器的开头
::before
。 - 使用弹性
auto
边距使蓝色框保持居中,绿色伪元素和 DOM 元素在两端创造相等的平衡。
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container::before {
content: "";
margin-top: auto;
height: calc(50px + 8px); /* height + borders */
visibility: hidden;
}
flex-container > flex-item:first-child {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
方法 #4:将 flex: 1
添加到顶部和底部项目
从上面的方法 #2 或 #3 开始,不用担心顶部和底部项目的高度相等以保持相等的平衡,只需给每一个 flex: 1
。这将迫使他们都消耗可用的 space,从而使中间项居中。
然后您可以将 display: flex
添加到底部项目以对齐内容。
方法 #5:CSS 网格布局
这可能是最干净、最有效的方法。不需要绝对定位、假元素或其他 hackery。
只需创建一个三行网格。然后将第二行和第三行中的项目居中对齐。第一行可以留空。
grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
align-items: center;
justify-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
grid-item:nth-child(2) {
display: flex;
}
grid-item:nth-child(2)>flex-item {
width: 50px;
height: 50px;
margin: 0 5px;
border: 4px solid aqua;
}
grid-item:nth-child(3) {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<grid-container>
<grid-item></grid-item>
<grid-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</grid-item>
<grid-item></grid-item>
</grid-container>
让容器position: relative
和绿色方块position:absolute;
body {
margin: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
width: 192px;
height: 192px;
border: 4px solid indigo;
position: relative;
background: lavender;
}
.blue {
margin: 10px;
width: 30px;
height: 30px;
outline: 4px solid skyblue;
background: honeydew;
}
#green {
position: absolute;
width: 30px;
height: 30px;
left: 0;
right: 0;
margin: auto;
bottom: 20px;
outline: 4px solid yellowgreen;
background: greenyellow;
}
<div id=container>
<div class=blue></div><div class=blue></div><div class=blue></div>
<div id=green></div>
</div>
您可以使用伪指令将前三个容器向下移动一行,然后将 margin:auto
应用到最后一个
div {
display:flex;
flex-wrap:wrap;
border:#0066FD solid;;
width:200px;
height:200px;
justify-content:space-around;
/* show me box center */
background:linear-gradient(to top,rgba(0,0,0,0.2) 50%, transparent 50%),linear-gradient(to left,rgba(0,0,0,0.2) 50%, transparent 50%)
}
span, div:before {
width:50px;
height:50px;
border:solid #01CDFF;
margin:0 auto 0;
}
span:last-of-type , div:before{
margin: 12px auto;
border:solid #01FE43;
}
div:before {
content:'';
width:100%;
border:none;
}
span {
/* show me box center */
background:linear-gradient(45deg,rgba(0,0,0,0.1) 50%, transparent 50%),linear-gradient(-45deg,rgba(0,0,0,0.1) 50%, transparent 50%)
}
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>