为什么这个内联块元素向下推?

以下是我的代码,我想了解为什么 #firstDiv被所有浏览器向下推。我真的想理解内部工作的事实,为什么它被向下推,而不是拉它向上以这样或那样的方式。(而且我知道如何对齐它们的顶部:))

我知道它的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>

http://jsfiddle.net/WGCyu/

164453 次浏览

CSS中vertical-align的默认值是baseline &此规则也适用于inline-block读取此http://www.brunildo.org/test/inline-block.html

在你的inline-block DIV中写入vertical-align:top

检查这个http://jsfiddle.net/WGCyu/1/

这个问题是因为你在第二个div上应用了float:left,这使得第二个div位于左侧,第一个div落在第二个div之后。 如果你在第一个div上也使用float:left,你的问题就会消失

溢出:隐藏不会对你的布局造成任何问题,溢出:隐藏只影响一个div的内部元素,它与外部的其他元素无关。

查看替代示例。这种行为的原因在CSS3模块:行:3.2。线盒包装[1]中描述:

一般情况下,行盒的开始边与包含它的块的开始边相接触,结束边与包含它的块的结束边相接触。但是,浮动框可能位于包含块边缘和行框边缘之间。因此,尽管在同一行内格式化上下文中的行框通常具有相同的行内进度推进(包含块的行内进度推进),但如果可用的行内进度空间由于浮动而减少,它们可能会有所不同[…]

正如你所看到的,第三个元素被向下推,尽管它没有overflow属性。原因一定在别的地方。你注意到的第二个行为在级联样式表Level 2 Revision 1 (CSS 2.1)规范:9.5 Floats [2]中描述:

由于浮动不在流中,因此在浮动框之前和之后创建的非定位块框垂直流动,就好像浮动不存在一样。但是,在浮动旁边创建的当前和后续行框将根据需要缩短,以便为浮动的边距框腾出空间。

你所有的display:inline-block; div都在使用一种特殊的baseline,在本例中是10.8行高计算:' Line -height'和'vertical-align'属性(very end) [3]:

'inline-block'的基线是它在正常流中的最后一个行框的基线,除非它没有流中的行框,或者它的'overflow'属性有一个计算值而不是'visible',在这种情况下基线是底边距。

因此,当你使用浮动元素和inline-block元素时,浮动元素将被推到一边,并且行内格式将根据1重新计算。另一方面,如果下一个元素不适合,它们就会被缩短。由于你已经在使用最小的空间,没有其他方法来修改你的元素,然后将它们推入2。在这种情况下,最高的元素将定义包装div的大小,从而定义baseline 3.,而另一方面,2中所述的位置和宽度的修改不能应用于这种最小间距的最大高度元素。在这种情况下,就会产生我的第一个演示中的行为。

最后,你的overflow:hidden将阻止#firstDiv被推到你的#container的下边缘的原因,尽管我在11节中找不到原因。如果没有overflow:hidden,它会像23.所定义的那样工作。演示

TL;博士:有一个非常密切的关注W3的建议和实现在浏览器。在我看来,如果你不知道浮动元素对周围元素的所有改变,它们就会显示出意想不到的行为。下面是另一个演示,它显示了浮点数的一个常见问题。

基本上,你已经在你的代码中添加了更多的混乱,这造成了更多的混乱,所以首先我试着删除阻碍理解真正问题的混乱。

首先,我们必须确定真正的问题是什么? 这就是为什么"inline-block"元素被向下推

现在我们开始理解它,并首先清除混乱。

< >强1 - 为什么不给所有三个div相同的边界宽度? 让我们给它。 < / p >

2 -浮动元素是否与向下推的内联块元素有任何连接?

.

.

所以,我们已经完全删除了这个div。你看到了内联块元素向下推的相同行为。

现在轮到一些文学来掌握行盒的思想,以及它们是如何在同一行中排列的,特别是仔细阅读最后一段,因为这是你问题的答案。

'inline-block'的基线是它在正常流中的最后一个行框的基线,除非它没有流中的行框,或者它的'overflow'属性有一个计算值而不是'visible',在这种情况下基线是底边距。

如果你不确定基线,那么这里是简单的解释。

除了“gjpqy”之外的所有字符都写在基线上,你可以把基线想象成如果你画一条简单的水平线,就像在这些“随机字符”下面画下划线一样,那么它将是基线,但现在如果你在同一条线上写任何“gjpqy”字符,那么这些字符的较低部分将落在线以下。

因此,我们可以说,除了'gjpqy'之外的所有字符都完全写在基线之上,而这些字符的一部分写在基线之下。

为什么不检查我们的线的基线在哪里? 我在我们的行中添加了显示基线的字符很少 为什么不在div中添加一些字符来查找div中的基线呢? 在这里,在div中添加了一些字符以澄清基线。< / p >

现在,当你理解了基线,阅读以下关于内联块基线的简化版本。

i)如果inline-block的overflow属性被设置为可见(这是默认情况,所以不需要设置)。 那么它的基线将是该行所在块的基线

ii)如果所讨论的inline-block的overflow属性设置为OTHER THAN visible。

  • 第一点
< p >现在再看一遍,明确一下绿色div的概念。 如果仍有任何混淆,则这里添加了更多靠近绿色div的字符,以建立包含块的基线和绿色div基线对齐

我现在说他们有相同的基线?对吧?

那么为什么不重叠它们,看看它们是否适合彼此? 因此,我引入第三个div -left: 35px;来检查他们现在是否有相同的基线吗?< / p >

现在,我们已经证明了第一点。

  • 第二点细节

好了,在解释了第一点之后,第二点就很容易理解了,你会看到第一个div的溢出属性设置为除了可见(隐藏)之外,它的底边距在一行的基线上。

现在,你可以做几个实验来进一步说明。

  1. 设置第一个div溢出:可见(或完全删除它)
  2. 设置第二个div溢出:除了可见的
  3. 设置两个div都溢出:除了可见

现在把你那些乱七八糟的东西拿回来,看看你是否觉得一切都好。

    返回浮动div(当然需要
    增加身体的宽度) 你看它没有效果。
  1. 带回相同的奇数边距
  2. 设置绿色div溢出:可见于您设置在您的问题(不对齐是由于边界宽度从1px增加到5px,所以如果调整左负,你会发现没有问题)
  3. 现在删除我添加的额外字符 理解< / >。(当然,移除左负)
  4. 最后减小体宽,因为我们不再需要更宽的。

现在我们又回到了起点。

希望我已经回答了你的问题。

只需使用vertical-align:top;即可

演示< a href = " http://jsfiddle.net/WGCyu/1007/ " > < / >

尝试将padding:0;添加到主体并删除div的边缘。

除了background*,添加background-color:*any color来检查差异。

尝试使所有元素的所有CSS属性相同。

我有类似的问题,在修复这个问题时,我发现我正在删除一个具有字体属性的元素到Div元素。

在删除带有字体属性的元素后,所有DIV的对齐都被打乱了。为了解决这个问题,我将字体属性设置为所有DIV元素,与放入其中的元素相同。

在下面的例子中,类的Dropped元素”。dldCuboidButton"用font-size:30 px定义。

因此,我将相同的属性添加到其余的类,即. cuboidrecycle, . licollect, . dldcollect,这些都是由DIV元素使用的。通过这种方式,所有DIV元素在放入元素之前和之后遵循相同的测量。

.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;
}

下面是使用上述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>"
);

我最初开始回答这个问题,但在我能完成之前,它被锁定为欺骗,所以我把答案贴在这里。

首先,我们需要理解inline-block是什么 MDN定义说:

元素生成一个块元素框,该块元素框将与它一起流动 围绕内容,就好像它是一个内联框(行为 例如替换的元素)

为了理解这里发生了什么,我们需要看看vertical-align,它的默认值是baseline

< p > 垂直位置可视化 < br > 在这个插图中,你有这个颜色图表:
蓝色:基线
红色:line-height
的顶部和底部 绿色:内嵌内容框的顶部和底部。< / p > 在#left元素中,确实有一些控制基线的文本内容。这意味着里面的文本定义了#left.
的基线 在#右侧,没有内容,所以浏览器只能使用框底部作为基线。< / p >

Se这个可视化的地方,我已经在一个例子中绘制了基线,其中第一个内联容器有一些文本,下一个是空的:

基线绘制

如果你特别地将一个元素对齐到顶部,你实际上是在将这个元素的顶部对齐到行框的顶部。

举个例子可能更容易理解。

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>

结果是这样的-我添加了蓝色基线和红色线框: Explained vertical-align < br > 这里的情况是,行盒的高度取决于整行内容的布局方式。这意味着要计算顶部对齐,必须首先计算基线对齐。#middle元素有vertical-align:top,所以它不用于基线定位。但是#left#right是垂直放置的,这样它们的基线是对齐的。当这样做时,行框的高度增加了,因为#right元素由于更大的字体大小而被向上推了一点。然后可以计算#middle元素的顶部位置,这是沿着行框的顶部