CSS 为什么这个内联块元素被向下推?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9273016/
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
Why is this inline-block element pushed downward?
提问by Shawn Taylor
Following is my code and I want to understand that why#firstDiv is being pushed downward by all browsers. I really want to understandthe inner workings of the fact that why its being pushed downward rather than pulling it upward by one way or another. (and I know how to align their tops :))
以下是我的代码,我想了解为什么所有浏览器都将 #firstDiv 向下推。我真的很想了解为什么它被向下推而不是以一种或另一种方式向上拉的事实的内部运作。(我知道如何对齐他们的上衣:))
And I know that its overflow:hidden which is causing it but not sure that why its pushing that div downward.
而且我知道它的 overflow:hidden 是导致它的原因,但不确定为什么它会向下推动该 div。
body {
width: 350px;
margin: 0px auto;
}
#container {
border: 15px solid orange;
}
#firstDiv {
border: 10px solid brown;
display: inline-block;
width: 70px;
overflow: hidden;
}
#secondDiv {
border: 10px solid skyblue;
float: left;
width: 70px;
}
#thirdDiv {
display: inline-block;
border: 5px solid yellowgreen;
}
<div id="container">
<div id="firstDiv">FIRST</div>
<div id="secondDiv">SECOND</div>
<div id="thirdDiv">THIRD
<br>some more content<br> some more content
</div>
</div>
回答by Gary Lindahl
Basically you have added more clutter in your code which is creating more confusion so first I try to remove clutter which hinders understanding the real issue.
基本上你在你的代码中添加了更多的混乱,这造成了更多的混乱,所以首先我尝试消除阻碍理解真正问题的混乱。
First of all we have to establish that what's the real question?
Its that why "inline-block
" element is pushed downward.
首先,我们必须确定真正的问题是什么?
这就是为什么 " inline-block
" 元素被向下推。
Now we start to understand it and remove the clutter first.
现在我们开始了解它并首先消除杂波。
1 -Why not give all three divs same border width? Let's give it.
1 -为什么不给所有三个 div 相同的边框宽度? 让我们给它。
2 -Does floating element has any connection with inline-block element being pushed downward? No, it has nothing to do with it.
2 -浮动元素与被向下推的内联块元素有任何联系吗?不,这与它无关。
So, we have removed that div altogether. And you are witnessing same behavior of inline-block element being pushed downward.
所以,我们已经完全删除了那个 div。并且您正在目睹内联块元素被向下推的相同行为。
Here comes the turn of some literatureto grasp the idea of line boxes and how they are lined in the same line esp read last paragraph carefully because there lies the answer of your question.
现在轮到一些文献来掌握线框的概念以及它们如何排列在同一行中,尤其是仔细阅读最后一段,因为这就是您问题的答案。
The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.
'inline-block' 的基线是它在正常流中的最后一个 line box 的基线,除非它没有 in-flow line box 或者它的 'overflow' 属性的计算值不是 'visible',在在这种情况下,基线是底部边距边缘。
If you are not sure about baselinethen here is brief explanation in simple words.
如果您不确定基线,那么这里用简单的话进行简要说明。
All characters except 'gjpqy' are written on the baseline you can think of baseline as if you draw a simple horizontal line same as underlining right below these "random characters" then it will be the baseline but now if you write any of 'gjpqy' character(s) on the same line then lower part of these characters would fall below the line.
除了“gjpqy”之外的所有字符都写在基线上,您可以将基线视为在这些“随机字符”下方绘制一条与下划线相同的简单水平线,那么它将成为基线,但现在如果您写下任何“gjpqy”同一行上的字符,那么这些字符的下部将落在该行下方。
So, we can say that all characters except 'gjpqy' are written completely above the baseline while some part of these characters are written below the baseline.
所以,我们可以说除了'gjpqy'之外的所有字符都完全写在基线之上,而这些字符的一部分写在基线之下。
3 -Why not check where is the baseline of our line? I have added few characters which show the baselineof our line.
3 -为什么不检查我们生产线的基线在哪里?我添加了几个字符来显示我们行的基线。
4 -Why not add some characters in our divs too to find their baselines in the div? Here, some characters added in divs to clarify baseline.
4 -为什么不在我们的 div 中添加一些字符以在 div 中找到它们的基线?在这里,在 div 中添加了一些字符以阐明基线。
Now when you understand about baseline, read the following simplified version about baseline of inline-blocks.
现在,当您了解基线时,请阅读以下有关内联块基线的简化版本。
i) If inline-block in question has its overflow property set to visible (which is by default so no need to set though). Then its baseline would be the baseline of the containing block of the line.
i) 如果有问题的内联块将其溢出属性设置为可见(默认情况下,因此无需设置)。那么它的基线将是该行包含块的基线。
ii) If inline-block in question has its overflow property set to OTHER THAN visible. Then its bottom margin would be on the baseline of the line of containing box.
ii) 如果有问题的内联块的溢出属性设置为其他可见。那么它的底部边距将在包含框线的基线上。
- First point in detail
- 第一点详细
Now look at this again to clarify your concept that what's happening with green div. If yet any confusion then here is added more characters close to green div to establish the baseline of the containing blockand green div baseline is aligned.
现在再看看这个,以澄清你的概念,即绿色 div 发生了什么。如果还有任何混淆,那么这里添加更多靠近绿色 div 的字符以建立包含块的基线,并且绿色 div 基线对齐。
Well, I am now claiming that they have same baseline? RIGHT?
好吧,我现在声称他们有相同的基线?对?
5 -Then why not overlap them and see if they are fit right one on another? So, I bring third div -left: 35px; to check if they have same baseline now?
5 -那为什么不把它们重叠起来,看看它们是否合适?所以,我带来了第三个 div -left: 35px; 检查他们现在是否有相同的基线?
Now, we have got our first point proved.
现在,我们已经证明了我们的第一点。
- Second point in detail
- 第二点详细
Well, after explanation of first point second point is easily digestible and you see that first div which has overflow property set to other than visible (hidden) has its bottom margin on the base line of the line.
好吧,在解释了第一点之后,第二点很容易理解,你会看到第一个溢出属性设置为可见(隐藏)以外的 div 的底部边距在线的基线上。
Now, you can do couple of experiments to further illustrate it.
现在,您可以做几个实验来进一步说明它。
- Set first div overflow:visible (or remove it altogether).
- Set second div overflow: other than visible.
- Set both divs overflow: other than visible.
Now bring back your clutter and see if everything is looking to fine to you.
现在带回您的杂物,看看是否一切都对您来说很好。
- Bring back your floated div(of course there is need to
increase some width of body) You see it has no effect. - Bring back same odd margins.
- Set green div to overflow: visible as you set in your question(that misalignment is due to increase of border width from 1px to 5px so if adjust negative leftyou'll see there is no issue)
- Now remove additional characters I added to aid in understanding. (and of course remove negative left)
- Finally reduce body widthbecause we no longer need wider one.
- 带回来的液浮格(当然有必要
增加身体的某些宽度)你看它有没有效果。 - 带回相同的奇数利润率。
- 将绿色 div设置为溢出:在您的问题中设置可见(该错位是由于边框宽度从 1px 增加到 5px,因此如果向左调整负值,您会发现没有问题)
- 现在删除我添加的其他字符以帮助理解. (当然删除负左)
- 最后减少主体宽度,因为我们不再需要更宽的宽度。
And now we are back to where we started from.
现在我们又回到了起点。
Hopefully I have answered your question.
希望我已经回答了你的问题。
回答by sandeep
The default value for vertical-align
in CSS is baseline
& this rule is also apply with inline-block
read this http://www.brunildo.org/test/inline-block.html
vertical-align
CSS 中的默认值是baseline
& 此规则也适用于inline-block
阅读此http://www.brunildo.org/test/inline-block.html
Write vertical-align:top
in your inline-block
DIV.
写vertical-align:top
在你的inline-block
DIV 中。
Check this http://jsfiddle.net/WGCyu/1/
回答by Zeta
View thisalternative example. The reason for such behavior is described in CSS3 module: line: 3.2. Line Box wrapping [1]:
查看此替代示例。这种行为的原因在CSS3 module: line: 3.2 中有描述。线盒包装 [1]:
In general, the start edge of a line box touches the start edge of its containing block and the end edge touches the end edge of its containing block. However, floating boxes may come between the containing block edge and the line box edge. Thus, although line boxes in the same inline formatting context generally have the same inline progression advance (that of the containing block), they may vary if available inline-progression space is reduced due to floats[...]
通常,行框的起始边缘与其包含块的起始边缘相接触,而结束边缘与其包含块的终止边缘相接触。但是,浮动框可能会出现在包含块边缘和行框边缘之间。因此,尽管同一行内格式上下文中的行框通常具有相同的行内进度推进(包含块的行进推进),但如果可用行内推进空间因浮动而减少 [...]
As you can see, the third element is pushed downward, although it does not have a overflow
property. The reason must be somewhere else to find. The second behavior you notice is described in Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification: 9.5 Floats [2]:
如您所见,第三个元素被向下推,尽管它没有overflow
属性。原因一定是在别处找。您注意到的第二种行为在Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification: 9.5 Floats [2] 中描述:
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.
由于浮动不在流中,因此在浮动框之前和之后创建的非定位块框垂直流动,就好像浮动不存在一样。但是,在浮动旁边创建的当前和后续行框会根据需要缩短,以便为浮动的边距框腾出空间。
All your display:inline-block;
divs are using a special kind of baseline
in this case 10.8 Line height calculations: the 'line-height' and 'vertical-align' properties (very end) [3]:
在这种情况下,您所有的display:inline-block;
div 都使用一种特殊的10.8 行高计算:“行高”和“垂直对齐”属性(最后)[3]:baseline
The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.
'inline-block' 的基线是它在正常流中的最后一个 line box 的基线,除非它没有 in-flow line box 或者它的 'overflow' 属性的计算值不是 'visible',在在这种情况下,基线是底部边距边缘。
So when you're using floating elements and inline-block
elements, the floating element will be pushed to the side and the inline formatting will be recalculated according to 1. On the other hand, the next elements are shortened if they won't fit. Since you're already working with a minimum amount of space, there's no other way to modify your elements then pushing them 2. In this case, the highest element will define the size of your wrapping div, thus defining the baseline
3, while on the other hand the modification of position and width stated in 2can't be applied to such minimal spaced maximum height elements. In this case a behavior as in my very first demo will result.
所以当你使用浮动元素和inline-block
元素时,浮动元素会被推到一边,内联格式会根据1重新计算。另一方面,如果下一个元素不适合,则会缩短它们。由于您已经使用了最少的空间,因此没有其他方法可以修改元素然后将它们推入2。在这种情况下,最高元素将定义环绕 div 的大小,从而定义baseline
3,而另一方面,2 中声明的位置和宽度的修改不能应用于这种最小间距的最大高度元素。在这种情况下,将导致我的第一个演示中的行为。
Lastly, the reason your overflow:hidden
will prevent #firstDiv
to be pushed to the lower edge of your #container
, although I couldn't find a reason in section 11. Without overflow:hidden
it works as excepted and defined by 2and 3. Demo
最后,你的overflow:hidden
will 阻止#firstDiv
被推到你的下边缘的#container
原因,虽然我在第 11 节中找不到原因。没有overflow:hidden
它,它按2和3 的例外和定义工作。演示
TL;DR:Have a very close look on the W3 recommendations and the implementations in the browser. In my humble opinion floating elements are determined to show unexpected behavior if you don't know all the changes they do to your surrounding elements. Here's another demowhich shows a common problem with floats.
TL;DR:仔细查看 W3 建议和浏览器中的实现。在我的拙见中,如果您不知道浮动元素对周围元素所做的所有更改,浮动元素就会表现出意想不到的行为。这是另一个演示,它显示了浮动的常见问题。
回答by awe
I originally started on answering this question, but it was locked as dupe before I could finish, so I post the answer here instead.
我最初开始回答这个问题,但在我完成之前它被锁定为欺骗,所以我把答案贴在这里。
First, we need to understand what inline-block
is.
The definition in MDNsays:
首先,我们需要了解什么inline-block
是。MDN 中
的定义说:
The element generates a block element box that will be flowed with surrounding content as if it were a single inline box (behaving much like a replaced element would)
该元素生成一个块元素框,它将与周围的内容一起流动,就好像它是一个单独的内联框(行为很像被替换的元素)
To understand what's going on here, we need to look at vertical-align
, and it's default value baseline
.
要了解这里发生了什么,我们需要查看vertical-align
,它是默认值baseline
。
In this illustration you have this color chart:
Blue: The baseline
Red: The top and bottom of the line-height
Green: The top and bottom of the inline content box.
在此插图中,您有以下颜色图表:
蓝色:基线
红色:行高
的顶部和底部 绿色:内联内容框的顶部和底部。
In the #left element, you do have some textual content that controls what is the baseline. This means that the text inside defines the baseline for #left.
In the #right, there is no content, so the browser has no other option than to use the box bottom as the baseline.
在#left 元素中,您确实有一些控制基线的文本内容。这意味着里面的文本定义了#left 的基线。
在#right 中,没有内容,因此浏览器除了使用框底部作为基线之外别无选择。
Se this visualisation where I have drawn the baseline on an example where the first inline container has some text, and the next is empty:
在这个可视化中,我在一个示例上绘制了基线,其中第一个内联容器有一些文本,而下一个是空的:
If you specifically align one element to top, you really say that you align the top of this element to the top of of the line box.
如果您专门将一个元素与顶部对齐,那么您实际上是在将此元素的顶部与行框的顶部对齐。
This might be easier to understand by an example.
举个例子可能更容易理解。
div {
display: inline-block;
width: 100px;
height: 150px;
background: gray;
vertical-align: baseline;
}
div#middle {
vertical-align: top;
height: 50px
}
div#right {
font-size: 30px;
height: 100px
}
<div id="left">
<span>groovy</span>
</div>
<div id="middle">groovy</div>
<div id="right">groovy</div>
The result is this - and I added the blue baseline, and the red line box:
What happens here, is that the height of line box is depended on how the the content of the entire line is laid out. This means that to calculate the top alignment, the basline alignments must be calculated first. The #middle
element has vertical-align:top
, so this is not used for the baseline positioning. but the #left
and #right
are positioned vertically so that their baselines are aligned. When this is done, the height of the line box has increased, because the #right
element has been pushed up a bit as a result of the larger font size. Then the top position for the #middle
element can be calculated, and this is along the top of the line box.
结果是这样的 - 我添加了蓝色基线和红色线框:
这里发生的是,线框的高度取决于整行内容的布局方式。这意味着要计算顶部对齐,必须首先计算基线对齐。该元件具有,因此不用于基线的定位。但是和垂直放置,以便它们的基线对齐。这样做后,行框的高度增加了,因为元素由于字体大小变大而被向上推了一点。然后可以计算元素的顶部位置,这是沿着行框的顶部。#middle
vertical-align:top
#left
#right
#right
#middle
回答by Pal Singh
the problem is because you have applied float:left on the second div. which makes the second div to come on the left side and your first div drops and comes after your second div. If you apply float:left on the first div also, your problem will be gone.
问题是因为您在第二个 div 上应用了 float:left 。这使得第二个 div 出现在左侧,而您的第一个 div 下降并出现在您的第二个 div 之后。如果你在第一个 div 上应用 float:left ,你的问题就会消失。
overflow:hidden is causing no problem to your layout, overflow:hidden affects only inner elements of a div, it has nothing to do with other elements which are outside.
overflow:hidden 不会对您的布局造成任何问题,overflow:hidden 仅影响 div 的内部元素,与外部的其他元素无关。
回答by LOLZ
Try adding padding:0;
to the body and removing the margin of your divs.
尝试添加padding:0;
到正文并删除 div 的边距。
Add background-color:*any
color aside from background* to check the difference.
添加background-color:*any
除背景 * 之外的颜色以检查差异。
回答by Rahul Varadkar
Try making all CSS properties of all Elements same.
尝试使所有元素的所有 CSS 属性都相同。
I had similar problem and while fixing this I identified that I was dropping an Element with Font property into Div Element.
我遇到了类似的问题,在解决这个问题时,我发现我正在将一个具有 Font 属性的元素放入 Div 元素中。
After dropping that Element with Font property the alignment of all DIV was disturbed. To fix this I set Font property to all DIV elements the same as the element that is dropped into it.
在删除带有 Font 属性的 Element 后,所有 DIV 的对齐方式都被打乱了。为了解决这个问题,我将 Font 属性设置为与放入其中的元素相同的所有 DIV 元素。
In the following example, the Dropped element of class ".dldCuboidButton" defined with font-size:30 px.
在以下示例中,使用 font-size:30 px 定义的类“.dldCuboidButton”的 Dropped 元素。
So I added same property to remaining classes i.e. .cuboidRecycle, .liCollect , .dldCollect which are used by DIV elements. In that way all DIV element follow the same Measurments before and after dropping the element into it.
所以我向剩余的类添加了相同的属性,即 DIV 元素使用的 .cuboidRecycle、.liCollect、.dldCollect。这样,所有 DIV 元素在将元素放入其中之前和之后都遵循相同的 Measurments。
.cuboidRecycle {
height:40px;
width:'20px; float:right';
overflow:'none';
background-color:#cab287;
color:#ffffff;
border-radius:8px;
text-align:'center';
vertical-align:'top';
display: inline-block;
font-size: 30px; /* Set a font-size */
}
.liCollect {
height:40px;
width:'20px; float:right';
overflow:'none';
background-color:#cab287;
color:#ffffff;
border-radius:8px;
text-align:'center';
vertical-align:'top';
display: inline-block;
font-size: 30px; /* Set a font-size */
}
.dldCollect {
height:40px;
width:'20px; float:right';
overflow:'none';
background-color:#009933;
color:#ffffff;
border-radius:8px;
text-align:'center';
vertical-align:'top';
display: inline-block;
font-size: 30px; /* Set a font-size */
}
.dldCuboidButton {
background-color: #7c6436;
color: white; /* White text */
font-size: 30px; /* Set a font-size */
border-radius: 8px;
margin-top: 1px;
}
Here is the example of HTML dynamically created using above CSS.
这是使用上述 CSS 动态创建的 HTML 示例。
$("div#tabs").append(
"<div id='" + newTabId + "'>#" + uniqueId +
"<input type=hidden id=hdn_tmsource_" + uniqueId + " value='" + divTmpfest + "'>" +
"<input type=hidden id=leCuboidInfo_" + uniqueId + " value=''>" +
"<div id='" + divRecycleCuboid + "' class=cuboidRecycle ondrop='removeDraggedCuboids(event, ui)' ondragover='allowDrop(event)'><font size='1' color='red'> Trash bin </font></div>" +
"<div id='" + divDropLeCuboid + "' class=liCollect ondrop='dropForLinkExport(event)' ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Manifest Cuboid here</font></div>" +
"<div id='" + divDropDwldCuboid + "' class=dldCollect ondrop='dropForTMEntry(event)' ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Cuboids here..</font></div>" +
"</div>"
);