【问题标题】:<input> has mysterious bottom padding<input> 有神秘的底部填充
【发布时间】:2012-02-16 08:50:41
【问题描述】:

我正在尝试对某些表单元素进行一些非常精确的样式设置,而这个问题让我很伤心。

如果我尝试从&lt;input&gt;(使用display: block)中删除paddingmarginborderoutline,以便字段的大小完全由文本决定,输入字段最终比任何其他以完全相同的方式样式化的块级元素具有几个像素的额外填充。这是一个例子: http://jsfiddle.net/nottrobin/b9zfa/

<input class="normalised testSubject" value="hello" />
<div class="normalised testSubject">hello</div>

渲染:

在该示例中,&lt;div&gt; 的计算高度为 16px,而&lt;input&gt; 的计算高度为 19px

我在 Chrome 16、Firefox 9 和 Opera 11 中得到了相同的行为,因此它显然独立于渲染引擎。

我可以通过手动添加高度来解决此问题,但我不想这样做,因为我希望设计保持responsive

谁能帮我理解这里发生了什么,以及我如何能够可靠地确保&lt;input&gt; 与它后面的任何块级元素的高度相同?

【问题讨论】:

标签: html css forms webkit


【解决方案1】:

您确定他们使用的是完全相同的字体(包括大小)吗?

尝试将box-sizing: border-box 添加到input

我自己从来没有遇到过这个问题,但我只是在 IE9 的某个地方用它作为测试......

【讨论】:

  • 表单元素默认为border-box,他正在重置它们以与其他元素上的content-box保持一致。
【解决方案2】:

删除line-height 似乎可以解决问题。

See fiddle。仅在 FF 中测试。

【讨论】:

  • 没有line-height:medium,它正在工作,因为您通过传递无效值有效地删除了行高。为什么删除行高有效,这就是我想要弄清楚的。
  • 不要删除行高,而是确保 line-height: normal 有效。
【解决方案3】:

&lt;input&gt; 的最小line-height 取决于字体大小。将这两个元素设置为更大的 line-height 值是可行的,完全删除 line-height 也是如此。但这仍然不允许您的高度小于最小值。解决方法是使用first-line 伪元素并将其设置为display: inline-block;

演示:http://jsfiddle.net/ThinkingStiff/B7cmQ/

CSS:

.normalised:first-line {
    display: inline-block;    
}

但这并不能解释为什么&lt;input&gt; 的行为与&lt;div&gt; 不同。甚至-webkit-appearance: none; 也没有修复它。似乎输入上有一些不可见的巫术,将其内容视为inlineinline 元素的最小 line-height 基于字体大小,这是我们在这里看到的行为。这就是first-line 修复它的原因。它似乎在为&lt;input&gt; 的“子”元素设置样式。

这是一个演示,显示了 inline 元素上的最小 line-height&lt;div&gt; 元素尊重 line-height: 7px;&lt;span&gt;,即使它的计算值显示为7px;,在视觉上并没有兑现它。

演示:http://jsfiddle.net/ThinkingStiff/zhReb/

输出:

HTML:

<div id="container"> 
    <div id="div-large">div <br />large</div> 
</div> 
<div id="container"> 
    <div id="div-medium">div <br />med</div> 
</div> 
<div id="container"> 
    <div id="div-small">div <br />small</div> 
</div> 
<div id="container"> 
    <span id="span-large">span <br />large</span> 
</div> 
<div id="container"> 
    <span id="span-medium">span <br />med</span> 
</div> 
<div id="container"> 
    <span id="span-small">span <br />small</span> 
</div> 

CSS:

#container { 
    background-color: lightblue;   
    display: inline-block; 
    height: 200px; 
    vertical-align: top; 
}

#div-large { 
    line-height: 50px; 
} 

#div-medium { 
    line-height: 20px; 
} 

#div-small { 
    line-height: 7px; 
}

#span-large { 
    line-height: 50px; 
    vertical-align: top; 
} 

#span-medium {
    line-height: 20px; 
    vertical-align: top; 
} 

#span-small {
    line-height: 7px;
    vertical-align: top;
}

【讨论】:

  • 精彩的解释,谢谢。我还没有完全测试你的 :first-child 跨浏览器解决方案,但它看起来很有希望。我想知道这种行为是否可能只存在于支持 HTML5“占位符”的浏览器中?我想渲染引擎会在表单字段中创建一个元素,以帮助以某种方式操纵内容。无论如何,这就是答案。非常感谢。
  • @RobinWinslow IE7+ 和所有其他浏览器:quirksmode.org/css/contents.html#t17
  • 不是我的意思。我的意思是制作 :first-line inner-block 的修复程序可以跨浏览器工作。但它可能会。
  • 此修复在 Firefox 中不适用于将 line-height 设置为小于 normal(大约 1-1.2em)。看到这个:stackoverflow.com/questions/8981420/…
【解决方案4】:

我知道这个问题迟到了几个月,但我在 Google 搜索中遇到了它,并想添加一件事来帮助澄清与 Firefox 中的 &lt;input&gt; 元素有关的其他一些答案。

Firefox 中的默认表单样式包含一些尴尬的 CSS:

input {
   ...
   line-height: normal !important;
   ...
}

这使得在 Firefox 中覆盖任何表单输入的line-height 属性实际上是不可能的。这个问题已经存在多年了,虽然对于 FF 开发者来说,从规则中删除 !important 似乎是一件轻而易举的事,但我认为这样做存在一些幕后的实现问题。此外,显然有些网站(包括 YouTube) 依赖此规则的行为。

有关详细信息和大量讨论,请参阅Mozilla bug #349259456bereastreet.com 上还有一篇很好的博文,以及 Eric Meyer 的另一篇(较旧的)meyerweb.com

【讨论】: