居中和底部对齐 flex 项目 [英] Center and bottom-align flex items

查看:49
本文介绍了居中和底部对齐 flex 项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下属性的 flex 容器(蓝色方块):

I have a flex container (the blue square) with the following properties:

display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;

因此,它的子项(浅蓝色方块)如下所示排列.但是,我想从正常流中添加另一个子项(绿色方块)并将其相对于其父项定位.要按如下所示放置它,我最好编写类似 bottom: 20px;margin: auto; 之类的内容.

Therefore, its children (the light blue squares) arrange themselves as you see below. However, I'd like to add another child (the green square) out of the normal flow and position it relative to its parent. To position it as you see below, I'd ideally write something like bottom: 20px; and margin: auto;.

我尝试使用 z-index 无济于事.我应该如何处理这个问题?我应该求助于创建另一个父元素吗?

I tried to play around with z-index to no avail. How should I approach this? Should I resort to creating another parent element?

推荐答案

以下是实现此布局的五个选项:

Below are five options for achieving this layout:

  1. CSS 定位
  2. 带有隐形 DOM 元素的 Flexbox
  3. 带有隐形伪元素的 Flexbox
  4. 带有 flex: 1
  5. 的 Flexbox
  6. CSS 网格布局

<小时>

方法 #1:CSS 定位属性

position:relative 应用到 f​​lex 容器.


Method #1: CSS Positioning Properties

Apply position: relative to the flex container.

position: absolute 应用到绿色 flex 项目.

Apply position: absolute to the green flex item.

现在绿色方块绝对位于 flex 容器内.

Now the green square is absolutely positioned within the flex container.

更具体地说,绿色方块已从文档流中移除,但仍保留在 最近定位的祖先.

More specifically, the green square is removed from the document flow but stays within the bounds of the nearest positioned ancestor.

使用 CSS 偏移属性 topbottomleftright 来移动绿色方块.

Use the CSS offset properties top, bottom, left and right to move the green square around.

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>

一个警告:某些浏览器可能不会从正常流程中完全删除绝对定位的弹性项目.这以一种非标准的、意想不到的方式改变了对齐方式.更多详情:在 Firefox & 中,绝对定位的弹性项目不会从正常流程中删除.IE11

One caveat: Some browsers may not completely remove an absolutely-positioned flex item from the normal flow. This changes the alignment in a non-standard, unexpected way. More details: Absolutely positioned flex item is not removed from normal flow in Firefox & IE11

结合auto边距和新的,可以实现不可见的flex item布局.

With a combination of auto margins and a new, invisible flex item the layout can be achieved.

新的 flex item 与底部 item 相同,并放置在另一端(顶部).

The new flex item is identical to the bottom item and is placed at the opposite end (the top).

更具体地说,因为 flex 对齐是基于自由空间的分布,所以新项是保持三个蓝色框垂直居中的必要平衡.新项目必须与现有绿色项目高度相同,否则蓝色框将无法精确居中.

More specifically, because flex alignment is based on the distribution of free space, the new item is a necessary counterbalance to keep the three blue boxes vertically centered. The new item must be the same height as the existing green item, or the blue boxes won't be precisely centered.

新项目从视图中移除,visibility: hidden.

The new item is removed from view with visibility: hidden.

简而言之:

  • 创建一个绿色框的副本.
  • 将其放在列表的开头.
  • 使用 flex auto 边距保持蓝色框居中,两个绿色框从两端创建相等的平衡.
  • visibility: hidden 应用到重复的绿色框.
  • Create a duplicate of the green box.
  • Place it at the beginning of the list.
  • Use flex auto margins to keep the blue boxes centered, with both green boxes creating equal balance from both ends.
  • Apply visibility: hidden to the duplicate green box.

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>

此方法与#2 类似,只是在语义上更清晰,并且必须知道绿色框的高度.

This method is similar to #2, except it's cleaner semantically and the height of the green box must be known.

  • 创建一个与现有绿色框高度相同的伪元素.
  • ::before 把它放在容器的开头.
  • 使用 flex auto 边距保持蓝色框居中,绿色伪元素和 DOM 元素在两端创建相等的平衡.
  • Create a pseudo-element with the same height as the existing green box.
  • Place it at the start of the container with ::before.
  • Use flex auto margins to keep the blue boxes centered, with the green pseudo and DOM elements creating equal balance from both ends.

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>

从上面的方法 #2 或 #3 开始,不要担心顶部和底部项目的高度相同以保持平衡,只需给每个项目一个 flex: 1.这将迫使它们都消耗可用空间,从而使中间项居中.

Starting with Method #2 or #3 above, instead of worrying about equal height for the top and bottom items to maintain equal balance, just give each one flex: 1. This will force them both to consume available space, thus centering the middle item.

然后您可以将 display: flex 添加到底部项目以对齐内容.

You can then add display: flex to the bottom item in order to align the content.

这可能是最干净、最有效的方法.不需要绝对定位,不需要虚假元素或其他黑客.

This may be the cleanest and most efficient method. There is no need for absolute positioning, fake elements or other hackery.

只需创建一个包含三行的网格.然后将第二行和第三行中的项目居中对齐.第一行可以留空.

Simply create a grid with three rows. Then center-align the items in the second and third rows. The first row can remain empty.

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>

这篇关于居中和底部对齐 flex 项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆