I\'m trying to style a text input with a value, text input with a placeholder, and a span, identically in Chrome. Specifically, I would like to control the line-height indep
OP
DEMO
FORK
Explination: <input>
is a replaced element so it's content does not
get rendered by the user agent.
For details refer to: HTML5: Non-replaced vs. replaced element?
Solution:
See FORK or Snippet
html {
height: 100vh;
width: 100vw;
font: 400 10px'Arial';
}
body {
height: 100%;
width: 100%;
background-color: grey;
color: #111;
}
#form {
display: inline-table;
}
.box {
display: table-row;
}
span,
input {
font: inherit;
font-size: 40px;
/* */
height: 50px;
/* */
line-height: 50px;
/* */
width: 100px;
display: table-cell;
outline: 2px solid red;
border: 5px solid transparent;
/* */
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form id="form">
<div class="box">
<input id="in1" type="text" placeholder="Text" value="Text">
<input id="in2" type="text" placeholder="Text" value="">
<span>Text</span>
</div>
</form>
</body>
</html>
Set the height
, and line-height
of <input>
s equally. (e.g. 50px)
Set the font-size
to a size less than height
and line-height
. (e.g. 40px)
Set either top
and bottom
of padding
or border
to the difference of the previous values divided by 2. (e.g. ((50px - 40px) / 2) = 5px)
Updated base on comments below
In order to use the same line-height
for each of the elements I updated the CSS to this:
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
div {
line-height: 50px;
font-family: Arial;
}
input, span {
border: 2px solid red;
display: inline-block;
font: 50px Arial;
height: 60px;
line-height: 60px;
padding: 0;
vertical-align: middle;
width: 100px;
}
input {
padding-top: 3px;
}
Basically you if use the same contain height
and line-height
the text will show correctly next to each other even if you change the font sizes. The font size must be at least 10px or so bigger than the height and line-height otherwise it will become skewed again.
You can see my updated JS.Fiddle here. Hope that helps.
This misalignment is being caused by the caret and as such I don't think you will find a way to align the text if the font-size
and line-height
are the same.
The caret has a height
greater than the text which is causing the alignment to be skewed.
There are a few things which support this:
1. You can see the size of the caret
input
and hold the left mouse button. Drag up and down and you will see that the text will moveheight: 50px;
from input, span
. The size of the input
will now increase to the height
of the caretdiv {
line-height: 50px;
font-family: Arial;
}
input, span {
font-size: 45px;
line-height: 50px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
}
<div>
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
</div>
2. The placeholder text is correctly aligned
input
the alignment is thrown offThe result of the caret having a greater height
is that the line-height
is being artificially increased causing the text to be out of line.
This can be proven by:
line-height
to 58px
. The alignment of the placeholder text and span
will be the same as the input
div {
line-height: 50px;
font-family: Arial;
}
input, span {
font-size: 50px;
line-height: 58px;
height: 50px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
}
<div>
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
</div>
font-size
to 45px
. The caret will now fit in the 50px
height
div {
line-height: 50px;
font-family: Arial;
}
input, span {
font-size: 45px;
line-height: 50px;
height: 50px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
}
<div>
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
</div>
As there is no way to style the caret itself (to make it smaller) the most efficient way of ensuring the text is aligned would be to use a font-size
which is smaller than the line-height
. This will in turn make the caret smaller and stop it from artificially increasing the line-height
of the input
.
div {
line-height: 50px;
font-family: Arial;
}
input, span {
font-size: 45px;
line-height: 50px;
height: 50px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
}
<div>
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
</div>
Alternatively you could remove height
and just specify a line-height
equal to the height
of the caret:
div {
line-height: 50px;
font-family: Arial;
}
input, span {
font-size: 50px;
line-height: 58px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
}
<div>
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
</div>
I've done a bit of experimenting with line-heights within input boxes and think I've come to some sort of conclusion.
It appears that if the size of the font in an input box equals or exceeds the line height, then the box changes size and its content (but not placeholder) changes also to fit. This is obvious if you remove the heights from your example.
input, span {
padding: 0;
margin: 0;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
vertical-align: middle;
}
input, input::-webkit-input-placeholder, span {
line-height: 50px;
font-size: 50px;
}
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
If you set the font-size
to smaller than the line height, you no longer see the weird line-height effect and all the text sits on the same line:
input, span {
padding: 0;
margin: 0;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
vertical-align: middle;
}
input, input::-webkit-input-placeholder, span {
line-height: 50px;
font-size: 45px;
}
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>
Here's a side-by-side example: http://codepen.io/Jivings/pen/OyOKOV
I hope this helps, and at least brings you closer to a solution in your own CSS!
Because diacritics are not part of the traditional definition of font size, you can't ever have line height = font size. Even ASCII includes some diacritics (for example U0060). Diacritics can be applied to capitalized letters too, you don't even need obscure unicode extensions, latin1 is sufficient (U00C0 for example).
When a font is correctly designed and includes the box drawing block this can be easily checked – box drawing lines are supposed to be jointive so U2502 for example will give you the actual exact maximum height used by the font. Its height will be more than A or one of the other latin caps usually used to define font size. (unfortunately because horizontal lines are also supposed to be jointive the box drawing block can only be found in monospace fonts).
After allocating font height the text stack still has to reserve some place where to put diacritics (there are metadata in font formats that define how much a particular font will consume in addition to font size for diacritics). Usually this place overlaps with line spacing. When there is a single line, it shows up as line height > font size
Computing the exact minimal line height for a font size requires deep knowledge of the font used (via a specific lib, something like opentype.js) and the characteristics of the text engine used to render each element. Depending on the advancement of this text engine it will use more (or less) of the tricks permitted by the opentype spec to minimize space wastage in complex international situations.
For example unless a text stack implements handling of the opentype base table opentype spec the actual added spacing can grow to huge values (more than the 15/20% typical of western latin and given in other answers) as soon as one uses a font with support for Vietnamese, or other scripts that like to stack many diacritics on top of one other (even if your browser manages to render this page with a generic font it will probably compress diacritics vertically compared to when a vietnamese font is installed)
Likewise the text stack knows whether the text you put on a page includes or not complex diacritics. But for an input element it has no such information, that depends on what the user will type. So it needs to be conservative and reserve the worst-case line height for the scripts supported by the font you chose.
Broken web site designs where vertical input height has been under-allocated are very common, because web site/js lib/browser authors live in a 96dpi no-diacritics latin world, and think minimizing vertical height is beautiful. That breaks as soon as the site is viewed in another language, with slightly more complex unicode glyphs, slightly different fonts, or slightly different text zoom levels (due to hidpi or just user near-sightness). Normal text is usually fine since the designer didn't try to force it inside an undersized fixed-pixel box.
It is also common for input field sizing to be broken, when it uses monospace fonts for one reason or another, and the web designer assumed some ratio between sans serif and monospace and tried to "fix" it (usually by enlarging monospace since some browsers ship with a small default monospace for obscure legacy reasons, even though it is not a general rule).
Try like this
As per the link:Firefox line-height issue with input fields
line-height on input won't change unless you change the font-size
so reduce the font-size:50px to 45px it will look fine.
Code Below
div {
line-height: 50px;
font-family: Arial;
}
span,input[type="text"],input[placeholder]{
height: 50px;
width: 100px;
padding: 0;
min-height: 0;
display: inline-block;
font-family: inherit;
border: 2px solid red;
overflow: hidden;
vertical-align: top;
font-size:45px;
}
::-webkit-input-placeholder {
color:#000000;
}