为什么添加或删除边框会改变边距的工作方式? [英] Why is adding or removing a border changing the way margins work?
问题描述
如果我有一个容器,其中一个元素的内部有一个空白,则该元素空白不会将其向下推入该容器中,而是向下推入容器本身.仅此而已,虽然很烦人,但可能只是w3c决定它将如何工作的方式.但是很奇怪的是,如果我在容器上添加边框,则该元素现在将被推入容器中,然后容器将与上面的元素齐平(我想要的).到现在为止,我使用的大多数容器都带有边框,以便我可以判断所有内容如何排列,但是现在,我决定开始添加背景色并删除边距,以使所有内容看起来更加美观.容器之间没有应用背景色的容器之间存在间隙问题.
If I have a container with an element inside that has a margin, that elements margin will not push it down within that container but instead push down the container itself. That alone, while annoying, might just be how the w3c decided it would work. But the weird thing is, if I add a border to the container that element will now be pushed down within the container and the container will then be flush against the element above (what I want). Until now most of the containers I use have had borders so that I could tell how everything was lining up, but now that I have decided to start adding background-colors and removing margins to make everything look nicer I am running in to a ton of issues with gaps between containers that have neither of the containers background colors applied to them.
在不清楚的情况下,我创建了一个jsfiddle来演示该问题,如您所见,通过查看html/js,单击按钮只会切换边框的存在,而没有其他任何变化.但是,容器之间的所有边距都会根据边界是否存在而改变.
In case I was not clear I created a jsfiddle to demonstrate the issue, as you can see by looking at the html / js clicking the button only toggles the existence of a border and nothing else. Yet all the margins between the containers change based on whether or not the border is there.
http://jsfiddle.net/Tysonzero/p5fgjmrn/
HTML:
<div class="first-div">
</div>
<div class="second-div">
<div class="inner-div">Test</div>
</div>
<button onclick="toggle()">Toggle Border</button>
CSS:
*
{
box-sizing: border-box;
margin: 0;
padding: 0;
}
.first-div
{
background-color: red;
min-height: 50px;
}
.second-div
{
background-color: blue;
min-height: 50px;
}
.inner-div
{
margin: 10px;
text-align: center;
}
JS:
toggle = function() {
if (document.getElementsByClassName('second-div')[0].style.border) {
document.getElementsByClassName('second-div')[0].style.border = "";
}
else {
document.getElementsByClassName('second-div')[0].style.border = "1px solid";
}
};
我希望它始终与IMO的边界一起工作,这使更多的事情变得有意义,而对于我的项目,这正是我所需要的.我真的希望我不必做任何麻烦的事情,例如为所有内容添加1px透明边框,并在必要时进行补偿.我试过使用溢出:自动;或溢出:隐藏.但是,两者都没有边界.溢出:自动;如果里面的元素大于父元素,或者如果您以某种方式使用负边距而没有添加边框,则有时会创建滚动条.完全可以防止滚动,而添加边框则不能.
I want it to always work the way it works WITH a border as IMO that makes a ton more sense, and for my project it is what I need. I really hope I don't have to do something hacky such as add a 1px transparent border to everything and compensate for it when necessary. I have tried using overflow: auto; or overflow: hidden. But neither are the same as having a border. overflow: auto; will sometimes create scrollbars if the element inside is bigger than the parent or if you are using negative margins in a certain way whereas adding a border does not, overflow: hidden; completely prevents scrolling whereas adding a border does not.
有人知道我可以如何强制浏览器将所有内容都视为带有边框(或至少不会出现此类问题),并且有人可以解释这种现象吗?似乎是无意的,但我可能是错的.
Does anyone know how I can force the browser to treat everything as though it has a border (or at least make issues like this not happen) and also can anyone explain this behavior? It seems unintentional but I could be wrong.
推荐答案
您问题的具体答案是 W3C的BOX模型规范:
The specific answer to your question is collapsing margins and is part of the W3C's BOX MODEL specifications:
某些框之间的垂直边距可能会折叠:
Vertical margins may collapse between certain boxes:
- 正常流中块框的两个或多个相邻的垂直边距会折叠.产生的边距宽度是相邻边距宽度中的最大值.在负边距的情况下,从正向相邻边距的最大值中减去负向相邻边距的绝对值的最大值.如果没有正的边距,则从零中减去负的相邻边距的绝对最大值.笔记.相邻的框可能由与兄弟姐妹或祖先无关的元素生成.
- 浮动框和任何其他框之间的垂直边距不会折叠(即使在浮动框及其流入子框之间也不会折叠).
- 建立新块格式上下文的元素的垂直边距(例如浮点数和具有可见"以外的溢出"的元素)不会随其流入子元素而消失.
- 绝对定位的框的边距不会折叠(即使带有其流入子框也不会折叠).
- 内联块元素的边距不会折叠(即使带有其流入子元素也不会折叠).
- 如果框的顶部和底部边距相邻,则边缘可能会通过它塌陷.在这种情况下,元素的位置取决于其与其边距被折叠的其他元素的关系.
- 如果元素的边距与父级的上边距折叠在一起,则框的顶部边界将定义为与父级的边沿相同.
- 否则,要么元素的父级不参与边距崩溃,要么仅涉及父级的底边距.元素的顶部边框边缘的位置与元素的底部边框非零时的位置相同.
已应用间隙的元素永远不会折叠其父块底部边距的顶部边距.
An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
请注意,已折叠的元素的位置对其他以其边距折叠的元素的位置没有影响;仅在布置这些元素的后代时才需要顶部边框边缘位置.根元素框的边距不会折叠.
Note that the positions of elements that have been collapsed through have no effect on the positions of the other elements with whose margins they are being collapsed; the top border edge position is only required for laying out descendants of these elements. Margins of the root element's box do not collapse.
因此,当添加边框时,您正是按照规范的要求进行操作,因此没有边距.
So, when you add a border, you're doing exactly what the specification says, therefore you have no margin.
有很多方法,修复程序和技巧可以解决此问题,但是对我来说,最直接,最简单的方法就是将
overflow:auto;
属性应用于您要清除的div边距.There are many ways and fixes and hacks to solve this, but to me, the most direct and easy is as simple as to apply an
overflow:auto;
property to the div you want to clear the margin.因此,在CSS中,您只需要像这样更改它:
Thus, in your CSS, you would only need to change it like this:
.second-div { background-color: blue; min-height: 50px; overflow:auto; }
我 分叉了小提琴 ,因此边框更大,因此您可以注意到效果看看效果如何
I forked your fiddle with even more border so you can notice the effect and see how good it works
这篇关于为什么添加或删除边框会改变边距的工作方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!