想象一下下面的布局,其中圆点代表盒子之间的空间:

[Left box]......[Center box]......[Right box]

当我移除右边的方框时,我希望中间的方框仍然在中间,就像这样:

[Left box]......[Center box].................

如果我移除左边的方框也是一样的。

................[Center box].................

现在,当中心框中的内容变长时,它将根据需要占用尽可能多的可用空间,同时保持居中。左右方框永远不会缩小,因此当没有空格时,overflow:hidden和text-overflow:省略号将生效,破坏内容;

[Left box][Center boxxxxxxxxxxxxx][Right box]

以上都是我的理想情况,但是我不知道如何达到这个效果。因为当我创建一个这样的伸缩结构时:

.parent {
    display : flex; // flex box
    justify-content : space-between; // horizontal alignment
    align-content   : center; // vertical alignment
}

如果左右方框的大小完全相同,我就会得到想要的效果。然而,当其中一个的大小不同时,居中的盒子就不再是真正的居中。

有人能帮我吗?

更新

一个自我证明很好,这很理想

.leftBox {
     justify-self : flex-start;
}

.rightBox {
    justify-self : flex-end;
}

如果左右方框的大小完全相同,我就会得到想要的效果。然而,当其中一个大小不同时,居中的盒子就不再是真正的居中了。有人能帮我吗?

下面是一个使用flexbox将中间项居中的方法,而不考虑兄弟项的宽度。

主要特点:

纯CSS 没有绝对定位 没有JS / jQuery

使用嵌套的伸缩容器和自动边距:

.container { display: flex; } .box { flex: 1; display: flex; justify-content: center; } .box:first-child > span { margin-right: auto; } .box:last-child > span { margin-left: auto; } /* non-essential */ .box { align-items: center; border: 1px solid #ccc; background-color: lightgreen; height: 40px; } p { text-align: center; margin: 5px 0 0 0; } <div class="container"> <div class="box"><span>short text</span></div> <div class="box"><span>centered text</span></div> <div class="box"><span>loooooooooooooooong text</span></div> </div> <p>&#8593;<br>true center</p>

下面是它的工作原理:

顶层的div (.container)是一个伸缩容器。 每个子div (.box)现在都是一个伸缩项。 每个.box项被赋予flex: 1,以便平均分配容器空间(更多细节)。 现在这些项占用了行中的所有空间,并且宽度相等。 将每个项目设置为(嵌套的)伸缩容器,并添加justify-content: center。 现在每个span元素都是居中的伸缩项。 使用弹性自动边距将外跨度左移和右移。

你也可以放弃合理内容,只使用汽车利润。

但合理内容在这里是可行的,因为汽车利润总是优先考虑的。

8.1. 与auto对齐 利润率 在通过justify-content和align-self对齐之前,any 正自由空间分布到该维度的自动边距。


Use three flex items in the container Set flex: 1 to the first and last ones. This makes them grow equally to fill the available space left by the middle one. Thus, the middle one will tend to be centered. However, if the first or last item has a wide content, that flex item will also grow due to the new min-width: auto initial value. Note Chrome doesn't seem to implement this properly. However, you can set min-width to -webkit-max-content or -webkit-min-content and it will work too. Only in that case the middle element will be pushed out of the center.

.outer-wrapper { display: flex; } .item { background: lime; margin: 5px; } .left.inner-wrapper, .right.inner-wrapper { flex: 1; display: flex; min-width: -webkit-min-content; /* Workaround to Chrome bug */ } .right.inner-wrapper { justify-content: flex-end; } .animate { animation: anim 5s infinite alternate; } @keyframes anim { from { min-width: 0 } to { min-width: 100vw; } } <div class="outer-wrapper"> <div class="left inner-wrapper"> <div class="item animate">Left</div> </div> <div class="center inner-wrapper"> <div class="item">Center</div> </div> <div class="right inner-wrapper"> <div class="item">Right</div> </div> </div> <!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item animate">Center</div></div><div class="right inner-wrapper"><div class="item">Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item">Center</div></div><div class="right inner-wrapper"><div class="item animate">Right</div></div></div>


你可以这样做:

.bar { display: flex; background: #B0BEC5; } .l { width: 50%; flex-shrink: 1; display: flex; } .l-content { background: #9C27B0; } .m { flex-shrink: 0; } .m-content { text-align: center; background: #2196F3; } .r { width: 50%; flex-shrink: 1; display: flex; flex-direction: row-reverse; } .r-content { background: #E91E63; } <div class="bar"> <div class="l"> <div class="l-content">This is really long content. More content. So much content.</div> </div> <div class="m"> <div class="m-content">This will always be in the center.</div> </div> <div class="r"> <div class="r-content">This is short.</div> </div> </div>


而不是默认使用flexbox,使用网格在2行CSS中解决了这个问题,而不需要在顶级子级中添加额外的标记。

HTML:

<header class="header">
  <div class="left">variable content</div>
  <div class="middle">variable content</div>
  <div class="right">variable content which happens to be very long</div>
</header>

CSS:

.header {
  display: grid;
  grid-template-columns: [first] 20% auto [last] 20%;
}
.middle {
  /* use either */
  margin: 0 auto;
  /* or */
  text-align: center;
}

Flexbox很棒,但不应该是所有问题的答案。在这种情况下,网格显然是最干净的选择。

甚至为您的测试乐趣做了一个代码依赖: https://codepen.io/anon/pen/mooQOV


你也可以使用这个简单的方法来达到中间元素的精确中心对齐:

.container {
    display: flex;
    justify-content: space-between;
}

.container .sibling {
    display: flex;
    align-items: center;
    height: 50px;
    background-color: gray;
}

.container .sibling:first-child {
    width: 50%;
    display: flex;
    justify-content: space-between;
}

.container .sibling:last-child {
    justify-content: flex-end;
    width: 50%;
    box-sizing: border-box;
    padding-left: 100px; /* .center's width divided by 2 */
}

.container .sibling:last-child .content {
    text-align: right;
}

.container .sibling .center {
    height: 100%;
    width: 200px;
    background-color: lightgreen;
    transform: translateX(50%);
}

codepen: https://codepen.io/ErAz7/pen/mdeBKLG


这里有一个答案,使用网格而不是flexbox。这个解决方案不需要像接受的答案那样在HTML中添加额外的孙子元素。即使一边的内容足够长,溢出到中间,它也能正常工作,不像2019年的网格答案。

这个解决方案没有做的一件事是显示省略号或隐藏在中心框中的额外内容,如问题中所述。

section { display: grid; grid-template-columns: 1fr auto 1fr; } section > *:last-child { white-space: nowrap; text-align: right; } /* not essential; just for demo purposes */ section { background-color: #eee; font-family: helvetica, arial; font-size: 10pt; padding: 4px; } section > * { border: 1px solid #bbb; padding: 2px; } <section> <div>left</div> <div>center</div> <div>right side is longer</div> </section> <section> <div>left</div> <div>center</div> <div>right side is much, much longer</div> </section> <section> <div>left</div> <div>center</div> <div>right side is much, much longer, super long in fact</div> </section>


这里有另一种方法,在父元素和子元素中使用display: flex:

.Layout { 显示:flex; justify-content:中心; } .Left { 显示:flex; justify-content: flex-start; 宽度:100%; } 铃声{ 显示:flex; justify-content: flex-end; 宽度:100%; } <div class = 'Layout'> <div class = 'Left'>我在左边</div> <div class = 'Mid'>居中</div> <div class = 'Right'>我在右边</div> < / div >


虽然我在这个问题上可能晚了,但所有这些解决方案似乎都很复杂,而且根据你所面临的情况可能不会起作用。

非常简单,只需要用position: absolute来包装你想要居中的组件,而让其他两个组件用justify-content: space来分隔,如下所示:

CSS:

.container { display: flex; justify-content: space-between; align-items: center; background-color: lightgray; } .middle { position: absolute; margin-left: auto; margin-right: auto; /* You should adapt percentages here if you have a background ; else, left: 0 and right: 0 should do the trick */ left: 40%; right: 40%; text-align: center; } /* non-essential, copied from @Brian Morearty answer */ .element { border: 1px solid #ccc; background-color: lightgreen; } p { margin: 5px; padding: 5px; } <div class="container"> <p class="element">First block</p> <p class="middle element">Middle block</p> <p class="element">Third THICC blockkkkkkkkk</p> </div>


关键是要使用弹性基准。那么解决方案很简单:

.parent {
    display: flex;
    justify-content: space-between;
}

.left, .right {
   flex-grow: 1;
   flex-basis: 0;
}

CodePen可以在这里找到。


稍微健壮一点的网格解决方案如下所示:

.container { overflow: hidden; border-radius: 2px; padding: 4px; background: orange; display: grid; grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr); } .item > div { display: inline-block; padding: 6px; border-radius: 2px; background: teal; } .item:last-child > div { float: right; } <div class="container"> <div class="item"><div contenteditable>edit the text to test the layout</div></div> <div class="item"><div contenteditable>just click me and</div></div> <div class="item"><div contenteditable>edit</div></div> </div>

在这里你可以看到它在Codepen: https://codepen.io/benshope2234/pen/qBmZJWN


我想要在问题中显示的确切结果,我结合了gamliela和Erik Martín Jordán的答案,它最适合我。

.parent {
    display: flex;
    justify-content: space-between;
}

.left, .right {
   flex-grow: 1;
   flex-basis: 0;
}

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

Michael Benjamin给出了一个不错的答案,但没有理由不能/不应该进一步简化:

.container {
  display: flex;
}

.box {
  flex: 1;
  display: flex;
  justify-content: center;
}

.box:first-child { justify-content: left; }

.box:last-child  { justify-content: right;  }

和html

<div class="container">
  <div class="box">short text</div>
  <div class="box">centered tex</div>
  <div class="box">loooooooooooooooong text</div>
</div>