Robin Winslow
Robin Winslow

Reputation: 11502

<input> has mysterious bottom padding

I am trying to do some quite precise styling on some form elements, and this issue is causing me a lot of grief.

If I try to remove padding, margin, border and outline from an <input> (with display: block) so that the size of the field is purely determined by the text, the input field ends up having a few pixels extra padding than any other block level element styled exactly the same way. Here's an example: http://jsfiddle.net/nottrobin/b9zfa/

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

Rendering:

Rendering

In that example, the <div> gets a computed height of 16px while the <input> gets a computed height of 19px.

I get the same behaviour in Chrome 16, Firefox 9 and Opera 11 so it's clearly rendering engine independent.

I can fix the issue by manually adding a height, but I don't want to do that because I want the design to remain responsive.

Can anyone help me understand what's going on here, and how I can reliably make sure that the <input> will be the same height as any block level element that follows it?

Upvotes: 11

Views: 7021

Answers (4)

eaj
eaj

Reputation: 2606

I know I'm months late to this question, but I ran across it in a Google search and wanted to add one thing that might help clarify some of the other answers with regard to the <input> elements in Firefox.

The default form styling in Firefox includes some awkward CSS:

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

This makes it effectively impossible to override the line-height property of any form input in Firefox. The problem has existed for years, and while it seems like a no-brainer for the FF devs to remove the !important from the rule, I gather there are some under-the-hood implementation problems with doing so. Also, apparently there are some websites (including YouTube) that rely on the behavior of this rule.

For details and lots of discussion see Mozilla bug #349259. There's also a good blog post on this at 456bereastreet.com, and another (older) by Eric Meyer at meyerweb.com.

Upvotes: 0

ThinkingStiff
ThinkingStiff

Reputation: 65341

The <input> has a minimum line-height based on font size. Setting both elements to a larger line-height value works, as does removing line-height altogether. But that still doesn't allow you to have smaller heights than the minimum. The fix for that is using the first-line pseudo-element and setting it to display: inline-block;.

Demo: http://jsfiddle.net/ThinkingStiff/B7cmQ/

enter image description here

CSS:

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

But this doesn't explain why the <input> is acting differently than the <div>. Even -webkit-appearance: none; didn't fix it. It would seem there is some invisible voodoo on inputs that treats its contents as inline. inline elements have minimun line-height based on font size, which is the behavior we're seeing here. That's why first-line fixes it. It seems to be styling the "child" element of the <input>.

Here's a demo that shows the minimum line-height on inline elements. The <div> element honors line-height: 7px;. The <span>, even though its computed value is showing 7px;, is not honoring it visually.

Demo: http://jsfiddle.net/ThinkingStiff/zhReb/

Output:

enter image description here

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

Upvotes: 16

mreq
mreq

Reputation: 6542

Removing the line-height seems to solve the problem.

See fiddle. Tested only in FF tho.

Upvotes: 2

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324620

Are you sure they're using the exact same font (including size)?

Try adding box-sizing: border-box to the input.

I've never had this issue myself, but I've only used it as a test somewhere in IE9...

Upvotes: 0

Related Questions