水平居中元素,以避免重叠的容器 [英] Horizontally centering elements to their container while avoiding overlap
问题描述
我今天遇到了一个有趣的CSS问题,我一直在试图解决它的问题。
这与连续三个元素,一个左,一个右,和中心,这可以用flexbox轻松解决 - 但它有一些警告,使得它(我认为)一个不可能的布局,没有JavaScript。
期望的目标 考虑一个像行的容器元素和三个孩子,左,右和中心。 Center应该尽量保持与其容器相对的位置 - 但是三个兄弟元素不能重叠,并且可能会在必要时将其推送到容器外面。 标记可能看起来像这: CSS就是挑战所在。 应该发生的例子 ,中心相对于容器居中(即,其兄弟的宽度无关紧要),如下图所示;请注意,中心元素的中点与容器的中点匹配,左右剩余空格不相等: 对于较窄的容器,中心邻接最宽的兄弟,但它不重叠。剩下的空间只分布在 兄弟姐妹和<中心>兄弟姐妹之间。请注意,由插入符号表示的容器中点不再是中心的中点: 最后,随着容器的不断缩小,除了三个元素排成一行,溢出父母: 我试图解决这个问题 令人惊讶的是,我还没有找到一个很好的方法来实现这个纯CSS。 你会认为flexbox是胜利者,但是你不能真正让flexbox做到这一点:属性之间的 使用<$只要容器足够宽,c $ c> position:absolute 就可以解决它,但是当容器收缩时,最终会出现重叠。 我可以结合上面最好的两个解决方案,并在它们之间切换 简而言之,我不知道纯粹的HTML和CSS解决方案。 / p> 结论和一个JSFiddle来试验 我创建了一个显示期望目标和一些非解决方案的JSFiddle。随意叉和实验。您可以通过抓取内容左侧的栏并拖动它来模拟容器大小调整。您可以重新排列/重构HTML和CSS,如果重写它可以使您更接近正常工作的答案。 https://jsfiddle.net/seanofw/35qmdnd6 那么有没有人有一个解决方案,这不涉及使用JavaScript来智能分配元素之间的空间? 使用 主要技巧是 欲了解更多版本,请参阅这个精彩的问题/答案, Flexbox的对齐项和对齐自性质 的 堆栈片段 I ran into an interesting CSS problem today, and I have been wracking my brain trying to solve it. This is similar to the trivial problem of "a row of three elements, with a left, a right, and center," which can be solved easily with flexbox — but it has a couple of caveats that make it (I think) an impossible layout without JavaScript. The desired goal Consider a row-like container element and three children, "left", "right", and "center". The children may be of varying widths, but they are all the same height. "Center" should try to stay centered relative to its container — but the three sibling elements must not overlap, and may push outside the container if necessary. The markup, then, might look something like this: The CSS is where the challenge is. Examples of what should happen For wide containers, "center" is centered relative to the container (i.e., its siblings' widths do not matter), as in the image below; notice that midpoint of the "center" element matches the midpoint of the container, and that the left and right "leftover" spaces are not equal: For narrower containers, "center" abuts the widest sibling, but it does not overlap. The remaining space is distributed only between the narrow sibling and the "center" sibling. Notice also that the container's midpoint, indicated by the caret, is no longer the same as "center's" midpoint: Finally, as the container continues to shrink, there's no other option but to have all three elements lined up in a row, overflowing the parent: My attempts to solve this Surprisingly, I haven't found a good way to implement this in pure CSS. You'd think flexbox would be the winner, but you can't really get flexbox to do it right: The Using (And float layouts can't get within a mile of getting this right.) I could combine the best two solutions above, and switch between them with a In short, there's no pure-HTML-and-CSS solution to this problem that I know of. Conclusion, and a JSFiddle to experiment with I created a JSFiddle that shows both the desired goal and a few non-solutions. Feel free to fork it and experiment. You can simulate the container resizing by grabbing the bar to the left of the content and dragging it. You are allowed to rearrange/restructure the HTML and CSS, if rewriting it gets you closer to a working answer. So does anyone have a solution to this that doesn't involve using JavaScript to intelligently distribute the space between the elements? With The main trick is For more versions, see this brilliant question/answer, flexbox-justify-items-and-justify-self-properties Stack snippet
这篇关于水平居中元素,以避免重叠的容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
< div class =container>
< div class =left>我是左边的内容。< / div>
< div class =center>我是中心内容。我比其他人长。< / div>
< div class =right> Right。< / div>
< / div>
< hr>
空间在元素之间均匀分配空间,所以中心元素实际上并不以居中为中心。 flex -
grow
/ shrink
/ basis
properties aren'因为它们负责控制子元素的大小,而不是控制它们之间的空间大小。
@media
查询 - 如果所有的宽度都是事先知道的。但他们不是,大小可能差别很大。
flexbox
你应该可以解决这个问题,通过给 right
元素 flex:1
和右边 text-align:right
。
$ b flex:1
,这将使它们平均分享可用空间。
body {font: 14px Arial;}。container {display:flex; border:1px solid#00F;}。container> div> span {display:inline-block;背景:#36F;白色空间:nowrap; padding:2px 4px; color:#FFF;}。container> .center> span {background:#696;}。container .left,.container .right {flex:1;}。container .right {text-align:right;}。 font-size:80%;}。注意{text-align:center;颜色:#666; font-style:italic; font-size:90%;}
< div class = 容器 > < div class =left> <跨度>我是左边的内容。 < /跨度> < / DIV> < div class =center> < span>我是中心内容。我比其他人长。< / span> < / DIV> < div class =right> <跨度>对。 < /跨度> < / div>< / div>< div class =center-mark> ^< / div>< div class =note>(centered marker / text) / code>
<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>
space-between
property distributes the space uniformly between the elements, so the center element doesn't actually end up centered. The flex-grow
/shrink
/basis
properties aren't especially useful for this either, since they're responsible for controlling the size of the child elements, not for controlling the size of the space between them.position:absolute
can solve it as long as the container is wide enough, but when the container shrinks, you end up with overlap.@media
query — if all of the widths were known in advance. But they aren't, and the sizes may vary widely.
flexbox
you should be able to solve that, by giving the left
/right
elements flex: 1
and the right text-align: right
.flex: 1
, which will make them share available space equally. 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>