Html 居中和右对齐 flexbox 元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38948102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 13:42:09  来源:igfitidea点击:

Center and right align flexbox elements

htmlcssflexbox

提问by hazyred

I would like to have ABand Caligned in the middle.

我想有ABC中间对齐。

How can I get Dto go completely to the right?

我怎样才能D完全向右走?

BEFORE:

前:

enter image description here

在此处输入图片说明

AFTER:

后:

enter image description here

在此处输入图片说明

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/

https://jsfiddle.net/z44p7bsx/

回答by Michael Benjamin

Below are five options for achieving this layout:

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

  • CSS Positioning
  • Flexbox with Invisible DOM Element
  • Flexbox with Invisible Pseudo-Element
  • Flexbox with flex: 1
  • CSS Grid Layout
  • CSS 定位
  • 带有隐形 DOM 元素的 Flexbox
  • 带有隐形伪元素的 Flexbox
  • 弹性盒与 flex: 1
  • CSS 网格布局


Method #1: CSS Positioning Properties

方法 #1:CSS 定位属性

Apply position: relativeto the flex container.

应用于position: relative弹性容器。

Apply position: absoluteto item D.

适用position: absolute于 D 项。

Now this item is absolutely positioned within the flex container.

现在这个项目绝对定位在 flex 容器中。

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

更具体地说,项目 D 从文档流中删除,但保留在最近定位的祖先的范围内。

Use the CSS offset properties topand rightto move this element into position.

使用 CSS 偏移属性top并将right此元素移动到位。

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>

One caveatto 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

这种方法的一个警告是一些浏览器可能不会从正常流中完全删除绝对定位的弹性项目。这以一种非标准的、意想不到的方式改变了对齐方式。更多细节:绝对定位的 flex 项目不会从 IE11 中的正常流程中删除



Method #2: Flex Auto Margins & Invisible Flex Item (DOM element)

方法#2:Flex Auto Margins & Invisible Flex Item(DOM 元素)

With a combination of automarginsand a new, invisible flex item the layout can be achieved.

通过结合auto边距和一个新的、不可见的弹性项目,可以实现布局。

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.

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

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

使用 将新项目从视图中删除visibility: hidden

In short:

简而言之:

  • Create a duplicate of the Delement.
  • Place it at the beginning of the list.
  • Use flex automargins to keep A, Band Ccentered, with both Delements creating equal balance from both ends.
  • Apply visibility: hiddento the duplicate D
  • 创建D元素的副本。
  • 将其放在列表的开头。
  • 使用Flexauto利润率保持ABC居中,既有D元素创建从两端完全平衡。
  • 适用visibility: hidden于副本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>



Method #3: Flex Auto Margins & Invisible Flex Item (pseudo-element)

方法#3:Flex Auto Margins & Invisible Flex Item(伪元素)

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

这种方法与#2 类似,但它在语义上更清晰,并且D必须知道的宽度。

  • Create a pseudo-element with the same width as D.
  • Place it at the start of the container with ::before.
  • Use flex automargins to keep A, Band Cperfectly centered, with the pseudo and Delements creating equal balance from both ends.
  • 创建一个与D.
  • 用 将它放在容器的开头::before
  • 使用 flex automargins 保持ABC完美居中,伪D元素和元素从两端创建相等的平衡。

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>



Method #4: Add flex: 1to left and right items

方法#4:添加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.

从上面的方法 #2 或 #3 开始,与其担心左右项目的宽度相等以保持平衡,只需给每个flex: 1. 这将迫使它们都消耗可用空间,从而使中间项目居中。

You can then add display: flexto individual items in order to align their content.

然后,您可以添加display: flex到单个项目以对齐它们的内容。

NOTEabout using this method with min-height:Currently in Chrome, Firefox, Edge and possibly other browsers, the shorthand rule flex: 1breaks down to this:

关于使用此方法的min-height注意事项目前在 Chrome、Firefox、Edge 和可能的其他浏览器中,速记规则flex: 1分解为:

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

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

百分比单位(%)flex-basis的原因这种方法时,打破min-height在容器上使用。这是因为,作为一般规则,子项的百分比高度需要height在父项上进行明确的属性设置。

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 hereand here.

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

Here's an illustration of the problem posted in the comments by user2651804:

这是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>

The solution is to not use the percentage unit. Try pxor 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).

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

#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>



Method #5: CSS Grid Layout

方法 #5:CSS 网格布局

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>

回答by Razib Hossain

Most easy way

最简单的方法

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>

回答by Ali Korkmaz

If you want to make it aligned, you can simply attach an empty span and split the three child spans into them.

如果你想让它对齐,你可以简单地附加一个空的跨度并将三个子跨度拆分成它们。

回答by Saba Ahang

Inspired by the Method #5: CSS Grid Layoutof @Michal Benjamin's solution and because I'm using Tailwind and as of now still don't have access to all the grid options by default. This seems to work:

受到@Michal Benjamin解决方案的方法 #5:CSS 网格布局启发,并且因为我使用的是 Tailwind,到目前为止默认情况下仍然无法访问所有网格选项。这似乎有效:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Not sure if mixing up flex and grid like this is a good idea!

PS:不确定像这样混合 flex 和 grid 是否是个好主意!

回答by Suhail AKhtar

The simplest solution will be to justify-content center to the parent container and giving margin-left auto to first and last child element.

最简单的解决方案是将内容中心对齐到父容器,并为第一个和最后一个子元素提供 margin-left auto。

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>

回答by Steven Spungin

Using the display:gridapproach, you can simply put all of the ulchildren into the same cell and then set justify-self:

使用该display:grid方法,您可以简单地将所有ul子项放入同一个单元格中,然后设置justify-self

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>

回答by rgfx

Very clear question. I couldn't help but post the answer after a few hours of digging. We Could of solved this with tables, table-cell, absolute positions, transforms but we just had to do it with flexbox :)

很清楚的问题。经过几个小时的挖掘,我忍不住发布了答案。我们可以用表格、表格单元格、绝对位置、变换来解决这个问题,但我们只需要用 flexbox 来做:)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd

http://codepen.io/rgfx/pen/BLorgd

回答by yunzen

I expanded on Michael_B's answer

我扩展了Michael_B回答

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

Here with the help of SASS as a codepen

这里借助 SASS 作为代码笔

回答by repo

The accepted answer can be changed a bit because you can use grid template areas and do it without fake element

可接受的答案可以稍作更改,因为您可以使用网格模板区域并在没有假元素的情况下进行

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

回答by SUDHIR KUMAR

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;
  position:absolute;
  right:10px;

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