Search code examples
htmlcsswidthhtml-input

HTML input field width varies with content using only CSS (no JS)


I can set the width of an <input type=number> field with CSS width = 6em; or width = 100%, but those only set a fixed width or a width that varies with the container. I want the width to depend on how big the number is that I've typed in.

I'm sure I can do this with JavaScript by setting width = 100% and writing the <input>'s value in the containing element (hidden somehow). But is there a way to do this without JavaScript at all? Pure CSS? I'm able to use the absolute latest bleeding-edge CSS features.


Solution

  • Unfortunately, at the moment a pure CSS solution is unavailable. You can get somewhat close with a monospace font and inline event handlers like shown below. However, this doesn't work for all unicode characters.

    input {
      font-family: 'Courier';
      min-width: 1ch;
      width: 1ch;
    }
    <input oninput="style.width = value.length+'ch'" />

    The best solution currently to work with any font is to "mirror" the input text in some invisible element, measure its width, and then apply that back to the input element. However, to properly mirror the input, make sure the "mirror" element is inline, whitespace-sensitive, and matches the <input> font, like so:

    input {
      font: 16px system-ui;
      min-width: 1ch;
      width: 1ch;
    }
    
    #mirror {
      font: 16px system-ui;
      display: inline;
    
      position: absolute;
      visibility: hidden;
      left: 0;
    }
    <input oninput="mirror.textContent = value; style.width = Math.ceil(mirror.offsetWidth)+'px'">
    <pre id="mirror"></pre>