cssinput

change color / transpanency of spinor of <input type="number">


I have an input field for a number and when hovering over it, it shows those arrows with whome one can change the value by one. I want to adjust them to fit my color shema. I'd like to change the color of the arrows if possible, but for now it would be enought if I could just make the background transparent. And I mean the white background ONLY. I know how to make the arrows transparent but that is not what I want.

enter image description here

For a scrollbar I manged it

/* ----- scrollbar ----- */
#message-input, .edit-input, #messages {
    scrollbar-color: #e4a9c4 transparent;
}

for the number input I tried this but it does not work

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    color: #e4a9c4 transparent;
}

enter image description here


Solution

  • The styling options for default spin buttons are limited, and not all browsers support them. Instead, I recommend hiding them and manually adding your own buttons.

    // For every input number that has the spin-buttons class, add the container and buttons with the proper structure
    document.addEventListener("DOMContentLoaded", function() {
      document.querySelectorAll("input[type='number'].spin-buttons").forEach(input => {
        const container = document.createElement("div");
        container.classList.add("spin-container");
        input.parentNode.insertBefore(container, input);
        container.appendChild(input);
    
        const controls = document.createElement("div");
        controls.classList.add("spin-controls");
    
        const upButton = document.createElement("button");
        upButton.classList.add("up");
        upButton.textContent = "▲";
        upButton.addEventListener("click", function(event) {
          event.stopPropagation();
          input.value = Number(input.value) + 1;
        });
    
        const downButton = document.createElement("button");
        downButton.classList.add("down");
        downButton.textContent = "▼";
        downButton.addEventListener("click", function(event) {
          event.stopPropagation();
          input.value = Number(input.value) - 1;
        });
    
        controls.appendChild(upButton);
        controls.appendChild(downButton);
        container.appendChild(controls);
      });
    });
    /* Set background-color just for test */
    input[type='number'] {
      background-color: #7fb0dc;
    }
    
    .spin-container {
      position: relative;
      display: inline-block;
    }
    
    /* Providing space for our arrows */
    .spin-container > input[type='number'].spin-buttons {
      padding-right: 15px;
    }
    
    /* Hiding the default arrows of the number input */
    .spin-container > input[type='number'].spin-buttons::-webkit-inner-spin-button,
    .spin-container > input[type='number'].spin-buttons::-webkit-outer-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    /* Positioning the buttons to the right */
    .spin-container > .spin-controls {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      width: 20px;
      display: none;
      flex-direction: column;
    }
    .spin-container .spin-controls button {
      width: 10px;
      height: calc((100% - 1px) / 2);
      font-size: 7px;
      border: none;
      background: transparent;
      color: #555;
      cursor: pointer;
      display: block;
    }
    .spin-container > .spin-controls > button:hover {
      color: #000;
    }
    .spin-container:hover > .spin-controls {
      display: flex;
    }
    Default
    <input type="number" />
    Improved
    <input type="number" class="spin-buttons" />

    It's not the most optimal solution I made, I just wanted to demonstrate the approach. I added padding to the right side of the input so that a div with two buttons could fit underneath each other. In these buttons, I displayed two arrows with appropriate sizes for the input.

    To avoid code duplication, in the basic HTML, only the input field needs to be declared, and when the spin-buttons class is present, JavaScript places the input field into a container upon DOM load and adds the necessary HTML code and buttons to display the up and down arrows.

    The spin-controls only appears when the input field is hovered.