Back to CSS Input Fields Stepper Number Light JS
Share
HTML
<label class="if-step">
  <span class="if-step-label">Quantity</span>
  <span class="if-step-wrap">
    <button type="button" class="if-step-btn" data-if-step="-1" aria-label="Decrease">−</button>
    <input type="number" name="qty" min="0" max="99" value="1" aria-label="Quantity" />
    <button type="button" class="if-step-btn" data-if-step="1" aria-label="Increase">+</button>
  </span>
</label>
CSS
.if-step {
  display: grid;
  gap: 6px;
  width: 100%;
  max-width: 220px;
  font-size: 11px;
  color: #b8b6d4;
}

.if-step-label {
  font-weight: 600;
}

.if-step-wrap {
  display: grid;
  grid-template-columns: 36px 1fr 36px;
  background: #1a1a22;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  overflow: hidden;
  transition: border-color 0.2s;
}

.if-step-wrap:focus-within {
  border-color: #14b8a6;
}

.if-step-btn {
  background: rgba(20, 184, 166, 0.06);
  border: 0;
  color: #5eead4;
  font-size: 18px;
  font-weight: 700;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

.if-step-btn:hover {
  background: rgba(20, 184, 166, 0.18);
  color: #fff;
}

.if-step-btn:active {
  background: rgba(20, 184, 166, 0.28);
}

.if-step input {
  background: transparent;
  border: 0;
  outline: none;
  color: #f0eeff;
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  padding: 10px 0;
  -moz-appearance: textfield;
}

.if-step input::-webkit-outer-spin-button,
.if-step input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
JS
// Stepper +/- buttons — clamp to min/max
document.querySelectorAll(".if-step-wrap").forEach(function (wrap) {
  var input = wrap.querySelector('input[type="number"]');
  if (!input) return;
  wrap.querySelectorAll("[data-if-step]").forEach(function (btn) {
    btn.addEventListener("click", function () {
      var dir = parseInt(btn.dataset.ifStep, 10) || 0;
      var min = input.min !== "" ? Number(input.min) : -Infinity;
      var max = input.max !== "" ? Number(input.max) : Infinity;
      var val = (Number(input.value) || 0) + dir;
      if (val < min) val = min;
      if (val > max) val = max;
      input.value = String(val);
    });
  });
});