Why does <input type='range'/> have the wrong size in terms of content flow?

Viewed 205

<div id='div-1' style='background:blue; height:100%'>
  <input id='input-1' type='range' style='height:100%; margin:0; padding: 0; border: 0'/>
</div>

<div id='div-2' style='background:red; height:fit-content; fit-content'>
  <input id='input-2' type='range' style='margin:0; padding: 0; border: 0'/>
</div>

In both cases, the div is taller than the input by 2.5px (Firefox) to 3px (Chrome), no matter what I do (aside from explicitly setting the size of both). Why does input seem to have some secret unchangeable padding that I cannot control (across all browsers, but not the same amount across all browsers)?

I'm trying to ensure that the div is the exact same size as the input, yet no matter what I do I cannot get them to be sized the same without doing some sketchy hard-coding of values (in a very browser-dependent fashion).

I have tried an assortment of "reset" tricks to try to get the input element to either fit its parent or for the parent to fit the input, but there always is some extra secret padding/margin below the input.

2 Answers

because input is inline-block. The default is baseline alignment. The larger the text, the more space below it. flex and grid Both have changed the document flow alignment, so there is no space below.

/* div {
  font-size: 0;
}*/

#input-1 {
  vertical-align: bottom;
}
<div id='div-1' style='background:blue; height:100%'>
  <input id='input-1' type='range' style='height:100%; margin:0; padding: 0; border: 0'/>javascript
</div>

<div id='div-2' style='background:red; height:fit-content;'>
  <input id='input-2' type='range' style='margin:0; padding: 0; border: 0'/>javascript
</div>

I looked it up, and the border can be changed. The following code only works in firefox.

input[type='range']::-moz-range-track {
    height: 10px;
    border-radius: 10px;
    box-shadow: 0 1px 1px #def3f8, inset 0 0.125em 0.125em #0d1112;
}

input[type='range']::-moz-range-thumb {
    -webkit-appearance: none;
    height: 10px;
    width: 10px;
    margin-top: -5px;
    background: #ffffff;
    border-radius: 50%;
    border: solid 0.125em rgba(205, 224, 230, 0.5);
    box-shadow: 0 0.125em 0.125em #3b4547;
}

input[type='range']::-moz-range-progress {
    background: linear-gradient(to right, green, white 100%, white);
    height: 10px;
    border-radius: 10px;
    border-width: 0; /* Set border-width */
}
input[type='range'] {
    background-color: transparent;
}
<input id='input-2' type='range'/>

Set display:flex or display:grid.

After more fiddling, I found out that if I set the wrapper div to display:flex or display:grid the problem goes away. I would still like to better understand why this problem is occurring, or if there are any other workarounds but if no one else provides an answer within a couple days I'll mark this as the answer.

Related