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

时间:2012-02-14 07:09:18

标签: overflow css

以下是我的代码,我想了解为什么 #firstDiv被所有浏览器向下推。我真的想理解事实的内在运作,即为什么它被向下推,而不是以某种方式向上拉。 (我知道如何调整他们的上衣:))

而且我知道它的溢出:隐藏了导致它,但不确定为什么它推动该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/

8 个答案:

答案 0 :(得分:340)

基本上你在你的代码中添加了更多的混乱,这造成了更多的混乱,所以首先我尝试去除那些妨碍理解真正问题的混乱。

首先,我们必须确定真正的问题是什么? 这就是“inline-block”元素向下推的原因。

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

1 - 为什么不给所有三个div相同的边框宽度? Let's give it.

2 - 浮动元素是否与向下推的内联块元素有任何关联? 不,它与它无关。

所以,we have removed that div altogether。并且您正在目睹内联块元素被向下推的相同行为。

转向某些literature以掌握线框的概念以及它们如何在同一行中排列,特别是仔细阅读上一段,因为答案就在于你的问题。

  

“内联块”的基线是正常流程中其最后一个线框的基线,除非它没有流入线框或者其“溢出”属性的计算值不是“可见” ',在这种情况下,基线是底部边缘边缘。

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

除了'gjpqy'之外的所有字符都写在您可以想到基线的基线上,就好像您在这些“随机字符”下方绘制一条与下划线相同的简单水平线,然后它将成为基线,但现在如果您写任何一个'gjpqy'字符位于同一行,然后这些字符的下半部分将落在该行下方。

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

3 - 为什么不查看我们行的基线在哪里? 我添加了few characters which show the baseline我们的行。

4 - 为什么不在我们的div中添加一些字符来在div中找到它们的基线? 在这里,some characters added in divs to clarify baseline

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

i)如果有问题的inline-block将其overflow属性设置为visible(默认情况下不需要设置)。 然后它的基线将是该行的包含块的基线。

ii)如果有问题的内联块的溢出属性设置为OTHER THAN可见。 然后它的底部边距将位于包含框的行的基线上。

  • 第一点详细

现在look at this again to clarify your concept that what's happening with green div。 如果还有任何混淆,那么here is added more characters close to green div to establish the baseline of the containing block和绿色div基线就会对齐。

嗯,我现在声称他们有相同的基线? RIGHT?

5 - 然后为什么不重叠它们,看看它们是否适合另一个? 所以,我带来第三个div -left:35px; to check if they have same baseline now

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

  • 详细第二点

好吧,在解释第一个点之后第二个点很容易消化,你会发现溢出属性设置为可见(隐藏)以外的第一个div在该行的基线上有它的下边距。

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

  1. 设置first div overflow:visible (or remove it altogether)
  2. 设置second div overflow: other than visible
  3. 设置both divs overflow: other than visible
  4. 现在把你的混乱带回来,看看你的一切是否正常。

    1. 带来back your floated div(当然需要有 增加一些身体的宽度) 你看它没有效果。
    2. Bring back same odd margins
    3. 设置green div to overflow: visible as you set in your question(错位是由于边框宽度从1px增加到5px所以如果adjust negative left你会看到没有问题)
    4. 现在remove additional characters I added to aid in understanding。 (当然还有消极的左侧)
    5. 最后reduce body width因为我们不再需要更宽的一个。
    6. 现在我们回到了我们开始的地方。

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

答案 1 :(得分:313)

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

vertical-align:top DIV。

中写下inline-block

选中此http://jsfiddle.net/WGCyu/1/

答案 2 :(得分:30)

只需使用vertical-align:top;

即可

Demo

答案 3 :(得分:8)

查看this替代示例。 CSS3 module: line: 3.2. Line Box wrapping [1]

中描述了此类行为的原因
  

通常,线框的起始边接触其包含块的起始边缘,而结束边接触其包含块的结束边缘。但是,浮动框可能位于包含块边缘和线框边缘之间。因此,尽管相同内联格式化上下文中的线框通常具有相同的内联进展(包含块的内容),但如果由于浮动可以减少内联进展空间,它们可能会发生变化[...]

如您所见,第三个元素向下推,但它没有overflow属性。原因必须在其他地方找到。您注意到的第二种行为在Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification: 9.5 Floats [2]

中有所描述
  

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

在这种情况下,10.8 Line height calculations: the 'line-height' and 'vertical-align' properties (very end) [3]所有display:inline-block; div都使用了一种特殊的baseline

  

“内联块”的基线是正常流程中其最后一个线框的基线,除非它没有流入线框或者其“溢出”属性的计算值不是“可见” ',在这种情况下,基线是底部边缘边缘。

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

最后,您overflow:hidden阻止#firstDiv被推到#container的下边缘的原因,尽管我在section 11找不到原因。如果没有overflow:hidden,则23将其作为例外和定义。 Demo

TL; DR:非常仔细地了解W3建议和浏览器中的实现。在我看来,如果您不知道他们对周围元素所做的所有更改,浮动元素将被确定为显示意外行为。这是另一个demo,它显示了浮点数的常见问题。

答案 4 :(得分:2)

我最初是从回答this question开始的,但是在完成之前它被锁定为dupe,所以我将答案发布在这里。

首先,我们需要了解inline-block是什么。
definition in MDN说:

  

该元素生成一个块元素框,该框将随   周围的内容,就好像它是一个内嵌框(行为   就像被替换的元素一样)

要了解这里发生的情况,我们需要查看vertical-align,它是默认值baseline

vertical position visualizations
在此插图中,您具有以下颜色图表:
蓝色:基线
红色:行高的顶部和底部
绿色:内联内容框的顶部和底部。

在#left元素中,您确实有一些文本内容可以控制基线。这意味着其中的文本定义了#left的基线。
在#right中,没有任何内容,因此浏览器除了使用框底部作为基准外没有其他选择。

在此可视化中,我在第一个内联容器包含一些文本,而下一个为空的示例上绘制了基线:

Baseline drawn

如果您将一个元素专门对齐到顶部,您实际上是说您将该元素的顶部与行框的顶部对齐。

通过示例可能更容易理解。

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
这里发生的是,线框的高度取决于整个行内容的布局方式。这意味着要计算顶部路线,必须首先计算基线路线。 #middle元素具有vertical-align:top,因此它不用于基线定位。但是#left#right垂直放置,以便它们的基线对齐。完成此操作后,行框的高度增加了,因为#right元素由于较大的字体大小而被向上推了一点。然后可以计算#middle元素的顶部位置,该位置位于行框的顶部。

答案 5 :(得分:1)

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

overflow:hidden对你的布局没有任何问题,overflow:hidden只影响div的内部元素,它与外面的其他元素无关。

答案 6 :(得分:0)

尝试将padding:0;添加到正文并删除div的边距。

在背景*之外添加background-color:*any颜色以检查差异。

答案 7 :(得分:0)

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

我有类似的问题,在修复此问题时,我发现我正在将一个带有Font属性的元素放入Div Element中。

删除具有Font属性的Element后,所有DIV的对齐都会受到干扰。为了解决这个问题,我将Font属性设置为与放入其中的元素相同的所有DIV元素。

在下面的示例中,类&#34; .dldCuboidButton&#34;的Dropped元素用font-size定义:30 px。

所以我将相同的属性添加到剩余的类中,即.cuboidRecycle,.liCollect,.dldCollect由DIV元素使用。这样,所有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;
  }

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