内联块内的块元素在 Firefox 中表现异常
Block element inside inline-block acting strangely in Firefox
谁能解释一下 FF 中的这种行为?
Fiddle: http://jsfiddle.net/4mrt8wq3/
<style>
.b { display: inline-block; }
#a { display: block; }
</style>
<div class="b">
<label>xxxxxxxxxx</label>
<input type="text" id="a"/>
</div>
<div class="b">
<label>xxxxxxxxxx</label>
<div> / </div>
</div>
只有在 firefox 中,第一个 div 比第二个低一行。它在 Chrome 和 IE(至少 IE11)中正常工作。就好像内联块中的块元素出于某种原因在第二个元素下方换行。
在第一个 div 上使用 overflow: hidden 解决了这个问题,但是第二个 div 的位置有点奇怪,上面有大约 4 或 5 个像素的边距。将 overflow-hidden 放在两者上会使其正确呈现。
我不是在寻找问题的解决方案,因为我已经找到了一个,但我无法解释这种行为... 谁能解释为什么要这样做?
您的问题是根据规范设置 overflow:hidden 更改了内联块的基线位置。 Firefox 实现了规范所说的内容。 Chrome 没有。
解决方案:
<style>
.b { display: inline-block;
vertical-align: top; /*add this line */
}
#a { display: block; }
</style>
是的,有趣的问题。首先我们要明白,inline-block元素默认的垂直对齐方式是baseline,每一个这样的元素的baseline就是其中最后一个line box的baseline
在第二个 div 和 class "b" 中,内部 div 本身包含一个行框来容纳 '/' 字符。然后为第二个 div 提供基线 class "b".
该基线必须与第一个 div 和 class "b" 的基线对齐。问题就变成了:那个div?
最后一个line box的基线在哪里
通过使输入元素本身成为 display:block
,Firefox¹ 认为输入元素是 "replaced",它的内容对 CSS 是不透明的,因此不会创建行框由输入元素。所以第一个 div 和 class "b" 的最后一行是包含标签的那一行,并且与 '/' 字符的行水平对齐。
Chrome 持不同观点。 Chrome 将输入元素视为具有对 CSS 可见的内部结构,因此元素的内部形成一个线框,其基线然后成为第一个 div 与 class"b",就是水平对齐'/'字符的
当你添加 `overflow:hidden' 时,它会影响行内块的基线,这样它们的基线就不再是它们最后包含的行框的基线,而是成为元素的底部边距。
尚不清楚哪种行为是正确的。这取决于历史和替换元素的有点掺假的概念。在浏览器的早期,一些元素的渲染被委托给外部系统,要么是底层操作系统,要么是插件。尤其是输入元素,渲染是通过 O/S 调用完成的。 O/S 没有 CSS 的概念,因此必须定义规则以允许有效的黑框与页面的其余部分进行交互。这些元素被 class 化为 "replaced" 元素。
注意这是定义的方式。没有被替换元素的官方列表,如果浏览器选择将其呈现委托给 CSS 世界之外的系统,那么元素就是被替换元素,所以理论上你可以有两个浏览器,一个委托渲染一个元素和一个本地渲染它,并且根据 CSS 规则获得完全不同的交互。
随着浏览器的进步,他们停止委托渲染输入元素并自己渲染它,在此过程中使渲染 CSS 感知。这会导致一个问题,因为假设输入元素将使用替换元素的规则呈现的现有网页可能变得不可用。如果浏览器允许这种情况发生,它将失去市场份额。因此,在大多数情况下,为了避免这种情况,浏览器实现这些元素的布局以与页面交互,就好像它们是被替换的元素一样,即使实际上它们不是。
他们在这方面能走多远还不清楚。 HTML5 规范不将表单控件识别为替换元素,并建议将它们呈现为内联块,这将使 Chrome 的行为正确,但是有很多方法可以使所有包括 Chrome 在内的浏览器根本不会那样做。从与旧 Web 内容向后兼容的角度来看,Firefox 的行为更可靠。
除非表单控件的布局比目前的情况更严格,否则无法断言哪种行为是正确的。
¹对我来说,IE11 的行为类似于 Firefox。 Opera 28(像 Chrome 这样的闪烁引擎)表现得像 Chrome。 Opera 12(presto 引擎)的行为类似于 Firefox。
谁能解释一下 FF 中的这种行为?
Fiddle: http://jsfiddle.net/4mrt8wq3/
<style>
.b { display: inline-block; }
#a { display: block; }
</style>
<div class="b">
<label>xxxxxxxxxx</label>
<input type="text" id="a"/>
</div>
<div class="b">
<label>xxxxxxxxxx</label>
<div> / </div>
</div>
只有在 firefox 中,第一个 div 比第二个低一行。它在 Chrome 和 IE(至少 IE11)中正常工作。就好像内联块中的块元素出于某种原因在第二个元素下方换行。
在第一个 div 上使用 overflow: hidden 解决了这个问题,但是第二个 div 的位置有点奇怪,上面有大约 4 或 5 个像素的边距。将 overflow-hidden 放在两者上会使其正确呈现。
我不是在寻找问题的解决方案,因为我已经找到了一个,但我无法解释这种行为... 谁能解释为什么要这样做?
您的问题是根据规范设置 overflow:hidden 更改了内联块的基线位置。 Firefox 实现了规范所说的内容。 Chrome 没有。
解决方案:
<style>
.b { display: inline-block;
vertical-align: top; /*add this line */
}
#a { display: block; }
</style>
是的,有趣的问题。首先我们要明白,inline-block元素默认的垂直对齐方式是baseline,每一个这样的元素的baseline就是其中最后一个line box的baseline
在第二个 div 和 class "b" 中,内部 div 本身包含一个行框来容纳 '/' 字符。然后为第二个 div 提供基线 class "b".
该基线必须与第一个 div 和 class "b" 的基线对齐。问题就变成了:那个div?
最后一个line box的基线在哪里通过使输入元素本身成为 display:block
,Firefox¹ 认为输入元素是 "replaced",它的内容对 CSS 是不透明的,因此不会创建行框由输入元素。所以第一个 div 和 class "b" 的最后一行是包含标签的那一行,并且与 '/' 字符的行水平对齐。
Chrome 持不同观点。 Chrome 将输入元素视为具有对 CSS 可见的内部结构,因此元素的内部形成一个线框,其基线然后成为第一个 div 与 class"b",就是水平对齐'/'字符的
当你添加 `overflow:hidden' 时,它会影响行内块的基线,这样它们的基线就不再是它们最后包含的行框的基线,而是成为元素的底部边距。
尚不清楚哪种行为是正确的。这取决于历史和替换元素的有点掺假的概念。在浏览器的早期,一些元素的渲染被委托给外部系统,要么是底层操作系统,要么是插件。尤其是输入元素,渲染是通过 O/S 调用完成的。 O/S 没有 CSS 的概念,因此必须定义规则以允许有效的黑框与页面的其余部分进行交互。这些元素被 class 化为 "replaced" 元素。
注意这是定义的方式。没有被替换元素的官方列表,如果浏览器选择将其呈现委托给 CSS 世界之外的系统,那么元素就是被替换元素,所以理论上你可以有两个浏览器,一个委托渲染一个元素和一个本地渲染它,并且根据 CSS 规则获得完全不同的交互。
随着浏览器的进步,他们停止委托渲染输入元素并自己渲染它,在此过程中使渲染 CSS 感知。这会导致一个问题,因为假设输入元素将使用替换元素的规则呈现的现有网页可能变得不可用。如果浏览器允许这种情况发生,它将失去市场份额。因此,在大多数情况下,为了避免这种情况,浏览器实现这些元素的布局以与页面交互,就好像它们是被替换的元素一样,即使实际上它们不是。
他们在这方面能走多远还不清楚。 HTML5 规范不将表单控件识别为替换元素,并建议将它们呈现为内联块,这将使 Chrome 的行为正确,但是有很多方法可以使所有包括 Chrome 在内的浏览器根本不会那样做。从与旧 Web 内容向后兼容的角度来看,Firefox 的行为更可靠。
除非表单控件的布局比目前的情况更严格,否则无法断言哪种行为是正确的。
¹对我来说,IE11 的行为类似于 Firefox。 Opera 28(像 Chrome 这样的闪烁引擎)表现得像 Chrome。 Opera 12(presto 引擎)的行为类似于 Firefox。