Keep the middle item centered when side items have different widths
想象一下以下布局,其中的点表示框之间的空间:
1 | [Left box]......[Center box]......[Right box] |
当我删除右框时,我希望中心框仍位于中心,如下所示:
1 | [Left box]......[Center box]................. |
如果我要删除左框,也是如此。
1 | ................[Center box]................. |
现在,当中心框中的内容变长时,它将在保持居中状态的同时占用所需的可用空间。左框和右框永远不会缩小,因此,当没有空间的地方
1 | [Left box][Center boxxxxxxxxxxxxx][Right box] |
以上是我的理想情况,但我不知道如何实现此效果。因为当我创建如下的flex结构时:
1 2 3 4 5 | .parent { display : flex; // flex box justify-content : space-between; // horizontal alignment align-content : center; // vertical alignment } |
如果左右框的大小完全相同,我将获得所需的效果。但是,如果两者之一的大小不同,则居中框不再真正居中。
有没有人可以帮助我?
更新资料
1 2 3 4 5 6 7 | .leftBox { justify-self : flex-start; } .rightBox { justify-self : flex-end; } |
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?
这是一种使用flexbox将中间项目居中的方法,而与兄弟姐妹的宽度无关。
主要特征:
- 纯CSS
- 没有绝对定位
- 没有JS / jQuery
使用嵌套的伸缩容器和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | .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; } |
1 2 3 4 5 6 7 | <span>short text</span> <span>centered text</span> <span>loooooooooooooooong text</span> <p> true center </p> |
运作方式如下:
-
顶级div(
.container )是Flex容器。 -
现在,每个子div(
.box )都是一个弹性项目。 -
为每个
.box 项目指定了flex: 1 ,以便平均分配容器空间(更多详细信息)。 - 现在,这些项目占用了该行中的所有空间,并且宽度相等。
-
使每个项目成为一个(嵌套的)flex容器,并添加
justify-content: center 。 -
现在,每个
span 元素都是一个居中的flex项目。 -
使用flex
auto 边距左右移动外部span 。
您也可以放弃
但是
8.1. Aligning with
auto
marginsPrior to alignment via
justify-content andalign-self , any
positive free space is distributed to auto margins in that dimension.
但是,如果第一个或最后一个项目的内容广泛,则该弹性项目也会由于新的
注意Chrome似乎无法正确实现此目的。但是,您可以将
只有在这种情况下,中间元素才会被推出中心。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | .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; } } |
1 2 3 4 5 6 7 8 9 10 | Left Center Right <!-- Analogous to above --> LeftCenterRightLeftCenterRight |
这是使用网格而不是flexbox的答案。此解决方案不需要HTML中多余的孙元素,就像接受的答案一样。即使一侧的内容足够长以溢出到中心,它也可以正常工作,这与2019年的网格答案不同。
该解决方案不做的一件事就是显示省略号或将多余的内容隐藏在中心框中,如问题中所述。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <section> left center right side is longer </section> <section> left center right side is much, much longer </section> <section> left center right side is much, much longer, super long in fact </section> |
代替使用默认的flexbox,使用grid可以在CSS的2行代码中解决它,而在顶级子代中则无需额外的标记。
HTML:
1 2 3 4 5 | <header class="header"> variable content variable content variable content which happens to be very long </header> |
CSS:
1 2 3 4 5 6 7 8 9 10 | .header { display: grid; grid-template-columns: [first] 20% auto [last] 20%; } .middle { /* use either */ margin: 0 auto; /* or */ text-align: center; } |
Flexbox摇摇欲坠,但不应成为所有解决方案的答案。在这种情况下,网格显然是最干净的选择。
甚至为您的测试乐趣制作了一个Codepen:
https://codepen.io/anon/pen/mooQOV
您可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | .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; } |
1 2 3 4 5 6 7 | This is really long content. More content. So much content. This will always be in the center. This is short. |
这是另一种方法,在父母和孩子中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .Layout{ display: flex; justify-content: center; } .Left{ display: flex; justify-content: flex-start; width: 100%; } .Right{ display: flex; justify-content: flex-end; width: 100%; } |
1 2 3 | I'm on the left Centered I'm on the right |
您还可以使用这种简单的方法来实现中间元素的精确中心对齐:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | .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