Html 当侧边项目具有不同的宽度时,保持中间项目居中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32378953/
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 18:09:40  来源:igfitidea点击:

Keep the middle item centered when side items have different widths

htmlcssflexboxcentering

提问by Mark

enter image description here

在此处输入图片说明

Imagine the following layout, where the dots represent the space between the boxes:

想象一下以下布局,其中的点代表框之间的空间:

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

When I remove the right box, I like the center box to still be in the center, like so:

当我移除右边的盒子时,我喜欢中心盒子仍然在中心,就像这样:

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

The same goes for if I would remove the left box.

如果我删除左框也是如此。

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

Now when the content within the center box gets longer, it will take up as much available space as needed while remaining centered. The left and right box will never shrink and thus when where is no space left the overflow:hiddenand text-overflow: ellipsiswill come in effect to break the content;

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

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

All the above is my ideal situation, but I have no idea how to accomplish this effect. Because when I create a flex structure like so:

以上都是我的理想情况,但是我不知道如何实现这种效果。因为当我像这样创建一个 flex 结构时:

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

If the left and right box would be exactly the same size, I get the desired effect. However when one of the two is from a different size the centered box is not truly centered anymore.

如果左右框的大小完全相同,我就会得到想要的效果。然而,当两者之一来自不同的尺寸时,居中的框不再真正居中。

Is there anyone that can help me?

有没有人可以帮助我?

Update

更新

A justify-selfwould be nice, this would be ideal:

Ajustify-self会很好,这将是理想的:

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

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

采纳答案by Michael Benjamin

If the left and right boxes would be exactly the same size, I get the desired effect. However when one of the two is a different size the centered box is not truly centered anymore. Is there anyone that can help me?

如果左右框的大小完全相同,我就会得到想要的效果。然而,当两者之一的大小不同时,居中的框不再真正居中。有没有人可以帮助我?

Here's a method using flexbox to center the middle item, regardless of the width of siblings.

这是一种使用 flexbox 将中间项居中的方法,无论兄弟姐妹的宽度如何。

Key features:

主要特点:

  • pure CSS
  • no absolute positioning
  • no JS/jQuery
  • 纯 CSS
  • 没有绝对定位
  • 没有 JS/jQuery

Use nested flex containers and automargins:

使用嵌套的 flex 容器和auto边距:

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

Here's how it works:

这是它的工作原理:

  • The top-level div (.container) is a flex container.
  • Each child div (.box) is now a flex item.
  • Each .boxitem is given flex: 1in order to distribute container space equally (more details).
  • Now the items are consuming all space in the row and are equal width.
  • Make each item a (nested) flex container and add justify-content: center.
  • Now each spanelement is a centered flex item.
  • Use flex automargins to shift the outer spans left and right.
  • 顶层 div ( .container) 是一个 flex 容器。
  • 每个子 div ( .box) 现在都是一个弹性项目。
  • .box给出每个项目是flex: 1为了平均分配容器空间(更多详细信息)。
  • 现在这些项目消耗了行中的所有空间并且宽度相等。
  • 使每个项目成为(嵌套的)弹性容器并添加justify-content: center.
  • 现在每个span元素都是一个居中的弹性项目。
  • 使用 flex automargins 左右移动外部spans。

You could also forgo justify-contentand use automargins exclusively.

您也可以放弃justify-contentauto专门使用边距。

But justify-contentcan work here because automargins always have priority.

justify-content可以在这里工作,因为auto利润率总是优先的。

8.1. Aligning with automargins

Prior to alignment via justify-contentand align-self, any positive free space is distributed to auto margins in that dimension.

8.1. 与auto边距对齐

在通过justify-content和对齐之前align-self,任何正自由空间都会分配到该维度的自动边距。

回答by Oriol

  1. Use three flex items in the container
  2. Set flex: 1to the first and last ones. This makes them grow equally to fill the available space left by the middle one.
  3. Thus, the middle one will tend to be centered.
  4. However, if the first or last item has a wide content, that flex item will also grow due to the new min-width: autoinitial value.

    Note Chrome doesn't seem to implement this properly. However, you can set min-widthto -webkit-max-contentor -webkit-min-contentand it will work too.

  5. Only in that case the middle element will be pushed out of the center.

  1. 在容器中使用三个弹性项目
  2. 设置flex: 1为第一个和最后一个。这使它们均匀增长以填充中间的可用空间。
  3. 因此,中间的将趋于居中。
  4. 但是,如果第一个或最后一个项目具有广泛的内容,那么该弹性项目也将由于新的min-width: auto初始值而增长。

    注意 Chrome 似乎没有正确实现这一点。但是,您可以设置min-width-webkit-max-contentor-webkit-min-content并且它也可以工作。

  5. 只有在这种情况下,中间元素才会被推出中心。

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

回答by Johan

Instead of defaulting to using flexbox, using grid solves it in 2 lines of CSS without additional markup inside the top level children.

与默认使用 flexbox 不同,使用 grid 可以在 2 行 CSS 中解决它,而无需在顶级子项中添加额外的标记。

HTML:

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:

CSS:

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

Flexbox rocks but shouldn't be the answer for everything. In this case grid is clearly the cleanest option.

Flexbox 摇滚,但不应该是一切的答案。在这种情况下,网格显然是最干净的选择。

Even made a codepen for your testing pleasure: https://codepen.io/anon/pen/mooQOV

甚至为您的测试乐趣制作了一个代码笔:https://codepen.io/anon/pen/mooQOV

回答by Michael Morton

You can do this like so:

你可以这样做:

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

回答by Erfan Azary

you can also use this simple way to reach exact center alignment for middle element :

您还可以使用这种简单的方法来实现中间元素的精确居中对齐:

.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

代码笔:https://codepen.io/ErAz7/pen/mdeBKLG