我今天遇到了一个有趣的CSS问题,而且我一直在试图解决它的问题。
这类似于“一排三个元素,左边,右边和中心”的微不足道的问题,这可以通过flexbox轻松解决 - 但它有一些注意事项(我认为) )没有JavaScript的不可能的布局。
预期目标
考虑一个类似行的容器元素和三个子元素,“left”,“right”和“center”。孩子们可能有不同的宽度,但它们都是相同的高度。
“中心”应该尝试相对于其容器保持居中 - 但是三个兄弟元素不得重叠,并且可以在必要时推送到容器外。
然后,标记可能看起来像这样:
<div class="container">
<div class="left">I'm the left content.</div>
<div class="center">I'm the center content. I'm longer than the others.</div>
<div class="right">Right.</div>
</div>
CSS是挑战所在。
对于宽容器,“中心”相对于容器居中(即,其兄弟姐妹的宽度无关紧要),如下图所示;注意“center”元素的中点与容器的中点匹配,左右“剩余”空格不相等:
对于较窄的容器,“中心”邻接最宽的兄弟,但它不重叠。剩余空间仅分布在 narrow 兄弟和“中心”兄弟之间。另请注意,由插入符指示的容器中点不再与“中心”中点相同:
最后,随着容器继续缩小,没有其他选择,只能将所有三个元素排成一行,溢出父级:
我尝试解决此问题
令人惊讶的是,我还没有找到一种在纯CSS中实现它的好方法。
你认为flexbox会成为胜利者,但是你无法让flexbox正确地做到这一点:space-between
属性在元素之间均匀分配空间,因此中心元素实际上并未结束向上集中。 flex - grow
/ shrink
/ basis
属性也不是特别有用,因为它们负责控制子元素的大小,而不是控制子元素的大小它们之间的空间。
只要容器足够宽,使用position:absolute
就可以解决它,但当容器缩小时,最终会出现重叠。
(并且浮动布局无法在达到这一目标的一英里之内。)
我可以将上面最好的两个解决方案结合起来,并使用@media
查询在它们之间切换 - 如果所有宽度都事先已知。但它们不是,尺寸可能差别很大。
简而言之,我所知道的这个问题没有纯HTML-and-CSS解决方案。
结论,以及一个JSFiddle来试验
我创建了一个JSFiddle,它既显示了所需的目标,也显示了一些非解决方案。随意分叉并进行实验。您可以通过抓取内容左侧的栏并拖动它来模拟容器调整大小。您可以重新排列/重新构建HTML和CSS,如果重写它可以让您更接近工作答案。
那么有没有人有这个解决方案,不涉及使用JavaScript智能地分配元素之间的空间?
答案 0 :(得分:2)
使用flexbox
,您应该能够通过提供left
/ right
元素flex: 1
和右text-align: right
来解决这个问题。
主要技巧是flex: 1
,这将使他们平等分享可用空间。
有关更多版本,请参阅此精彩问题/答案,flexbox-justify-items-and-justify-self-properties
Stack snippet
body {
font: 14px Arial;
}
.container {
display: flex;
border: 1px solid #00F;
}
.container > div > span {
display: inline-block;
background: #36F;
white-space: nowrap;
padding: 2px 4px;
color: #FFF;
}
.container > .center > span {
background: #696;
}
.container .left,
.container .right {
flex: 1;
}
.container .right {
text-align: right;
}
.center-mark {
text-align: center;
font-size: 80%;
}
.note {
text-align: center;
color: #666;
font-style: italic;
font-size: 90%;
}
<div class="container">
<div class="left">
<span>
I'm the left content.
</span>
</div>
<div class="center">
<span>I'm the center content. I'm longer than the others.</span>
</div>
<div class="right">
<span>
Right.
</span>
</div>
</div>
<div class="center-mark">^</div>
<div class="note">(centered marker/text)</div>