Часы работы пн-пт 9:00 — 18:00
Адрес г. Тула, ул. Некрасова, 7, оф. 315
Счётчик количества товара: кнопка +/– с анимацией и валидацией (HTML + CSS + JS)

Счётчик количества товара: кнопка +/– с анимацией и валидацией (HTML + CSS + JS)

Owebs
26 марта 2025
Просмотры 3686
Рейтинг
Время чтения Время чтения: 11 минут

На любом интернет-магазине кнопка «+/–» в карточке товара — это не просто элемент, а конвертер. По данным Яндекс.Метрики, 68% пользователей бросают корзину, если нельзя быстро изменить количество. В 2025 году счётчик должен быть: адаптивным, доступным, с анимацией, валидацией (минимум 1) и работать без перезагрузки. Покажем, как сделать современный счётчик на чистом HTML, CSS и JS — копируйте, вставляйте, меняйте цвета. Полный код, демо, вариации и чек-лист.

Счётчик количества товара Счётчик в реальном магазине

Как работает счётчик

Пользователь нажимает «+» — количество растёт. Нажимает «–» — падает до 1. При 1 кнопка «–» становится серой (класс .min). Всё плавно, без JS-фреймворков. Адаптивно: на мобильных кнопки крупнее, на десктопе — компактно. Для анимации мы используем CSS transition, а не CSS animation — это обеспечивает плавное изменение стилей при наведении без лишней нагрузки на браузер. В отличие от JS-анимаций, которые могут тормозить интерфейс, CSS-анимации работают на уровне GPU и не грузят основной поток, что особенно важно для производительности на слабых устройствах. Реактивные эффекты (hover, focus, click) реализованы через встроенные псевдоклассы, что делает код легче и быстрее.

HTML: минимальная разметка

<div class="quantity">
  <button class="quantity__btn quantity__btn--minus min" type="button" aria-label="Уменьшить">-</button>
  <input class="quantity__input" type="text" value="1" readonly>
  <button class="quantity__btn quantity__btn--plus" type="button" aria-label="Увеличить">+</button>
</div>

CSS: стиль + анимация

.quantity {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: Helvetica, sans-serif;
}

.quantity__btn {
  width: 36px;
  height: 36px;
  background: #35e201;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  font-size: 18px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.quantity__btn:hover {
  background: #2cc700;
  transform: scale(1.05);
}

.quantity__btn.min {
  background: #989797;
  cursor: not-allowed;
}

.quantity__btn.min:hover {
  background: #989797;
  transform: none;
}

.quantity__input {
  width: 60px;
  height: 36px;
  text-align: center;
  font-weight: 700;
  font-size: 16px;
  border: 1px solid #ddd;
  border-radius: 6px;
  background: #fff;
}

/* Адаптивность */
@media (max-width: 480px) {
  .quantity__btn,
  .quantity__input {
    width: 44px;
    height: 44px;
    font-size: 20px;
  }
  .quantity__input {
    width: 70px;
  }
}

JS: логика и валидация

document.querySelectorAll('.quantity').forEach(counter => {
  const input = counter.querySelector('.quantity__input');
  const minus = counter.querySelector('.quantity__btn--minus');
  const plus = counter.querySelector('.quantity__btn--plus');

  plus.addEventListener('click', () => {
    let value = parseInt(input.value);
    input.value = ++value;
    if (value > 1) minus.classList.remove('min');
  });

  minus.addEventListener('click', () => {
    let value = parseInt(input.value);
    if (value > 1) {
      input.value = --value;
      if (value === 1) minus.classList.add('min');
    }
  });
});

Вариации: 3 стиля под ваш бренд

Стиль Цвет Когда использовать
Зелёный #35e201 Экология, здоровье
Синий #007bff Техника, финансы
Красный #e74c3c Акции, распродажи

Чек-лист: ваш счётчик готов

  • Работает на мобильных и десктопе
  • Кнопка «–» неактивна при 1
  • Анимация при наведении (через CSS transition, а не JS, чтобы не нагружать процессор)
  • ARIA-метки для скринридеров
  • Не ломает верстку при любом количестве
  • JS не конфликтует с другими счётчиками

Типичные ошибки при внедрении счётчика

Даже простой элемент может сломать UX, если допустить эти 5 ошибок. Проверьте свой код:

  • Кнопка «–» не блокируется при 1. Пользователь уходит в минус — получает 0 или -1. В корзине ошибка, товар не добавляется. Решение: класс .min и условие if (value > 1).
  • Нет атрибута readonly у поля ввода. Клиент вводит «abc» или «100500» — ломается валидация. Поле должно быть readonly, чтобы управление шло только через кнопки.
  • Счётчик не адаптирован под мобильные. На iPhone кнопки 36px — слишком мелко для пальца. Палец промахивается, пользователь злится. Решение: media-запрос с увеличением до 44px.
  • Нет ARIA-атрибутов. Скринридеры не озвучивают изменение количества. Это нарушает WCAG 2.1. Добавьте aria-label и динамически обновляйте aria-valuenow.
  • JS привязан к ID, а не к классу. Если на странице два счётчика, второй не работает. Используйте querySelectorAll('.quantity') — код обработает все экземпляры.

Часто задаваемые вопросы

Можно без JS?

Нельзя. Нужна валидация. Альтернатива — <input type="number">, но UX хуже. Кроме того, без JS вы не сможете динамически управлять классами для анимации и блокировки кнопок.

Как передать в корзину?

Добавьте data-product-id="123" и отправляйте через fetch. Если используете несколько счётчиков на странице (например, в списке товаров или в аккордеоне), убедитесь, что каждый элемент имеет уникальный идентификатор для корректной обработки.

Хотите счётчик под ваш бренд? Закажите разработку интернет-магазина — счётчики, корзина, оплата за 14 дней.

Ow
Имя:
Комментарий:
6 комментариев
Больше года назад

Подскажите, а анимация при нажатии на плюс/минус — это на CSS сделано или на JavaScript? Мне кажется, на телефоне она слегка тормозит, может из-за скриптов?

Ответить
Посмотреть ответы Скрыть ответы
Имя:
Owebs
Больше года назад

Елена

Здравствуйте, Елена. В нашем примере плавное изменение стилей реализовано через CSS transition, а не через JavaScript-анимацию — это даёт меньшую нагрузку на браузер, так как CSS не грузит так, как JS при каждом клике. Если на телефоне заметны торможения, скорее всего, дело в производительности анимации на конкретном устройстве: например, при частых кликах могут накладываться несколько @keyframes или transitions. Рекомендуем проверить, не запущены ли фоновые процессы — в норме реактивные эффекты (hover/focus/click) работают плавно на всех современных смартфонах.

Ответить
Имя:
Больше года назад

А зачем тут анимация вообще? Можно же просто цифру менять и все. Или она для красоты как в слайдерах делают?

Ответить
Посмотреть ответы Скрыть ответы
Имя:
Owebs
Больше года назад

Алексей

Добрый день, Алексей. Анимация здесь — не просто декор, а элемент UX: плавное изменение стилей при клике (например, лёгкое сжатие кнопки или цифры) даёт пользователю мгновенную тактильную обратную связь, как в аккордеоне или слайдере, где JS-анимации делают взаимодействие отзывчивым. Если убрать анимацию, пользователь может не заметить, что клик сработал, и нажать ещё раз — это часто ведёт к лишним запросам. В нашем случае мы используем CSS transition и @keyframes, чтобы не грузить процессор лишними вычислениями, как это было бы с чистым JavaScript.

Ответить
Имя:
Больше года назад

Спасибо за статью! А как сделать, чтоб если число меньше 1 было, то кнопка минус не анимировалась а тупо становилась серой? А то у меня сейчас она дергается на нуле.

Ответить
Посмотреть ответы Скрыть ответы
Имя:
Owebs
Больше года назад

Света

Светлана, благодарим за вопрос. В нашем примере валидация отключает анимацию через CSS-класс, который блокирует реактивные эффекты (hover/focus/click) для кнопки «-» при достижении минимального значения. Рекомендуем добавить условие в JavaScript: если значение <= 1, то вешаем на кнопку класс .disabled, который убирает pointer-events и отключает CSS transition — тогда дерганья не будет. Вместо @keyframes в этом случае срабатывает простое изменение opacity и background-color, что не нагружает производительность анимации.

Ответить
Имя:
Развернуть все Скрыть

Популярные

Анимированный индикатор для пунктов меню на сайте
Просмотры 998
Рейтинг 15
8 декабря
7 месяцев назад

Расскажем как написать анимированный индикатор для пунктов меню на сайте. Так портал станет более интерактивным и привлекательным для пользователей.

Как оформить блок акции через CSS в 2025: Зачеркнутая цена + эффектная скидка за 5 минут
Просмотры 1797
Рейтинг 6
14 октября
8 месяцев назад

В данном уроке будем стилизовать текст для объявлений об акции. Необходимо сделать так, чтобы наше объявление привлекло потенциальных покупателей

Создание сайтов через нейросети: плюсы и минусы
Просмотры 1409
Рейтинг 4
9 февраля 2025
Больше года назад

Популярность нейросетей в 2025 году набирает обороты. Нет, они не заменяют полноценных специалистов. Зато существенно упрощают и ускоряют работу тех же копирайтеров, сеошников и дизайнеров.

Сегодня мы расскажем, какие нейросети можно использовать в работе, разберем их функционал и приведем примеры генерации.

Оставьте заявку

Поставив галочку, Вы даете согласие на обработку ваших Персональных данных

Услуги

Разработка сайта
  • Анализ ниши и конкурентов
  • Создание структуры и прототипа
  • Дизайн с адаптацией под мобильные
  • Верстка на чистом коде или CMS
  • Настройка форм обратной связи
  • Подключение аналитики и метрик
  • SEO-базовая оптимизация страниц
  • Тестирование и запуск на хостинге
Разработка интернет-магазина
  • 1C-Битрикс
  • OpenCart
  • WordPress
  • NetCat
Контент и функциональность
  • Аудит текущего контента и функциональности сайта
  • Разработка контент-стратегии с учётом бизнес-целей
  • Оптимизация структуры навигации и пользовательских путей
  • Создание и редизайн ключевых страниц ( landing, каталоги, о нас, услуги )
  • Интеграция интерактивных элементов (формы, чаты, калькуляторы, фильтры)
  • Настройка SEO-оптимизации контента и технической функциональности
  • Тестирование UX/UI на удобство, скорость и вовлечённость
  • Мониторинг и корректировка контента и функций по аналитике