css - 内联 block 内的 block 元素在 Firefox 中表现异常

标签 css 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)中正常工作。就好像内联 block 中的 block 元素出于某种原因在第二个元素下方换行。

在第一个 div 上使用 overflow: hidden 解决了这个问题,但是第二个 div 的位置有点奇怪,上面有大约 4 或 5 个像素的边距。将 overflow-hidden 放在两者上会使其正确呈现。

我不是在寻找问题的解决方案,因为我已经找到了一个,但我无法解释这种行为......任何人都可以解释为什么它在做这个?

最佳答案

是的,有趣的问题。首先我们需要了解内联 block 元素的默认垂直对齐方式是基线,每个此类元素的基线是其中最后一个行框的基线。

在类为“b”的第二个 div 中,内部 div 本身包含一个行框来容纳“/”字符。然后为第二个 div 类“b”提供基线。

该基线必须与类为“b”的第一个 div 的基线水平对齐。问题就变成了:那个 div 中最后一个 line box 的基线在哪里?

通过使输入元素本身成为 display:block,Firefox¹ 认为输入元素被“替换”,它的内容对 CSS 是不透明的,因此输入不会创建行框元素。因此,类为“b”的第一个 div 的最后一行是包含标签的行,并且与“/”字符所在的行水平对齐。

Chrome 有不同的看法。 Chrome 将 input 元素视为具有 CSS 可见的内部结构,因此该元素的内部形成一个线盒,其基线随后成为第一个类为“b”的 div 的基线,并且它与'/' 字符。

当你添加 `overflow:hidden' 时,它会影响行内 block 的基线,这样它们的基线就不再是它们最后包含的行框的基线,而是成为元素的底部边距。


尚不清楚哪种行为是正确的。这取决于历史和替换元素的有点掺假的概念。在浏览器的早期,一些元素的渲染被委托(delegate)给外部系统,要么是底层操作系统,要么是插件。尤其是输入元素,渲染是通过 O/S 调用完成的。 O/S 没有 CSS 的概念,因此必须定义规则以允许有效的黑框与页面的其余部分进行交互。这些元素被归类为“替换”元素。

注意这是定义的方式。没有被替换元素的官方列表,如果浏览器选择将其呈现委托(delegate)给 CSS 世界之外的系统,则元素是被替换元素,因此理论上你可以有两个浏览器,一个委托(delegate)元素的呈现和一个本地渲染它,并从 CSS 规则获得完全不同的交互。

随着浏览器的进步,他们不再委托(delegate)他们渲染输入元素,而是自己渲染它,在这个过程中让渲染 CSS 感知。这会导致一个问题,因为假设输入元素将使用替换元素的规则呈现的现有网页可能变得不可用。如果浏览器允许这种情况发生,它将失去市场份额。因此,在大多数情况下,为了避免这种情况,浏览器实现这些元素的布局以与页面交互,就好像它们是被替换的元素一样,即使实际上它们不是。

他们在这方面能走多远还没有明确说明。 HTML5 规范不将表单控件识别为替换元素,并建议将它们呈现为内联 block ,这将使 Chrome 的行为正确,但在很多方面,包括 Chrome 在内的所有浏览器都不会这样做.从与旧 Web 内容向后兼容的 Angular 来看,Firefox 的行为更可靠。

除非表单控件的布局比当前情况更严格地指定,否则无法断定哪种行为是正确的。


¹对我来说,IE11 的行为类似于 Firefox。 Opera 28(像 Chrome 一样的闪烁引擎)表现得像 Chrome。 Opera 12(presto 引擎)的行为类似于 Firefox。

关于css - 内联 block 内的 block 元素在 Firefox 中表现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29858497/

相关文章:

asp.net - 如何可靠地跟踪 CSS 的使用情况?

javascript - django CSS : general query on CDNs and crispy forms

visual-studio-2010 - 如何使用 visual studio 2010 在调试器下运行 firefox?

javascript - 如何使 EventSource 在 FireFox 的 SharedWorker 中可用?

python - 如何在 Firefox geckodriver 中使用代理?

html - 表单不会在 CSS 中居中

html - 动画返回 css 动画

html - 为什么 medium-offset-2 值不适用

javascript - 使用 FireFox 中的 Vaadin 按钮复制到剪贴板

javascript - 如何将浏览器窗口识别为 Firefox-Extension 中的弹出窗口?