将一个flexbox元素居中并使其左/右对齐 [英] Center one and right/left align other flexbox element

查看:133
本文介绍了将一个flexbox元素居中并使其左/右对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拥有 A B C 对齐在中间。

I would like to have A B and C aligned in the middle.

如何获得 D 完全移到右边?

How can I get D to go completely to the right?

之前:

之后:

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

推荐答案

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

Below are five options for achieving this layout:


  • CSS定位

  • 带有不可见DOM元素的Flexbox

  • 带有不可见的伪元素的Flexbox

  • 带有 flex的Flexbox:1

  • CSS网格布局

  • CSS Positioning
  • Flexbox with Invisible DOM Element
  • Flexbox with Invisible Pseudo-Element
  • Flexbox with flex: 1
  • CSS Grid Layout

position:relative 应用于flex容器。

Apply position: relative to the flex container.

位置:绝对应用于项目D。

现在,此项目已完全放置在flex容器中。

Now this item is absolutely positioned within the flex container.

更具体地说,项目D已从文档流中删除,但仍位于 最靠近的祖先

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

使用CSS偏移属性 top 将元素移到位置。

Use the CSS offset properties top and right to move this element into position.

li:last-child {
  position: absolute;
  top: 0;
  right: 0;
  background: #ddd;
}
ul {
  position: relative;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p {
  text-align: center;
  margin-top: 0;
}
span {
  background-color: aqua;
}

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>

此方法的一个警告是,某些浏览器可能无法从正常流程中完全删除绝对定位的flex项目。这将以非标准的意外方式更改对齐方式。更多详细信息: 绝对定位的弹性商品不会从IE11的常规流程中删除

One caveat to this method is that 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 the normal flow in IE11

auto 边距和一个新的,不可见的flex项目,可以实现布局。

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

新的flex项与项D相同,并位于另一端(左边缘)。

The new flex item is identical to item D and is placed at the opposite end (the left edge).

更具体地说,因为flex对齐基于自由的分布空间中,新商品是保持三个中间盒子水平居中的必要平衡。新项目的宽度必须与现有D项目的宽度相同,否则中间框将无法精确居中。

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

使用<$将新项目从视图中删除c $ c>可见性:隐藏。

简而言之:


  • 创建 D 元素的副本。

  • 将其放在列表的开头。

  • 使用flex auto 边距来保持 A B C 居中,两个 D 元素在两端产生相等的余额。

  • 可见性:隐藏应用于重复的 D

  • Create a duplicate of the D element.
  • Place it at the beginning of the list.
  • Use flex auto margins to keep A, B and C centered, with both D elements creating equal balance from both ends.
  • Apply visibility: hidden to the duplicate D

li:first-child {
  margin-right: auto;
  visibility: hidden;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }

<ul>
  <li>D</li><!-- new; invisible spacer item -->
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>

此方法与#2相似,但在语义上更清晰,且宽度 D 必须是已知的。

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


  • 创建一个宽度与 D

  • 使用 :: before 将其放在容器的开头。

  • 使用flex auto 边距来保持 A B C 完美居中,伪元素和 D 元素在两端产生了相等的余额。

  • Create a pseudo-element with the same width as D.
  • Place it at the start of the container with ::before.
  • Use flex auto margins to keep A, B and C perfectly centered, with the pseudo and D elements creating equal balance from both ends.

ul::before {
  content:"D";
  margin: 1px auto 1px 1px;
  visibility: hidden;
  padding: 5px;
  background: #ddd;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>

从上面的方法2或方法3开始,不必担心左右物品的宽度相等以保持平衡,给每个一个 flex:1

Starting with Method #2 or #3 above, instead of worrying about equal width for the left and right 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 individual items in order to align their content.

注意 关于将此方法与最小高度当前在Chrome,Firefox,Edge和其他浏览器中,速记规则 flex:1 细分为:


  • flex-grow:1

  • flex-shrink:1

  • flex-basis:0%

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

flex-上的百分比单位(%)在容器上使用最小高度时,base 会使此方法中断。这是因为,通常来说,孩子的百分比高度要求在父对象上具有明确的 height 属性设置。

That percentage unit (%) on flex-basis causes this method to break when min-height is used on the container. This is because, as a general rule, percentage heights on the children require an explicit height property setting on the parent.

这是一条可以追溯到1998年的旧CSS规则( CSS 2级)在某种程度上仍在许多浏览器中有效。有关完整的详细信息,请参见 此处 此处

This is an old CSS rule dating back to 1998 (CSS Level 2) which is still in effect in many browsers to some degree or another. For complete details see here and here.

这是user2651804

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container>div {
  background: orange;
  margin: 5px;
}

#flex-container>div:first-child {
  flex: 1;
}

#flex-container::after {
  content: "";
  flex: 1;
}

<div id="flex-container">
  <div>very long annoying text that will add on top of the height of its parent</div>
  <div>center</div>
</div>

解决方案是不使用百分比单位。尝试 px 或根本不尝试(这是规范的实际建议,尽管事实上至少有一些主要的浏览器出于某种原因附加了百分比单位。

The solution is to not use the percentage unit. Try px or just nothing at all (which is what the spec actually recommends, despite the fact that at least some of the major browsers have appended a percentage unit for whatever reason).

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container > div {
  background: orange;
  margin: 5px;
}


/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */

#flex-container > div:first-child {
  flex: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex: 1;
  flex-basis: 0;
}


/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY

#flex-container > div:first-child {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}
 */

<div id="flex-container">
  <div>very long annoying text that will add on top of the height of its parent</div>
  <div>center</div>
</div>

这可能是最干净,最有效的方法。不需要绝对定位,伪造元素或其他黑客手段。

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 multiple columns. Then position your items in the middle and end columns. Basically, just leave the first column empty.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>

这篇关于将一个flexbox元素居中并使其左/右对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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