我想让A、B和C在中间对齐。

怎样才能让D完全向右移动呢?

之前:

后:

ul { 填充:0; 保证金:0; 显示:flex; flex-direction:行; justify-content:中心; 对齐项目:中心; } 李{ 显示:flex; 保证金:1 px; 填充:5 px; 背景:# aaa级; } 李:胎{ 背景:# ddd; /*魔术扔到右边*/ } < ul > <李> < /李> <李> B < /李> <李> C < /李> <李> D < /李> < / ul >

https://jsfiddle.net/z44p7bsx/


下面是实现这种布局的五个选项:

CSS定位 Flexbox与隐形DOM元素 Flexbox与隐形伪元素 flex: 1 CSS网格布局


方法#1:CSS定位属性

应用位置:相对于伸缩容器。

应用位置:D项的绝对位置。

现在这个项目完全位于伸缩容器中。

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

使用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>

这种方法需要注意的一点是,有些浏览器可能不会完全从正常流中删除绝对定位的伸缩项。这会以一种非标准的、意想不到的方式改变对齐方式。更多细节:在IE11中,绝对定位的伸缩项不会从正常流程中移除


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

结合了汽车边际和一个新的,无形的灵活项目的布局可以实现。

新的伸缩项目与项目D相同,并被放置在相反的一端(左边缘)。

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

新项目从视图中删除,可见性:hidden。

简而言之:

创建D元素的副本。 把它放在列表的开头。 使用灵活的自动边距来保持A, B和C居中,两个D元素从两端创造相等的平衡。 应用可见性:隐藏到重复的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:弹性自动边距和不可见的弹性项目(伪元素)

这个方法类似于第2条,除了它在语义上更简洁,而且必须知道D的宽度。

创建一个与D宽度相同的伪元素。 将它放在容器的开头,使用::before。 使用灵活的自动边距来保持A, B和C的完美居中,pseudo和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开始,而不是担心左右项目的宽度相等,以保持平衡,只要给每个项目一个弹性:这将迫使他们都消耗可用的空间,从而居中中间的项目。

然后,您可以将display: flex添加到单个项目,以便对其内容进行对齐。

目前在Chrome, Firefox, Edge和可能的其他浏览器中,简写规则flex: 1分解为:

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

在容器上使用最小高度时,基于flex的百分比单位(%)会导致此方法失效。这是因为,作为一般规则,子节点的百分比高度需要在父节点上显式设置height属性。

这是一条可以追溯到1998年(CSS Level 2)的老CSS规则,在许多浏览器中或多或少仍然有效。详情请见这里和这里。

下面是用户2651804在评论中发布的问题说明:

# flex-container { 显示:flex; flex-direction:列; 背景:蓝绿色; 宽度:150 px; 最小高度:80 vh; justify-content:之间的空间; } # flex-container > div { 背景:橙色; 保证金:5 px; } # flex-container > div:第一个孩子{ flex: 1; } # flex-container::{后 内容:“”; flex: 1; } < div id = " flex-container " > <div>非常长的烦人的文本,将添加到其父元素的高度之上 < div > < / div中心> < / div >

解决方案是不使用百分比单位。尝试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>


方法#5:CSS网格布局

这可能是最干净和最有效的方法。不需要绝对定位,虚假元素或其他hack。

只需创建一个包含多列的网格。然后把你的项目放在中间和结尾的列中。基本上,只要把第一列空了。

ul { 显示:网格; Grid-template-columns: 1fr repeat(3, auto) 1fr; grid-column-gap: 5 px; justify-items:中心; } Li:n -child(1) {grid-column-start: 2;} Li:n -child(4) {margin-left:自动;} /*仅用于演示*/ Ul{填充:0;保证金:0;list-style:没有;} Li {padding: 5px;背景:# aaa级;} P {text-align: center;} < ul > <李> < /李> <李> B < /李> <李> C < /李> <李> D < /李> < / ul > <p><span>| true center |</span></p>


非常清楚的问题。经过几个小时的挖掘,我忍不住把答案贴了出来。我们可以用表格,表格单元格,绝对位置,转换来解决这个问题,但我们必须用flexbox来做:)

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

.center {
  margin: auto;
}

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


我扩展了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>Center</li> <li>this</li> </span> <span> <li>Accusamus</li> <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>Center</li> <li>this</li> </span> <span> <li>Accusamus</li> <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>Accusamus</li> <li>Porro</li> <li>Culpa</li> <li>Sit</li> </span> <span> <li>Center</li> <li>this</li> </span> </ul> <br><br> 1 of 1 <ul class="center-flex__1-of-1"> <span> <li>Center</li> <li>this</li> </span> </ul>

这里有SASS作为一个代码依赖的帮助


接受的答案可以改变一点,因为你可以使用网格模板区域,没有假元素

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

使用display:grid方法,你可以简单地把所有的ul子元素放到同一个单元格中,然后设置justification -self:

.ul { 显示:网格; } .ul > * { grid-column-start: 1; grid-row-start: 1; justify-self:中心; } .ul > *:last child { justify-self:正确; } /* Make Fancy */ .li { 显示:inline-block; 保证金:1 px; 填充:5 px; 背景:# bbb; } < div class =“ul”> < span > < span类=‘李’> < / span > B <跨类=‘李’> < / span > < span类=‘李’> C > < /跨度 < / span > D <跨类=‘李’> < / span > < / div >


如果您想使它对齐,您可以简单地附加一个空span并将三个子span分割为它们。


最简单的方法

.box { 显示:flex; justify-content:中心; } .item1 { flex: 1; 显示:flex; justify-content:中心; 变换:translateX(10px);/*D元素宽度[如果需要]*/ } < div class = "盒子" > < div class = " item1”> < div > < / div > div < div > < / B > < div > C < / div > < / div > < div class = "第二条“> D < / div > < / div >


最简单的解决方案是将justify-content center设置为父容器,并将margin-left auto设置为第一个和最后一个子元素。

ul { 显示:flex; justify-content:中心; } 。。d { margin-left:汽车; } < ul > <李类= " " > < /李> <李> B李< / > <李> C李< / > d <李类= " d " > < /李> < / ul >


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>

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

ul { 显示:网格; Grid-template-columns: repeat(3, minmax(0, 1fr)); } 李{ align-self:中心; } 李:nth-child (1) { justify-content: flex-start;/*或margin-right:自动*/ } 李:nth-child (3) { justify-content: flex-end;/* OR margin-left:自动*/ } < ul > <李> < /李> <李> B < /李> <李> C李< / > < / ul >

PS:不确定把flex和grid混合起来是不是一个好主意!


最简单的方法: .wrap { 显示:flex; } .full-width { 宽度:100%; } .centered { 显示:flex; justify-content:中心; } .btn { 显示:flex; justify-content:结束; } < div class = " wrap " > < div class = "宽屏" > < / div > <div class="full-width居中"> < div > < / div > div < div > < / B > < div > C < / div > < / div > <div class="full-width btn">D</div> < / div >