← Назад к вопросам
Почему нельзя использовать div элемент вместо button в HTML?
2.0 Middle🔥 132 комментариев
#HTML и CSS#Оптимизация и производительность
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему DIV не должен заменять BUTTON
Это фундаментальный вопрос про семантику HTML и доступность. Расскажу почему это критично.
Проблема: неправильно сделанная кнопка
<!-- ПЛОХО - это не кнопка, а просто поле -->
<div class="button" onclick="handleClick()">
Нажми на меня
</div>
<!-- ХОРОШО - это настоящая кнопка -->
<button onclick="handleClick()">
Нажми на меня
</button>
Это не просто вопрос семантики - это влияет на функциональность!
1. Доступность (Accessibility)
Люди с ограничениями используют assistive technologies (скринридеры, клавиатура).
Скринридер не прочитает DIV как кнопку:
<!-- ПЛОХО - скринридер не знает что это кнопка -->
<div class="button" onclick="handleClick()">
Удалить
</div>
<!-- Скринридер скажет: "Удалить" (просто текст)
Не скажет что это интерактивный элемент!
Пользователь может пропустить это
-->
<!-- ХОРОШО - скринридер понимает что это кнопка -->
<button onclick="handleClick()">
Удалить
</button>
<!-- Скринридер скажет: "Кнопка Удалить"
Пользователь знает что это нажимаемый элемент!
-->
2. Клавиатурная навигация
Многие пользователи используют клавиатуру (Tab, Enter, Space).
<!-- ПЛОХО - DIV не фокусируется по Tab -->
<div class="button" onclick="handleClick()">
Отправить
</div>
<!-- Пользователь нажимает Tab - кнопка НЕ фокусируется
Он может её вообще не увидеть
Не может нажать Enter или Space
-->
<!-- ХОРОШО - BUTTON фокусируется автоматически -->
<button onclick="handleClick()">
Отправить
</button>
<!-- Пользователь нажимает Tab - кнопка ФОКУСИРУЕТСЯ
Он видит что кнопка выбрана (outline)
Может нажать Enter или Space для активации
-->
3. Семантика HTML
HTML элементы имеют встроенный смысл (semantic meaning).
<!-- ПЛОХО - неправильная семантика -->
<div class="button" role="button" tabindex="0" onclick="...">
Вход
</div>
<!-- Это выглядит как кнопка, но на самом деле DIV
Браузер не знает какого поведения ожидать
Поисковые системы не понимают назначение элемента
-->
<!-- ХОРОШО - правильная семантика -->
<button>
Вход
</button>
<!-- Браузер ЗНАЕТ что это кнопка
Применяет правильные стили по умолчанию
Поддерживает правильное поведение
SEO лучше индексирует
-->
4. Встроенное поведение браузера
BUTTON имеет встроенное поведение:
<!-- BUTTON автоматически обрабатывает -->
<button type="submit">Отправить</button>
<!-- Встроенное поведение:
1. Enter активирует кнопку (не нужен onClick)
2. Space активирует кнопку
3. Поддерживает disabled состояние
4. Показывает :focus состояние
5. Показывает :active состояние
6. Работает в формах
-->
<!-- DIV не имеет этого поведения -->
<div class="button" onclick="...">Отправить</div>
<!-- Нужно вручную реализовать:
- Обработку клавиш
- Обработку фокуса
- Состояния
- CSS для всех состояний
- ARIA атрибуты
-> Много лишнего кода!
-->
5. Встроенные стили и состояния
<!-- BUTTON имеет встроенные стили -->
<button>Нажми</button>
<!-- Браузер применяет стили по умолчанию
- Видимая граница
- Фон
- Padding
- Правильный cursor: pointer
- :hover состояние
- :active состояние
- :disabled состояние
- :focus состояние
-->
<!-- DIV требует стилизации -->
<div class="button">Нажми</div>
<!-- Нужно написать CSS:
.button {
border: ...
background: ...
padding: ...
cursor: pointer;
}
.button:hover { ... }
.button:active { ... }
.button:focus { ... }
-> Много кода!
-->
6. Правильный пример: React компонент
// ПЛОХО - DIV вместо button
function DeleteButton() {
const handleClick = () => {
deleteItem();
};
return (
<div
className="delete-button"
onClick={handleClick}
role="button"
tabIndex={0}
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
aria-label="Удалить"
>
Удалить
</div>
);
}
// ХОРОШО - button элемент
function DeleteButton() {
const handleClick = () => {
deleteItem();
};
return (
<button onClick={handleClick} aria-label="Удалить">
Удалить
</button>
);
}
// Второй вариант:
// - Короче
// - Понятнее
// - Доступнее
// - Работает везде
7. Используй правильные элементы
<!-- Для кнопки -->
<button>Действие</button>
<button type="submit">Отправить форму</button>
<button type="reset">Очистить форму</button>
<button type="button" disabled>Отключена</button>
<!-- Для ссылки -->
<a href="/page">Перейти на страницу</a>
<!-- Для input поля -->
<input type="text" placeholder="Введи текст">
<input type="email" placeholder="Email">
<input type="password" placeholder="Пароль">
<!-- Для текста -->
<p>Обычный текст</p>
<h1>Заголовок</h1>
<strong>Важное</strong>
<em>Выделенное</em>
<!-- Не использовать DIV для этого! -->
<div onclick="...">❌ НЕ ПРАВИЛЬНО</div>
8. ARIA атрибуты - это костыль
<!-- DIV с ARIA - плохое решение -->
<div
role="button"
tabindex="0"
aria-pressed="false"
aria-label="Лайк"
onclick="toggleLike()"
>
♥ Лайк
</div>
<!-- Это работает благодаря ARIA, НО:
- Нужно вручную управлять фокусом
- Нужно обрабатывать клавиши вручную
- Нужны CSS состояния вручную
- Это костыль над костылём
- Легче ошибиться
-->
<!-- BUTTON - естественное решение -->
<button aria-pressed="false" aria-label="Лайк" onclick="toggleLike()">
♥ Лайк
</button>
<!-- Это просто работает:
- Фокус управляется браузером
- Клавиши обрабатываются браузером
- Стили есть по умолчанию
- Меньше ошибок
- Меньше кода
-->
9. Проверка: правильно ли я сделал?
// Вопрос 1: Это действие или навигация?
// - Действие (удалить, отправить, сохранить) -> BUTTON
// - Навигация (перейти на страницу) -> LINK <a>
// Вопрос 2: Использую ли я click handler?
// - Да (onclick=...) -> probably BUTTON
// - Нет (обычная навигация) -> LINK
// Вопрос 3: Это часть формы?
// - Да (submit, reset) -> BUTTON
// - Нет -> BUTTON or LINK
// Вопрос 4: Может ли пользователь использовать клавиатуру?
// - Нет -> ПЛОХО, нужно исправить
// - Да -> ХОРОШО
// Вопрос 5: Может ли пользователь табуляции табом?
// - Нет -> ПЛОХО
// - Да -> ХОРОШО
10. Реальный пример: toggle кнопка
// ПЛОХО - DIV
function ToggleDarkMode() {
const [isDark, setIsDark] = useState(false);
return (
<div
className={`toggle ${isDark ? 'dark' : 'light'}`}
onClick={() => setIsDark(!isDark)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setIsDark(!isDark);
}
}}
>
{isDark ? '🌙' : '☀️'}
</div>
);
}
// ХОРОШО - button
function ToggleDarkMode() {
const [isDark, setIsDark] = useState(false);
return (
<button
className={`toggle ${isDark ? 'dark' : 'light'}`}
onClick={() => setIsDark(!isDark)}
aria-label={isDark ? 'Включить светлую тему' : 'Включить тёмную тему'}
>
{isDark ? '🌙' : '☀️'}
</button>
);
}
// Второй вариант:
// - 40% меньше кода
// - Работает с клавиатурой
// - Доступен для скринридеров
// - Правильная семантика
// - Лучше для SEO
Итого
НИКОГДА не используй DIV вместо BUTTON потому что:
- Доступность - скринридеры не поймут
- Клавиатура - Tab и Enter не работают
- Семантика - неправильное значение
- Поведение - нет встроенного поведения браузера
- CSS - нужно писать много кода
- Состояния - focus, hover, disabled не работают
- SEO - поисковики не понимают
- Проще - BUTTON это стандартный элемент
Правильное правило:
- Кнопка = <button>
- Ссылка = <a href>
- Текст = <p>, <div>
- Input = <input>
- Не нарушай семантику HTML!