← Назад к вопросам
В чем разница между button и div помимо screen reader?
1.2 Junior🔥 91 комментариев
#HTML и CSS
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между button и div помимо доступности для screen reader
Основное различие между <button> и <div> выходит далеко за рамки поддержки экранных читателей. <button> — это специализированный семантический элемент, который имеет встроенное поведение и функциональность, которую <div> полностью лишён.
1. Встроенное поведение (Native Behavior)
Button имеет встроенное функционирование:
// ✅ Button: работает по умолчанию
<button onClick={() => console.log('clicked')}>Нажми меня</button>
// Нажимается по:
// - Клику мыши
// - Enter при фокусе
// - Space при фокусе (задержка)
// - Мобильный тап
// ❌ Div: требует дополнительной логики
<div onClick={() => console.log('clicked')}>Нажми меня</div>
// Работает только при клике мышью!
// Enter и Space не сработают
// На мобильных сложно определить длинный тап
Практический пример:
function MyButton() {
const handleClick = () => console.log('Нажата кнопка');
return (
<>
<button onClick={handleClick}>Button (правильно)</button>
<div onClick={handleClick}>Div (неправильно)</div>
</>
);
}
// При нажатии Enter:
// - Button: сработает handleClick ✅
// - Div: ничего не произойдёт ❌
2. Стили по умолчанию (Default Styling)
Button имеет встроенные стили
/* Button стили браузера */
button {
padding: 6px 12px;
border: 1px solid #ccc;
background-color: #f0f0f0;
cursor: pointer;
border-radius: 4px;
font-family: inherit;
}
button:hover {
background-color: #e0e0e0;
}
button:active {
background-color: #d0d0d0;
}
button:focus {
outline: 2px solid blue;
}
/* Div не имеет стилей */
div {
/* ничего */
}
Визуальное сравнение:
<!-- Button выглядит как кнопка из коробки -->
<button>Нажми меня</button>
<!-- Div выглядит как обычный текст -->
<div>Нажми меня</div>
3. Типы button
Тег <button> имеет встроенные типы с разным поведением:
<!-- type="submit" (по умолчанию) -->
<form>
<input type="text" name="user" />
<button type="submit">Отправить форму</button>
<!-- При нажатии отправит данные формы -->
</form>
<!-- type="reset" -->
<form>
<input type="text" name="user" value="John" />
<button type="reset">Очистить форму</button>
<!-- При нажатии вернёт значение на default -->
</form>
<!-- type="button" -->
<button type="button" onclick="doSomething()">Просто действие</button>
<!-- Ничего не отправляет, только вызывает функцию -->
<!-- Div не имеет таких встроенных типов -->
<div onclick="doSomething()">Просто текст</div>
4. Фокусируемость (Focusability)
Button фокусируется по умолчанию
// ✅ Button: доступен в табуляции
<button>Я в Tab order</button>
// Tab переместит фокус на эту кнопку
// ❌ Div: не фокусируется
<div>Я НЕ в Tab order</div>
// Tab пропустит этот div
// ✅ Div с tabindex: искусственно фокусируется
<div tabindex="0">Я в Tab order благодаря tabindex</div>
Это критично для пользователей, использующих только клавиатуру:
function Navigation() {
return (
<nav>
{/* ✅ Правильно: можно переходить между кнопками через Tab */}
<button>Главная</button>
<button>О нас</button>
<button>Контакты</button>
{/* ❌ Неправильно: нельзя выбрать эти элементы через Tab */}
<div onclick="goHome()">Главная</div>
<div onclick="goAbout()">О нас</div>
<div onclick="goContact()">Контакты</div>
</nav>
);
}
5. Обработка Enter и Space
Button обрабатывает клавиши автоматически
function App() {
const handleAction = () => console.log('Action');
return (
<>
{/* ✅ Button: работает с Enter и Space */}
<button onClick={handleAction}>Button</button>
{/* onClick сработает при: мышь, Enter, Space */}
{/* ❌ Div: работает только с мышью */}
<div onClick={handleAction} role="button">Div</div>
{/* onClick НЕ сработает при Space (требует doSomething) */}
</>
);
}
Для корректной работы div нужно добавить обработчик клавиш:
function CustomButtonDiv() {
const handleClick = () => console.log('Action');
const handleKeyDown = (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleClick();
}
};
return (
<div
onClick={handleClick}
onKeyDown={handleKeyDown}
role="button"
tabIndex={0}
>
Div как кнопка (много кода!)
</div>
);
}
6. Состояния disabled
Button имеет встроенное состояние disabled
<!-- ✅ Button: встроенный disabled -->
<button disabled>Я отключена</button>
<!-- Браузер автоматически:
- Блокирует клики
- Меняет внешний вид
- Исключает из Tab order
- Оповещает screen reader
-->
<!-- ❌ Div: нужно всё делать вручную -->
<div aria-disabled="true" class="disabled">Я отключена</div>
<!-- Нужно добавить стили, обработку клавиш, aria-disabled -->
Практический пример:
function SubmitForm() {
const [loading, setLoading] = useState(false);
return (
<form>
<input type="text" />
{/* ✅ Правильно: браузер знает, что кнопка отключена */}
<button disabled={loading} type="submit">
{loading ? 'Загрузка...' : 'Отправить'}
</button>
</form>
);
}
7. Form Submission
Button в форме имеет встроенное поведение
function MyForm() {
const handleSubmit = (e) => {
e.preventDefault();
console.log('Форма отправлена');
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="username" />
{/* ✅ Button: при нажатии триггерит submit событие */}
<button type="submit">Отправить</button>
{/* ❌ Div: не триггерит submit */}
<div onClick={() => handleSubmit()}>Отправить</div>
</form>
);
}
8. Мобильные браузеры
Button имеет встроенное поведение на мобилях
<!-- ✅ Button: оптимизирован для сенсорных устройств -->
<button>Нажми на мобиле</button>
<!-- Браузер добавляет hover эффект, точку фокуса -->
<!-- ❌ Div: требует дополнительной логики -->
<div onclick="action()">Нажми на мобиле</div>
<!-- Может быть сложно точно нажать -->
9. Стили для состояний
Button имеет встроенные styles для :active, :focus
/* ✅ Button: браузер знает эти состояния */
button:hover { background: #ddd; }
button:active { transform: scale(0.98); }
button:focus { outline: 2px solid blue; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
/* ❌ Div: нужно всё прописывать вручную */
.custom-button:hover { background: #ddd; }
.custom-button:active { transform: scale(0.98); }
.custom-button.focused { outline: 2px solid blue; }
.custom-button.disabled { opacity: 0.5; cursor: not-allowed; }
Полное сравнение в таблице
| Аспект | Button | Div |
|---|---|---|
| Клик мышью | ✅ | ✅ |
| Активация Enter | ✅ | ❌ |
| Активация Space | ✅ | ❌ |
| В Tab order | ✅ (auto) | ❌ (нужен tabindex) |
| Встроенный disabled | ✅ | ❌ |
| Стили по умолчанию | ✅ | ❌ |
| Form submission | ✅ | ❌ |
| Keyboard handling | ✅ (auto) | ❌ (manual) |
| Screen reader поддержка | ✅ | ❌ |
| Состояния (:hover, :focus) | ✅ | ❌ |
Когда использовать что
// ✅ Используй BUTTON для действий
<button onClick={handleDelete}>Удалить</button>
<button type="submit">Отправить форму</button>
<button type="reset">Очистить</button>
// ✅ Используй DIV для структуры/контейнера
<div className="container">...</div>
<div className="card">...</div>
<div className="layout">...</div>
// ❌ НЕ используй DIV для действий (даже с onclick)
<div onClick={handleAction}>Это не кнопка</div>
// ❌ НЕ используй BUTTON только для стилей
<button className="fancy-box">Это контейнер, не кнопка</button>
Итоги
Использование <button> вместо <div> для интерактивных элементов — это не просто вопрос доступности. Это обеспечивает:
- Встроенное поведение: Enter, Space, фокус
- Встроенные стили: наглядность, что это кнопка
- Встроенные состояния: disabled, hover, active, focus
- Форма-интеграция: работа с формами
- Мобильная оптимизация: лучшее сенсорное взаимодействие
- Меньше кода: не нужно повторять логику
- Лучший SEO: семантический HTML
Всегда используй семантический HTML для своего назначения — <button> для кнопок, а не <div>.