html - 居中和右对齐flexbox元素

标签 html css flexbox

我想在中间对齐A BC

如何获得D完全右移?

之前:

enter image description here

后:

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/

最佳答案

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


CSS定位
带有不可见DOM元素的Flexbox
带有不可见伪元素的Flexbox
flex: 1的Flexbox
CSS网格布局




方法1:CSS定位属性

position: relative应用于flex容器。

position: absolute应用于项目D。

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

更具体地说,项目D已从文档流中删除,但停留在nearest positioned ancestor的范围内。

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



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项目。这会以非标准的意外方式更改对齐方式。更多详细信息:Absolutely positioned flex item is not removed from the normal flow in IE11



方法2:Flex自动边距和不可见的Flex项(DOM元素)

结合使用auto margins和新的,不可见的flex项目,可以实现布局。

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

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

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

简而言之:


创建D元素的副本。
将其放在列表的开头。
使用flex auto边距使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>







方法3:Flex自动页边距和不可见的Flex项(伪元素)

此方法与#2相似,但在语义上更简洁,并且必须知道D的宽度。


创建一个宽度与D相同的伪元素。
::before将其放在容器的开头。
使用flex auto边距可保持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>







方法4:将flex: 1添加到左侧和右侧的项目

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

然后,您可以将display: flex添加到各个项目以使其内容对齐。

关于将此方法与min-height结合使用的注意事项:当前在Chrome,Firefox,Edge和其他浏览器中,速记规则flex: 1细分为:


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


当在容器上使用flex-basis时,min-height上的百分比单位(%)导致此方法中断。这是因为,通常来说,子级上的百分比高度要求在父级上有显式的height属性设置。

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

这是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或根本不尝试(which is what the spec actually recommends,尽管事实上至少有一些主要的浏览器出于某种原因附加了百分比单位)。



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







方法5:CSS网格布局

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

只需创建一个具有多列的网格。然后将项目放在中间和结尾列中。基本上,只需将第一列留空。



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>

关于html - 居中和右对齐flexbox元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57219144/

相关文章:

CSS 显示 :flex align-items:baseline not working in Firefox

android - Android 浏览器上的页脚绿色边框

twitter-bootstrap - 带有右侧固定侧边栏的 Bootstrap 响应式网格

html - 我如何将一个 div 放在另一个 div 的下面?

html - Flexbox 作为 Firefox 和 Opera 上表格的替代品

css - 通过示例了解flex 1

html - CSS 菜单 - 左对齐图像和右对齐菜单项

javascript - 如何找出默认占位符设置

javascript - 从 JSON 绑定(bind)每个表列(Head)的选择下拉列表,同时将 JSON 数据绑定(bind)到 HTML 表 Jquery

javascript - 在一个 block 中显示所有大写字母