skip to Main Content

When I change the font-size CSS property of the <input type="number"> element, either directly with CSS or post-element creation via JavaScript, the spinners don’t change size in either FireFox or Safari. The input/display box does. So with larger fonts — extremely important for accessibility — the actual spinner buttons are relatively tiny when the font is large.

In FireFox:

enter image description here
versus
enter image description here

According to Mozilla, checking this morning:

There is no standard way to change the style of spinners used to change the value of the field, with the spinners on Safari being outside the field.

This seems… unreasonable. It also seems unreasonable the spinner size doesn’t track the font size in use. I feel like I must be missing something.

Is my only option to completely roll my own spinner?

2

Answers


    • To use custom styling for the up-/down-buttons (spinners):
      Yes, you need to create your own custom input element.
    • I you are concerned about "touch"-devices:
      The browsers on those devices should be responsible to provide appropriate ways to change the number.

    The browsers standard form elements (like input) are just very basic and un-styled, pretty much just like all HTML elements (e.g. h1, p, ul, …) would have some basic default style if you would create an HTML page without any CSS.

    You can create an HTML page without any styling, including number inputs, and you might not like the style, but it will look consistent. If you zoom the whole page (usually CTRL + / CTRL - / CTRL mouse-wheel), then the up- / down-buttons would as well scale to match the font size.

    The up- / down-buttons are no HTML elements themselves, but only a "convenience" addition that the browser provides. To satisfy the declaration <input type="number"> the browser could theoretically decide to just render only the input box, or only some up- / down-buttons, or something else.

    This is even worse with e.g. a <input type="file">, which renders including a button and a file name, which can’t be styled with CSS.

    Login or Signup to reply.
  1. Turns out that making bigger controls for input[type="number"] is not a cross-browser feature. So one thing that you can do to make it work everywhere is "simulate" the controls.

    1- First hide the native controls

    This can be done simply in CSS like this:

    /* Chrome, Safari, Edge, Opera */
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    /* Firefox */
    input[type=number] {
      -moz-appearance: textfield;
    }
    

    2- Next add 2 custom buttons with their actions

    (Complete solution)

    const input = document.getElementById("nb-input");
    function returnNb(nb) {
      if (nb) return parseFloat(nb);
      else return 0;
    }
    const increment = () => input.value = (returnNb(input.value) + 1).toString();
    const decrement = () => input.value = (returnNb(input.value) - 1).toString();
    input {
      font-size: 34px;
    }
    /* Chrome, Safari, Edge, Opera */
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    /* Firefox */
    input[type=number] {
      -moz-appearance: textfield;
    }
    .container {
      display: flex;
      width: 200px;
    }
    .controls {
      display: flex;
      flex-direction: column;
    }
    .spinner {
      flex: 50%;
    }
    <div class="container">
      <input id="nb-input" type="number" />
      <div class="controls">
        <button class="spinner" onclick="increment()">
          <svg width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
            <path d="M3.204 11h9.592L8 5.519 3.204 11zm-.753-.659 4.796-5.48a1 1 0 0 1 1.506 0l4.796 5.48c.566.647.106 1.659-.753 1.659H3.204a1 1 0 0 1-.753-1.659z" />
          </svg>
        </button>
        <button class="spinner" onclick="decrement()">
          <svg width="24" height="24" viewBox="0 0 16 16">
            <path d="M3.204 5h9.592L8 10.481 3.204 5zm-.753.659 4.796 5.48a1 1 0 0 0 1.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 0 0-.753 1.659z" />
          </svg>
        </button>
      </div>
    </div>

    And for sure you can customize the buttons as you desire, you don’t have to follow the styles that I’ve used.

    Regards

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search