左右对齐一个弹性项目,同时使其他弹性项目居中 [英] Right or left align one flex item, while keeping the others centered

查看:45
本文介绍了左右对齐一个弹性项目,同时使其他弹性项目居中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在中间对齐 A B C .

如何获取 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:1
  • 的Flexbox
  • CSS网格布局

position:relative 应用于flex容器.

Apply position: relative to the flex container.

position:absolute 应用于项目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 right 将此元素移到位置.

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.

新的伸缩项目与项目D相同,并位于另一端(左边缘).

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

更具体地说,因为弯曲对齐基于自由空间的分布,所以新项目是保持三个中间框水平居中的必要平衡.新项目的宽度必须与现有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.

具有 visibility:hidden (隐藏)的新项目将从视图中删除.

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

简而言之:

  • 创建 D 元素的副本.
  • 将其放在列表的开头.
  • 使用flex auto 边距使 A B C 居中,并且同时保持 D元素从两端创建相等的平衡.
  • 对重复的 D
  • 应用 visibility:hidden
  • 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.

注意 关于将这种方法与 min-height 结合使用的信息:当前在Chrome,Firefox,Edge以及可能的操作系统中在其他浏览器中,速记规则 flex:1 分解为:

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

  • flex-grow:1
  • 弯曲收缩:1
  • 弹性基础:0%

当在容器上使用 min-height 时, flex-basis 上的百分比单位(%)会导致此方法中断.这是因为,通常,子级上的百分比高度要求父级上的显式 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 在评论中发布的问题的说明:

Here's an illustration of the problem posted in the comments by 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>

这篇关于左右对齐一个弹性项目,同时使其他弹性项目居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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