До сих пор мы стилизовали блоки, текст, изображения, сетки — элементы, которые ведут себя более или менее предсказуемо. input — другое дело: это интерактивный элемент управления, у которого:
- есть собственное поведение браузера "из коробки" (фокус, ввод текста, встроенная валидация);
- внешний вид по умолчанию сильно отличается между браузерами и операционными системами — тот же
<input type="checkbox">в Chrome на Windows, Safari на macOS и Firefox на Android выглядит и ведёт себя по-разному; - это точка прямого взаимодействия пользователя с сайтом — здесь особенно важна доступность (accessibility): не все посетители водят мышкой, кто-то использует клавиатуру или экранный диктор.
Мы разберём стилизацию input отдельно от самой формы — про <form> целиком, отправку данных на сервер и логику форм речь пойдёт в Уроке 15. Здесь наша задача — научиться делать сами поля ввода аккуратными, понятными и доступными.
Атрибут type полностью меняет поведение input — это не просто "разные виды рамочек", а разная логика ввода, разная клавиатура на мобильных устройствах и разная встроенная валидация.
type |
Назначение | Особое поведение браузера |
|---|---|---|
text |
Обычный однострочный текст | Ничего особенного, базовый вариант |
email |
Email-адрес | Встроенная проверка формата (@, домен); на мобильных — клавиатура с @ |
password |
Пароль | Символы скрываются точками/звёздочками |
number |
Числовое значение | Стрелочки увеличения/уменьшения; на мобильных — цифровая клавиатура |
tel |
Телефон | Не валидирует формат сам (номера слишком разные в мире), но вызывает цифровую клавиатуру на мобильных |
url |
Ссылка | Встроенная проверка на наличие протокола и структуры URL |
search |
Поле поиска | В некоторых браузерах — крестик очистки поля "из коробки" |
date |
Дата | Нативный календарь-пикер браузера |
checkbox |
Логический выбор (да/нет, вкл/выкл) | Можно выбрать несколько одновременно |
radio |
Выбор одного варианта из группы | Только один активен внутри группы с одинаковым name |
range |
Числовое значение через ползунок | Визуальный слайдер вместо текстового поля |
file |
Загрузка файла | Открывает системный диалог выбора файла |
submit |
Кнопка отправки формы | Визуально похож на <button>, разберём подробно в Уроке 14 |
Важное практическое следствие: правильный type — это не мелочь ради "красоты", а первая линия валидации и главный помощник для мобильных пользователей. Если для номера телефона поставить type="text" вместо type="tel" — пользователь на телефоне получит обычную буквенную клавиатуру вместо цифровой, и наберёт номер куда медленнее и с большей вероятностью ошибки.
<div class="demo-form">
<input type="text" placeholder="Ваше имя">
<input type="email" placeholder="you@example.com">
<input type="password" placeholder="Пароль">
<input type="tel" placeholder="+7 900 000-00-00">
<input type="number" min="1" max="10" placeholder="Возраст">
<input type="date">
<input type="search" placeholder="Поиск">
<input type="range" min="0" max="100">
<input type="file">
</div>.demo-form {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 400px;
}По умолчанию input выглядит по-разному в каждом браузере — со своей рамкой, отступами, шрифтом. Первый шаг — привести это к общему, предсказуемому виду.
<div class="field-group">
<input
type="text"
class="field"
placeholder="Введите имя"
>
</div>.field-group {
max-width: 400px;
}
.field {
width: 100%;
padding: 10px 14px;
font-size: 16px;
font-family: inherit;
color: #1a1a1a;
background: #fff;
border: 1px solid #d1d5db;
border-radius: 6px;
outline: none; /* уберём стандартную обводку — но обязательно заменим её ниже через :focus! */
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}Разберём построчно:
width: 100%+box-sizing: border-box(обычно задаётся глобально,* { box-sizing: border-box; }) — безborder-boxширина 100% плюсpaddingиborderможет вылезти за пределы родительского контейнера. Это одна из самых частых причин "поле не помещается в форму" у новичков.font-family: inherit— по умолчанию уinputв некоторых браузерах свой системный шрифт, отличный от остального текста страницы.inheritподтягивает шрифт от родителя, чтобы поле визуально не выбивалось.outline: none— убирает стандартную синюю обводку браузера при фокусе. Это опасная строчка — подробнее разберём её в разделе "Подводные камни": убиратьoutlineможно только если тут же ставится собственная, не менее заметная альтернатива через:focus.
Текст-подсказка внутри пустого поля (placeholder="...") — отдельный псевдоэлемент, который стилизуется через ::placeholder:
<div class="field-group">
<input
type="text"
class="field"
placeholder="Например, Иван Иванов"
>
</div>.field::placeholder {
color: #9ca3af;
font-style: italic;
}Важно: placeholder — это подсказка о формате ввода ("например, +7 900 000-00-00"), а не замена подписи к полю. Подробнее — в разделе про доступность ниже.
:focus срабатывает, когда поле получило фокус — пользователь кликнул в него или перешёл клавишей Tab.
<div class="field-group">
<label for="name">Имя</label>
<input
id="name"
type="text"
class="field"
placeholder="Введите имя"
>
</div>.field-group {
max-width: 400px;
}
.field {
width: 100%;
padding: 10px 14px;
font: inherit;
border: 1px solid #d1d5db;
border-radius: 6px;
outline: none;
transition:
border-color 0.15s ease,
box-shadow 0.15s ease;
}
.field:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}Кликните в поле, а затем щёлкните в любое место страницы. Обратите внимание, как при получении фокуса изменяется оформление поля.
Здесь мы заменили убранный outline собственным решением: более насыщенный цвет рамки плюс мягкое "свечение" через box-shadow. Это даёт даже более заметный и стилистически согласованный со страницей эффект, чем стандартная обводка браузера — но, в отличие от простого outline: none без замены, не оставляет пользователя без визуальной подсказки, где сейчас находится фокус.
Современный псевдокласс :focus-visible решает конкретную проблему: браузер сам определяет, был ли фокус получен через клавиатуру (когда обводка действительно нужна) или через клик мышью (когда многие дизайнеры считают обводку визуально излишней).
<div class="field-group">
<label for="email">Email</label>
<input
id="email"
type="email"
class="field"
placeholder="you@example.com"
>
</div>.field:focus-visible {
outline: 2px solid #2563eb;
outline-offset: 2px;
}Попробуйте перейти к полю с помощью клавиши Tab. Обратите внимание на появление обводки вокруг активного элемента.
Разница на практике: клик мышью в поле — :focus срабатывает, :focus-visible в большинстве браузеров тоже сработает для input (в отличие, например, от кнопок, где поведение отличается сильнее). Но общий принцип стоит запомнить: :focus-visible — более "умный" вариант :focus, специально спроектированный так, чтобы не мешать визуально там, где в обводке нет необходимости, и не убирать её там, где она нужна для навигации с клавиатуры.
Браузер умеет валидировать некоторые поля сам, без единой строчки JavaScript — через атрибуты required, pattern, type="email", min/max и подобные. Псевдоклассы :valid и :invalid отражают текущий результат этой встроенной проверки прямо в CSS.
<div class="field-group">
<label for="email">Email</label>
<input
id="email"
type="email"
required
class="field"
placeholder="you@example.com"
>
</div>CSS оставил бы практически без изменений.
.field:invalid {
border-color: #dc2626;
}
.field:valid {
border-color: #16a34a;
}Попробуйте ввести корректный и некорректный адрес электронной почты. Цвет рамки будет автоматически меняться в зависимости от результата встроенной проверки браузера.
| Атрибут | Что проверяет |
|---|---|
required |
Поле не должно быть пустым |
minlength / maxlength |
Минимальная/максимальная длина текста |
min / max |
Минимальное/максимальное числовое значение (для type="number", date, range) |
pattern |
Регулярное выражение, которому должно соответствовать значение |
step |
Шаг для числовых значений (например, step="0.01" для копеек) |
<div class="field-group">
<label for="username">Имя пользователя</label>
<input
id="username"
type="text"
class="field"
placeholder="Например, Иван"
pattern="[A-Za-zА-Яа-я]{2,30}"
required
title="Только буквы, от 2 до 30 символов"
>
</div>Атрибут title в связке с pattern — это текст, который браузер покажет во всплывающей подсказке, если введённое значение не соответствует регулярному выражению.
Если применить :invalid буквально как в примере выше, поле с required окажется отмечено красным сразу при загрузке страницы — ещё до того, как пользователь вообще успел что-либо ввести. Технически поле действительно невалидно (оно пустое, а обязательно), но с точки зрения пользовательского опыта это выглядит так, будто он уже совершил ошибку, хотя только открыл форму.
Частое CSS-решение — использовать комбинацию с :placeholder-shown: подсказка-placeholder показывается только тогда, когда поле пустое, значит красную рамку нужно применять к невалидному состоянию только если placeholder уже не отображается (то есть пользователь что-то ввёл и удалил, либо ввёл некорректное значение):
<div class="field-group">
<label for="city">Город</label>
<input
id="city"
type="text"
class="field"
placeholder="Введите город"
required
>
</div>.field:invalid:not(:placeholder-shown) {
border-color: #dc2626;
}Попробуйте открыть страницу и ничего не вводить — поле останется нейтральным. Затем введите текст и удалите его. После этого сработает правило :invalid:not(:placeholder-shown), и поле получит красную рамку.
Так поле остаётся нейтральным, пока пользователь ещё не начал с ним взаимодействовать, и подсвечивается красным только после того, как он ввёл (и, например, стёр или ввёл некорректно) какое-то значение. Это простое и надёжное решение, которое работает без единой строчки JavaScript.
Более новый псевдокласс
:user-invalidрешает эту же задачу ещё точнее (срабатывает после того, как пользователь взаимодействовал с полем, а не по признаку "показан ли placeholder"), но на момент написания курса поддержка в браузерах у него всё ещё неполная, поэтому в качестве базового и надёжного варианта мы используем связку:invalid:not(:placeholder-shown).
<div class="field-group">
<label for="name">Имя *</label>
<input
id="name"
type="text"
class="field"
required
placeholder="Введите имя"
>
</div>
<div class="field-group">
<label for="city">Город</label>
<input
id="city"
type="text"
class="field"
placeholder="Недоступно"
disabled
>
</div>.field:disabled {
background: #f3f4f6;
color: #9ca3af;
cursor: not-allowed;
}
.field:required {
border-left: 3px solid #f59e0b;
}
.field:hover:not(:disabled) {
border-color: #9ca3af;
}Попробуйте навести курсор на оба поля. Активное поле изменит цвет рамки, а отключённое (disabled) никак не отреагирует.
:hover:not(:disabled) — полезный приём: эффект при наведении мышью применяется, только если поле активно. Незачем показывать пользователю "живую" реакцию на элемент, с которым сейчас нельзя взаимодействовать.
Чекбоксы и радиокнопки устроены иначе, чем текстовые поля — у них нет "текста внутри", есть только состояние вкл/выкл, и стандартный внешний вид у браузеров отличается сильнее всего.
Самый простой современный способ подкрасить чекбоксы, радиокнопки и range под цветовую схему сайта — свойство accent-color. Оно не меняет форму элемента, но красит его в нужный цвет, сохраняя нативное поведение и доступность браузера "из коробки":
<div class="field-group">
<label>
<input type="checkbox">
Запомнить меня
</label>
</div>
<div class="field-group">
<label>
<input type="radio" name="theme" checked>
Светлая тема
</label>
<label>
<input type="radio" name="theme">
Тёмная тема
</label>
</div>input[type="checkbox"],
input[type="radio"] {
accent-color: #2563eb;
width: 18px;
height: 18px;
}Для большинства учебных и даже вполне серьёзных прикладных задач этого достаточно — доступность полностью сохраняется (это по-прежнему нативный элемент со всем его поведением), а внешний вид уже не выглядит как "стандартный браузерный чекбокс, забытый дизайнером".
Если нужен полностью нестандартный вид (например, чекбокс-переключатель), браузерный вид можно убрать полностью через appearance: none, а затем нарисовать элемент заново вручную — через background, border и псевдоэлемент ::before для галочки. Такой подход требует больше кода и внимательности к доступности (важно не потерять фокус-стили и не сломать поведение для скринридеров), поэтому в рамках этого курса мы им подробно не занимаемся — достаточно знать, что такой путь существует, и что accent-color в большинстве практических случаев — оптимальный баланс простоты и результата.
Стилизация — это не только "красиво", но и "можно ли этим пользоваться всем". Несколько базовых правил, которые стоит соблюдать всегда, а не только "для галочки".
<!-- Плохо: только placeholder, подписи нет -->
<div class="field-group">
<input type="text" placeholder="Имя">
</div>
<!-- Правильно: есть настоящая подпись -->
<div class="field-group">
<label for="name">Имя</label>
<input
id="name"
type="text"
placeholder="Например, Мария"
>
</div>Атрибут for у <label> должен совпадать с id соответствующего input. Это делает две вещи одновременно: клик по тексту подписи переносит фокус в поле (удобно на мобильных — попасть пальцем в текст легче, чем в узкое поле), и экранные дикторы озвучивают эту подпись, когда пользователь переходит к полю.
Почему placeholder не заменяет label: как только пользователь начинает печатать, placeholder исчезает — и если он был единственным указанием, что это за поле, пользователь (особенно при возврате к форме или при использовании автозаполнения) теряет контекст. Кроме того, экранные дикторы не всегда озвучивают placeholder так же надёжно, как настоящий <label>.
Иногда по дизайну поле не должно иметь видимой подписи (например, компактное поле поиска с одной лишь иконкой лупы). В этом случае подпись всё равно должна существовать — просто не визуально, а для вспомогательных технологий:
<div class="field-group">
<input
type="search"
class="field"
aria-label="Поиск по сайту"
placeholder="Найти фильм..."
>
</div>Мы уже касались этого выше: outline: none без альтернативы (например, через :focus или :focus-visible) делает страницу непригодной для навигации с клавиатуры — пользователь просто не видит, где сейчас находится фокус, и не понимает, в какое поле он печатает.
На мобильных устройствах рекомендуемая минимальная область нажатия — около 44×44px. Слишком тонкие чекбоксы или радиокнопки (например, 12px) сложно точно нажать пальцем.
<label>
<input type="checkbox">
Я принимаю условия использования
</label>
<br>
<label>
<input type="radio" name="plan">
Базовый тариф
</label>
<label>
<input type="radio" name="plan">
Премиум тариф
</label>input[type="checkbox"],
input[type="radio"] {
width: 20px;
height: 20px;
}
label {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 0;
}Вернёмся к нашему сквозному примеру — странице фильмов из Уроков 11–12 — и добавим два реальных элемента с формами: поле поиска в шапке и чекбоксы фильтров в aside.
Раметка и стилизация из финальной практики урока 11:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>MovieGrid</title>
<link rel="stylesheet" href="style.css" />
</head>
<body class="page">
<header class="header">
<div class="header__logo">🎬 MovieGrid</div>
<nav class="header__nav">
<a href="#">Главная</a>
<a href="#">Фильмы</a>
<a href="#">Контакты</a>
</nav>
</header>
<aside class="filters">
<div>Фильмы</div>
<div>Сериалы</div>
<div>Мультики</div>
</aside>
<main class="movies">
<article class="movie-card">
<img src="https://picsum.photos/300/200?1" alt="Фильм 1" />
<h3>Название фильма 1</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
<article class="movie-card">
<img src="https://picsum.photos/300/200?2" alt="Фильм 2" />
<h3>Название фильма 2</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
<article class="movie-card">
<img src="https://picsum.photos/300/200?3" alt="Фильм 3" />
<h3>Название фильма 3</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
<article class="movie-card">
<img src="https://picsum.photos/300/200?4" alt="Фильм 4" />
<h3>Название фильма 4</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
<article class="movie-card">
<img src="https://picsum.photos/300/200?5" alt="Фильм 5" />
<h3>Название фильма 5</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
<article class="movie-card">
<img src="https://picsum.photos/300/200?6" alt="Фильм 6" />
<h3>Название фильма 6</h3>
<p>Краткое описание фильма для примера карточки.</p>
<a href="#">Смотреть</a>
</article>
</main>
<footer class="footer">
<div>Связаться с нами: info@moviegrid.ru</div>
<div>© 2025 MovieGrid</div>
</footer>
</body>
</html>* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, sans-serif;
}
.page {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"aside main"
"footer footer";
min-height: 100vh;
}
.header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: #2d3436;
color: white;
}
.header__nav {
display: flex;
gap: 16px;
}
.header__nav a {
color: white;
text-decoration: none;
}
.filters {
grid-area: aside;
display: flex;
flex-direction: column;
gap: 12px;
padding: 16px;
background: #f5f5f5;
}
.movies {
grid-area: main;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
padding: 16px;
}
.movie-card {
display: flex;
flex-direction: column;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.movie-card img {
width: 100%;
height: 140px;
object-fit: cover;
}
.movie-card h3,
.movie-card p {
padding: 0 12px;
}
.movie-card a {
margin: 12px;
padding: 8px 12px;
background: #2563eb;
color: white;
text-decoration: none;
border-radius: 6px;
text-align: center;
}
.footer {
grid-area: footer;
display: flex;
justify-content: space-between;
padding: 16px 24px;
background: #333;
color: white;
}Добавляем form search в header между .logo и .nav:
<header class="header">
<div class="logo">MovieGrid</div>
<form class="search" role="search">
<label for="site-search" class="visually-hidden">Поиск по сайту</label>
<input
type="search"
id="site-search"
class="search__input"
placeholder="Найти фильм..."
aria-label="Поиск по сайту"
/>
</form>
<nav class="nav">
<a href="#">Главная</a>
<a href="#">Фильмы</a>
<a href="#">Контакты</a>
</nav>
</header>Добавляем стилизацию для search__input (сразу после .header):
.search__input {
width: 100%;
max-width: 280px;
padding: 8px 14px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 20px;
background: rgba(255, 255, 255, 0.1);
color: white;
font-size: 14px;
outline: none;
transition: border-color 0.15s ease, background 0.15s ease;
}
.search__input::placeholder {
color: rgba(255, 255, 255, 0.6);
}
.search__input:focus-visible {
border-color: #ffffff;
background: rgba(255, 255, 255, 0.2);
}
/* Класс для визуально скрытых, но доступных экранным дикторам подписей */
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}Разбор .visually-hidden: здесь label физически присутствует в разметке — это важно для доступности и для связи for/id — но не занимает видимого места на странице. В отличие от display: none, такой приём не убирает элемент из "дерева доступности", и экранный диктор по-прежнему озвучит подпись при переходе к полю.
Теперь нужно заменить старую разметку aside на новую:
<aside class="filters">
<h3>Категория</h3>
<label class="filter-option">
<input type="checkbox" name="category" value="films" checked />
Фильмы
</label>
<label class="filter-option">
<input type="checkbox" name="category" value="series" />
Сериалы
</label>
<label class="filter-option">
<input type="checkbox" name="category" value="cartoons" />
Мультики
</label>
</aside>И так же заменить стилизацию к ней:
.filters {
display: flex;
flex-direction: column;
gap: 12px;
}
.filter-option {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
padding: 6px 0;
}
.filter-option input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: #2d3436;
cursor: pointer;
}Обратите внимание, что весь текст пункта фильтра обёрнут внутрь <label> вместе с самим input — благодаря этому кликабельна вся строка "Фильмы", а не только маленький квадратик чекбокса. Это одновременно и вопрос удобства, и вопрос доступности (увеличенная область нажатия).
/* Плохо: убрали фокус, ничего не поставили взамен */
input:focus {
outline: none;
}/* Хорошо: убрали стандартный outline, но заменили собственным явным стилем */
input:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}Без какой-либо замены пользователь, работающий с клавиатуры (или из-за двигательных ограничений вынужденный работать только ей), не может понять, в каком поле сейчас находится фокус.
/* Проблема: при width: 100% и padding поле вылезет за пределы родителя */
.field {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
}Без глобального box-sizing: border-box (обычно задаётся один раз для всего проекта через * { box-sizing: border-box; }) итоговая ширина элемента равна width + padding + border, а не просто width. На узких мобильных экранах это часто проявляется как поле, которое "вылезает" за пределы формы или контейнера.
<!-- Проблема: единственная подсказка исчезает при вводе текста -->
<input type="text" placeholder="Ваше имя" />Как только пользователь начинает печатать, единственный источник информации о том, что за поле перед ним, исчезает. Всегда должен быть либо видимый <label>, либо (если по дизайну подпись не нужна визуально) aria-label.
/* Проблема: поле помечается красным сразу при загрузке страницы */
input:invalid {
border-color: red;
}Разобрано подробно в разделе 4 — решение — комбинация :invalid:not(:placeholder-shown).
Стандартный размер чекбокса браузера (обычно около 13–16px) неудобен для нажатия пальцем. Решение — увеличить сам элемент через width/height и, что ещё важнее, оборачивать текст пункта в <label>, чтобы кликабельной была вся строка, а не только маленький квадратик.
Тип input — это не декоративный атрибут, а часть логики поля: он определяет встроенную валидацию браузера и тип клавиатуры на мобильных устройствах. Базовая стилизация текстовых полей требует внимания к box-sizing, чтобы padding не ломал ширину поля, заданную в процентах.
:focus и более современный :focus-visible дают визуальную обратную связь о том, где сейчас находится фокус — убирать стандартный outline можно только вместе с добавлением собственной, не менее заметной замены. Псевдоклассы :valid/:invalid отражают встроенную HTML5-валидацию (required, pattern, type="email" и другие), а связка :invalid:not(:placeholder-shown) решает проблему преждевременной подсветки ошибок ещё до взаимодействия пользователя с полем.
Для чекбоксов и радиокнопок самый практичный способ подкрасить внешний вид без потери нативного поведения — свойство accent-color; более глубокая кастомизация через appearance: none возможна, но требует большего внимания к деталям и не входит в базовый набор этого курса.
Доступность держится на нескольких простых правилах: настоящий <label> (или aria-label, если подпись не видна визуально), сохранённый видимый фокус, и достаточная область нажатия для мобильных устройств.
В следующем уроке разберём стилизацию button — второй ключевой элемент управления, без которого не обходится ни одна форма.
- Почему выбор правильного значения атрибута
typeуinputважнее, чем просто "чтобы поле выглядело иначе"? - Почему
outline: noneпри:focusсчитается опасной практикой и как её нужно применять правильно? - В чём разница между
:focusи:focus-visible? - Почему поле с атрибутом
requiredне стоит стилизовать через голое правилоinput:invalid { border-color: red; }? - Почему
placeholderне может полностью заменить<label>? - Чем
accent-colorудобнее, чемappearance: noneдля стилизации чекбоксов, и когда стоит выбрать второй вариант?
Создайте текстовое поле логина (type="text" или type="email") с оформлением для всех ключевых состояний:
- Базовое состояние: рамка, отступы, скруглённые углы,
placeholderприглушённого серого цвета. :focus-visible— изменение цвета рамки и добавление мягкой тени (box-shadow), без использования гологоoutline: noneбез замены.:disabled— серый фон, курсорnot-allowed.required, с корректной обработкой:invalidчерез связку с:placeholder-shown, чтобы ошибка не показывалась сразу при загрузке страницы.- Добавьте настоящий
<label>, связанный черезfor/id.
Создайте блок фильтра с тремя чекбоксами ("Фильмы", "Сериалы", "Мультики"):
- Используйте
accent-color, чтобы подкрасить чекбоксы под общую цветовую схему. - Каждый пункт — это
<label>, оборачивающий иinput, и текст, чтобы кликабельной была вся строка. - Увеличьте область нажатия каждого пункта минимум до 40px по высоте.
- При наведении на пункт (
:hover) — лёгкая подсветка фона всей строки.
Возьмите страницу фильмов (Уроки 11–12) и добавьте на неё:
- Поле поиска в
header, стилизованное под тёмный фон шапки (полупрозрачная светлая рамка и фон, светлый текст), сaria-label, так как видимого<label>в дизайне шапки нет. - Блок фильтров в
asideиз Задания 2. - Убедитесь, что оба элемента корректно проходят проверку клавиатурой: переход по
Tabдолжен явно показывать, какой элемент сейчас в фокусе, без единого пропущенногоoutline/замены. - Проверьте, что при уменьшении ширины экрана (используя медиа-запросы из Урока 12) поле поиска и фильтры не теряют читаемость и не вылезают за пределы контейнеров.