Home > database >  What is this extra vertical space after range <input> elements?
What is this extra vertical space after range <input> elements?

Time:01-03

All my range <input> elements seem to have extra vertical space after them, preventing them from being packed tightly together vertically, and also preventing placing related elements (like text labels) closely after them vertically.

How do I get rid of this unwanted extra vertical space?

Here's an html css snippet that demonstrates the problem; it attempts to remove all space between all elements (except for some 1px colored borders for debugging):

<!DOCTYPE html>
<html>
<head>
  <style>

    /*
      pack everything as tightly as possible,
      except some 1px colored borders for debugging
    */
    * {
      margin:0;
      border:10px solid black; /* make anything not covered by rules below look terrible */
      padding:0;
    }
    html { border:1px solid red; }
    body { border:1px solid orange; }
    hr { border:1px solid green; }
    table {
      border:1px solid cyan;
      border-spacing:0;
    }
    td { border: 1px solid blue; }
    div { border:1px solid magenta; }
    input {border:1px solid red; } /* the 1px matters but the red doesn't show?? */

  </style>
</head>
<body>

Three range &lt;input&gt;s separated by &lt;br&gt; (unwanted extra vertical space):
<br>
<input type="range">
<br>
<input type="range">
<br>
<input type="range">

<hr>

Table with three range &lt;input&gt;s in same cell, separated by &lt;br&gt; (unwanted extra vertical space):
<table>
  <tr>
    <td>
      <input type="range">
      <br>
      <input type="range">
      <br>
      <input type="range">
</table>

<hr>

Table with three range &lt;input&gt;s in different cells (unwanted extra vertical space):
<table>
  <tr><td><input type="range">
  <tr><td><input type="range">
  <tr><td><input type="range">
</table>

<hr>

Three &lt;div&gt;s, each with a range &lt;input&gt; inside (unwanted extra vertical space):
<div><input type="range"></div>
<div><input type="range"></div>
<div><input type="range"></div>

<hr>

Three range &lt;input&gt;s separated by &lt;div&gt;s with negative margins (hack to show desired spacing):
<br>
<input type="range">
<div style="margin-top:-5px; margin-bottom:-1px;"></div>
<input type="range">
<div style="margin-top:-5px; margin-bottom:-1px;"></div>
<input type="range">

<hr>

&lt;input&gt; elements of type other than range, to show that the border color (red) works as expected on most of them:
<br>
button:<input type="button" value="button value"></input>
checkbox:<input type="checkbox"></input>
color:<input type="color"></input>
date:<input type="date"></input>
datetime-local:<input type="datetime-local"></input>
email:<input type="email" value="email value"></input>
file:<input type="file"></input>
hidden:<input type="hidden"></input>
image:<input type="image"></input>
month:<input type="month"></input>
number:<input type="number" value="123"></input>
password:<input type="password" value="abc"></input>
radio:<input type="radio"></input>
range:<input type="range"></input>
reset:<input type="reset"></input>
search:<input type="search" value="search value"></input>
submit:<input type="submit"></input>
tel:<input type="tel" value="tel value"></input>
text:<input type="text" value="text value"></input>
time:<input type="time"></input>
url:<input type="url" value="url value"></input>
week:<input type="week"></input>

</body>
</html>

Here's the output of the above snippet in chrome 108.0.5359 on linux; notice that the range <input>s seem to be a bit more widely spaced vertically than necessary:

screenshot of the above code

Inspecting the elements, I observe:

  • This range <input> element is 18 pixels high (16 if I turn off the 1px debugging borders); this looks reasonable:

    inspecting the range input element: it's 18 pixels high

  • The <td> that contains the range <input> is 24 pixels high (22 if I turn off the 1px debugging borders), because it contains 6 pixels of mystery space at the bottom:

    inspecting the td element: it's 24 pixels high

More generally, there seems to be 6 pixels of mystery extra vertical space after each range <input> element. Where is this mystery extra vertical space coming from? Is there a way to get rid of it, without hard-coding the assumption that it's there and how big it is?

Also, less importantly, I'm curious why the border color (red) doesn't seem to have any effect on range <input> elements in the above snippet (the border-width is honored, but the border-color is not).

CodePudding user response:

This is being caused by the default line-height (which is 1.2 times the current font size in chrome).

So the line break is actually breaking a new line at that size.

add a line-height of 0 to the td or div or any container it sits in

JSFiddle

CodePudding user response:

This is usually browser specific, but at least in chrome browser, the cause of the extra white space is actually because input has display: inline-block and if you change it to display: block, it won't have extra space.

<!DOCTYPE html>
<html>

<head>
  <style>
    /*
      pack everything as tightly as possible,
      except some 1px colored borders for debugging
    */
    
    * {
      margin: 0;
      border: 10px solid black;
      /* make anything not covered by rules below look terrible */
      padding: 0;
    }
    
    html {
      border: 1px solid red;
    }
    
    body {
      border: 1px solid orange;
    }
    
    hr {
      border: 1px solid green;
    }
    
    table {
      border: 1px solid cyan;
      border-spacing: 0;
    }
    
    td {
      border: 1px solid blue;
    }
    
    div {
      border: 1px solid magenta;
    }
    
    input {
      border: 1px solid red;
      display: block
    }
    /* the 1px matters but the red doesn't show?? */
  </style>
</head>

<body>

  Three range &lt;input&gt;s separated by &lt;br&gt; (unwanted extra vertical space):
  <br>
  <input type="range">
  <br>
  <input type="range">
  <br>
  <input type="range">

  <hr> Table with three range &lt;input&gt;s in same cell, separated by &lt;br&gt; (unwanted extra vertical space):
  <table>
    <tr>
      <td>
        <input type="range">
        <br>
        <input type="range">
        <br>
        <input type="range">
  </table>

  <hr> Table with three range &lt;input&gt;s in different cells (unwanted extra vertical space):
  <table>
    <tr>
      <td><input type="range">
        <tr>
          <td><input type="range">
            <tr>
              <td><input type="range">
  </table>

  <hr> Three &lt;div&gt;s, each with a range &lt;input&gt; inside (unwanted extra vertical space):
  <div><input type="range"></div>
  <div><input type="range"></div>
  <div><input type="range"></div>

  <hr> Three range &lt;input&gt;s separated by &lt;div&gt;s with negative margins (hack to show desired spacing):
  <br>
  <input type="range">
  <div style="margin-top:-5px; margin-bottom:-1px;"></div>
  <input type="range">
  <div style="margin-top:-5px; margin-bottom:-1px;"></div>
  <input type="range">

  <hr> &lt;input&gt; elements of type other than range, to show that the border color (red) works as expected on most of them:
  <br> button:
  <input type="button" value="button value"></input>
  checkbox:<input type="checkbox"></input>
  color:<input type="color"></input>
  date:<input type="date"></input>
  datetime-local:<input type="datetime-local"></input>
  email:<input type="email" value="email value"></input>
  file:<input type="file"></input>
  hidden:<input type="hidden"></input>
  image:<input type="image"></input>
  month:<input type="month"></input>
  number:<input type="number" value="123"></input>
  password:<input type="password" value="abc"></input>
  radio:<input type="radio"></input>
  range:<input type="range"></input>
  reset:<input type="reset"></input>
  search:<input type="search" value="search value"></input>
  submit:<input type="submit"></input>
  tel:<input type="tel" value="tel value"></input>
  text:<input type="text" value="text value"></input>
  time:<input type="time"></input>
  url:<input type="url" value="url value"></input>
  week:<input type="week"></input>

</body>

</html>

As for why the border is not applied to the range slider, it's caused by the appearance: auto, if you change that to appearance: none, it will have the borders shown:

<!DOCTYPE html>
<html>

<head>
  <style>
    /*
      pack everything as tightly as possible,
      except some 1px colored borders for debugging
    */
    
    * {
      margin: 0;
      border: 10px solid black;
      /* make anything not covered by rules below look terrible */
      padding: 0;
    }
    
    html {
      border: 1px solid red;
    }
    
    body {
      border: 1px solid orange;
    }
    
    hr {
      border: 1px solid green;
    }
    
    table {
      border: 1px solid cyan;
      border-spacing: 0;
    }
    
    td {
      border: 1px solid blue;
    }
    
    div {
      border: 1px solid magenta;
    }
    
    input {
      border: 1px solid red;
      appearance: none;
      display: block;
    }
    /* the 1px matters but the red doesn't show?? */
  </style>
</head>

<body>

  Three range &lt;input&gt;s separated by &lt;br&gt; (unwanted extra vertical space):
  <br>
  <input type="range">
  <br>
  <input type="range">
  <br>
  <input type="range">

  <hr> Table with three range &lt;input&gt;s in same cell, separated by &lt;br&gt; (unwanted extra vertical space):
  <table>
    <tr>
      <td>
        <input type="range">
        <br>
        <input type="range">
        <br>
        <input type="range">
  </table>

  <hr> Table with three range &lt;input&gt;s in different cells (unwanted extra vertical space):
  <table>
    <tr>
      <td><input type="range">
        <tr>
          <td><input type="range">
            <tr>
              <td><input type="range">
  </table>

  <hr> Three &lt;div&gt;s, each with a range &lt;input&gt; inside (unwanted extra vertical space):
  <div><input type="range"></div>
  <div><input type="range"></div>
  <div><input type="range"></div>

  <hr> Three range &lt;input&gt;s separated by &lt;div&gt;s with negative margins (hack to show desired spacing):
  <br>
  <input type="range">
  <div style="margin-top:-5px; margin-bottom:-1px;"></div>
  <input type="range">
  <div style="margin-top:-5px; margin-bottom:-1px;"></div>
  <input type="range">

  <hr> &lt;input&gt; elements of type other than range, to show that the border color (red) works as expected on most of them:
  <br> button:
  <input type="button" value="button value"></input>
  checkbox:<input type="checkbox"></input>
  color:<input type="color"></input>
  date:<input type="date"></input>
  datetime-local:<input type="datetime-local"></input>
  email:<input type="email" value="email value"></input>
  file:<input type="file"></input>
  hidden:<input type="hidden"></input>
  image:<input type="image"></input>
  month:<input type="month"></input>
  number:<input type="number" value="123"></input>
  password:<input type="password" value="abc"></input>
  radio:<input type="radio"></input>
  range:<input type="range"></input>
  reset:<input type="reset"></input>
  search:<input type="search" value="search value"></input>
  submit:<input type="submit"></input>
  tel:<input type="tel" value="tel value"></input>
  text:<input type="text" value="text value"></input>
  time:<input type="time"></input>
  url:<input type="url" value="url value"></input>
  week:<input type="week"></input>

</body>

</html>

Note that this is browser specific and different browser could have a different behaviors.

  •  Tags:  
  • css
  • Related