Ссылки, изображения и таблицы
Научимся соединять страницы между собой и наполнять их мультимедиа.
Ссылки — <a>
Ссылка задаётся тегом <a> с атрибутом href. Ссылаться можно на внешние сайты, локальные файлы и элементы своей страницы.
<a href="https://developer.mozilla.org">MDN Docs</a>
<a href="about.html">О нас</a>
<a href="#contacts">Контактная информация</a>
| Вид ссылки | Пример | Куда ведёт |
|---|---|---|
| Абсолютная | href="https://…" | На другой сайт |
| Относительная | href="about.html" | На файл рядом с текущим |
| Якорная | href="#id" | К элементу с этим id |
href="mailto:hi@mail.ru" | Открывает почтовый клиент | |
| Телефон | href="tel:+79990000000" | Звонок на мобильных |
target="_blank" и rel="noopener" — это безопаснее по открытию в новой вкладке.Изображения — <img>
Изображение — одиночный тег с src (путь) и alt (текст-заменитель). Ширину и высоту можно управлять через CSS, а здесь уменьшим прямо атрибутами для примера:
<img src="cat.jpg" alt="Рыжий кот на подоконнике" width="300">
Атрибут alt показывается, если картинка не загрузилась. Скринридеры озвучивают его незрячим пользователям — это не формальность, а доступность.
Таблицы
Таблица строится из рядов <tr>, ячеек данных <td> и заголовков <th>. Для объединения ячеек есть атрибуты colspan и rowspan.
<table>
<thead>
<tr><th>Технология</th><th>Сложность</th></tr>
</thead>
<tbody>
<tr><td>HTML</td><td>Низкая</td></tr>
<tr><td>CSS</td><td>Средняя</td></tr>
<tr><td>JS</td><td>Высокая</td></tr>
</tbody>
</table>
Видео и аудио
Современные теги позволяют встраивать видео без сторонних плееров:
<video controls width="400">
<source src="promo.mp4">
</video>
<audio controls>
<source src="track.mp3">
</audio>
Пути: относительные и абсолютные
Путь к файлу может быть полным (от корня сайта) или относительным (от текущей папки). Разница критична при переносе сайта на хостинг:
<img src="images/cat.jpg"> <!-- в подпапке images/ -->
<img src="../images/cat.jpg"> <!-- на уровень выше -->
<a href="/blog/post.html"> <!-- от корня сайта -->
<img src="https://site.ru/i/cat.jpg"> <!-- внешний -->
../ — подняться на уровень вверх, ./ — остаться в текущей папке (пишут не всегда). Слеш в вебе всегда прямой /, даже в Windows.Форматы изображений
| Формат | Плюсы | Для чего |
|---|---|---|
| JPEG | маленький вес для фото | фотографии, фон |
| PNG | прозрачность без потерь | логотипы, скриншоты |
| WebP | лучшее сжатие и прозрачность | современные сайты |
| SVG | вектор, масштабируется без потери качества | иконки, иллюстрации |
| GIF | простая анимация | мелкие анимации |
Ленивая загрузка и скорость сайта
Страница не обязана ждать загрузки всех картинок сразу. Атрибут loading="lazy" подгружает изображение, только когда пользователь докрутил до него:
<img src="gallery/photo-12.jpg"
alt="Фото из поездки"
loading="lazy" decoding="async">
loading="lazy". Первому экрану — наоборот, eager (по умолчанию): там лень только навредит, пользователь уже смотрит на эту картинку.Семантика таблиц: caption и scope
Таблицам можно дать подпись <caption>, а заголовки колонок пометить scope="col" — так её понимают скринридеры и поисковики:
<table>
<caption>Расписание занятий</caption>
<tr>
<th scope="col">День</th>
<th scope="col">Тема</th>
</tr>
<tr><td>Пн</td><td>HTML</td></tr>
</table>
Ссылка «наверх» и глубокие якоря
Якорь можно направить не только вниз, но и «наверх» — на любого предка, у которого есть id. Классика — кнопка возврата:
<body id="top">
<a href="#top">↑ Наверх</a>
<!-- или на любой блок -->
<a href="#footer">К контактам</a>
<footer id="footer">...</footer>
<a href="contacts.html#map"> — откроет страницу и сразу прокрутит к блоку.Безопасные ссылки: rel="noopener"
При открытии в новой вкладке передавайте rel="noopener noreferrer" — тогда вкладка-цель не получит ссылку на вашу страницу и не сможет ею манипулировать:
<a href="https://example.com"
target="_blank"
rel="noopener noreferrer">Внешняя ссылка</a>
noopener автоматически у target="_blank", но правило «отец и сын» не мешает: noreferrer ещё и отключает передачу реферера.Адаптивные изображения: srcset и <picture>
Тег <picture> и атрибут srcset подсказывают браузеру несколько вариантов картинки — для экрана, плотности пикселей и формата:
<picture>
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg"
srcset="hero@2x.jpg 2x"
alt="Баннер">
</picture>
@2x-логика применима и в CSS — background-image: -webkit-image-set(url(...) 2x). На ретине телефон запросит картинку вдвое чётче, а на обычном экране — полегче.Встраивание: iframe
В чужой контент — карты, видео, формы — встраивают через <iframe>:
<iframe src="https://www.openstreetmap.org/export/embed.html"
width="500" height="300"
loading="lazy"></iframe>
sandbox или заголовок X-Frame-Options на стороне встраиваемого ресурса.Мета-теги соцсетей (Open Graph)
Шаринг в мессенджерах и соцсетях показывает превью-карточку. Ею управляют OG-теги:
<meta property="og:title" content="WebDev Уроки">
<meta property="og:image" content="https://dev.ru/preview.png">
<meta property="og:description" content="Курс по вебу">
Скачивание файла: download
Ссылку можно превратить в кнопку «скачать» — браузер не откроет файл, а сохранит его:
<a href="files/resume.pdf" download>Скачать резюме</a>
<!-- можно задать своё имя загрузки: -->
<a href="files/report.pdf" download="Отчёт-2026.pdf">Скачать</a>
Ссылки mailto и tel
Контактные ссылки открывают почтовый клиент или приложение для звонков:
<a href="mailto:hi@site.ru?subject=Вопрос">Написать нам</a>
<a href="tel:+79990000000">Позвонить</a>
subject, body и прочие параметры передаются знаком ? после адреса.colspan и rowspan
Ячейки таблицы объединяются по строкам и столбцам:
<table>
<tr>
<th colspan="2">Объединённый заголовок</th>
</tr>
<tr>
<td rowspan="2">Радужка на две строки</td>
<td>право 1</td>
</tr>
<tr>
<td>право 2</td>
</tr>
</table>
Размер изображений для скорости
Скорость загрузки — часть вёрстки. Держите под контролем:
- Фото — WebP или JPEG про среднем качестве;
- Превью не больше 300–400 КБ;
- Ширина картинки не больше, чем блок, в который её ставят.
<img src="hero.webp" alt="Баннер" width="1200" height="500">
Картинка без файла: data URI
Маленькую картинку можно встроить прямо в атрибут — идеально для иконок и прелоадеров:
<img alt="Иконка"
src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24'><circle r='10' fill='%2338bdf8'/></svg>">
Редирект через meta refresh
Страница может «прыгнуть» на другой адрес без JavaScript:
<meta http-equiv="refresh" content="0; url=https://new-site.ru">
location.href. Для постоянных переносов предпочтителен серверный 301: он «склеивает» в поиске.video: autoplay, muted, loop
Встроенный плеер управляется атрибутами прямо в разметке:
<video autoplay muted loop controls>
<source src="bg.mp4" type="video/mp4">
</video>
muted обязательно.SVG прямо в HTML
Вектор вставляется тегом — это текст, который можно красить из CSS и анимировать:
<svg width="80" height="80">
<circle cx="40" cy="40" r="36" fill="#38bdf8"></circle>
</svg>
fill, stroke, переходы и hover работают как у обычного элемента.Favicon: иконка вкладки
Вкладка и закладки украшает маленькая иконка — её подключают тегом link:
<link rel="icon" href="favicon.ico" sizes="any">
<link rel="icon" type="image/svg+xml" href="favicon.svg">
CORS: доступ к чужим ресурсам
Загружать можно многое, но манипулировать чужими данными — только по правилам. О них вам скажут в консоли:
<!-- свои/простые ресурсы грузятся свободно -->
<img src="https://cdn.site.ru/logo.png">
<!-- чтение данных (fetch и др.) требует CORS-заголовков -->
fetch("https://api.other.ru/data");
Меню из списков
Классическая навигация строится на <ul> и <a> внутри <nav>:
<nav>
<ul>
<li><a href="/">Главная</a></li>
<li><a href="/blog">Блог</a></li>
</ul>
</nav>
list-style: none. Так и делают все меню мира.Query-параметры в ссылках
После ? передают данные между страницами — при фильтрах, поиске, пагинации:
<a href="/catalog?category=notebooks&page=2">Ноутбуки, стр. 2</a>
& — иначе часть параметра может потеряться при обработке.alt и семантика изображений
Текст alt важен и когда картинка не загрузилась, и для незрячих пользователей. Что писать:
<!-- Содержательные картинки: опишите смысл -->
<img src="diagram.png" alt="График роста продаж за год">
<!-- Декоративные: пустой alt -->
<img src="line.png" alt="">
alt="", а не пропуск. Пропущенный alt у скринридера превратится в «картинка» — шум. Фото рядом с названием в тексте можно писать и как alt="Фото кота".rel=nofollow: не передавать вес
Ссылка без «рекомендации» поисковикам — для недоверенных источников:
<a href="https://spam.ru" rel="nofollow">Источник</a>
rel=sponsored и rel=me
Пометки для рекламы и подтверждения авторства:
<a href="https://shop.ru" rel="sponsored">Партнёр</a>
<a href="https://github.com/me" rel="me">Мой профиль</a>
hreflang: язык цели
Подсказывает поисковику язык страницы, на которую ведёт ссылка:
<a href="https://en.site.com" hreflang="en">English</a>
Ссылка-заглушка: href="#"
Пока адрес неизвестен — но лучше явно предупредить:
<a href="#">Скоро</a> <!-- прыгает к началу -->
<a href="https://example.com" aria-disabled="true">Черновик</a>
Якорь к конкретному месту
Ссылка на любой элемент с id — не только «наверх»:
<a href="#reviews">К отзывам</a>
...
<section id="reviews">...</section>
Карта изображения: map и area
Разные ссылки на разных участках одной картинки:
<img src="map.png" alt="Карта" usemap="#m">
<map name="m">
<area shape="rect" coords="0,0,60,40" href="/north" alt="Север">
</map>
Картинка как ссылка
Изображение прекрасно работает внутри ссылки:
<a href="/product"><img src="watch.jpg" alt="Часы"></a>
Относительные пути: ./ и ../
Как найти файл относительно текущей страницы:
<img src="photo.jpg"> <!-- рядом -->
<img src="./img/logo.png"> <!-- в подпапке -->
<img src="../img/logo.png"> <!-- на уровень выше -->
Абсолютные пути
От корня сайта — со слеша, либо с полным адресом:
<img src="/img/logo.png">
<img src="https://cdn.site.ru/logo.png">
Таблицы: colgroup и col
Общие настройки целых колонок одним махом:
<table>
<colgroup>
<col style="background:#1e293b">
<col span="2">
</colgroup>
</table>
Таблицы: thead, tbody, tfoot
Смысловые части таблицы помогают и стилям, и скринридерам:
<table>
<thead><tr><th>Товар</th><th>Цена</th></tr></thead>
<tbody>
<tr><td>Хлеб</td><td>40 ₽</td></tr>
</tbody>
<tfoot><tr><td>Итог</td><td>40 ₽</td></tr></tfoot>
</table>
Скролл длинной таблицы
Оберните таблицу в контейнер — на узком экране появится прокрутка:
<div style="overflow-x:auto">
<table>...</table>
</div>
Таблицы: рамки-границы
Убираем двойные линии между ячейками:
table { border-collapse: collapse; }
td, th { border: 1px solid #334155; padding: 8px; }
VIDEO: постер и подгрузка
Картинка-заставка и стратегия загрузки:
<video controls poster="cover.jpg" preload="metadata"></video>
preload="none" экономит трафик, "auto" грузит сразу, "metadata" — только длительность и первый кадр.Субтитры: track
Подключаем файл субтитров к видео — доступность и иностранные языки:
<video controls>
<source src="movie.mp4">
<track kind="subtitles" src="ru.vtt" srclang="ru" label="Русский" default>
</video>
Несколько форматов видео
Браузер выберет первый поддерживаемый источник:
<video controls>
<source src="clip.webm" type="video/webm">
<source src="clip.mp4" type="video/mp4">
</video>
Запасной текст для видео
Если видео не поддерживается — покажется текст или ссылка:
<video controls>
<source src="clip.mp4">
Ваш браузер не умеет видео — <a href="clip.mp4">скачать файл</a>.
</video>
Аудио: форматы
Тот же принцип нескольких источников для звука:
<audio controls>
<source src="song.mp3" type="audio/mpeg">
<source src="song.ogg" type="audio/ogg">
</audio>
Встраивание: embed и object
Способы встроить внешнее содержимое, когда iframe не подходит:
<embed src="file.pdf" type="application/pdf" width="600" height="400">
iframe: песочница sandbox
Ограничиваем возможности встроенной страницы ради безопасности:
<iframe src="widget.html" sandbox></iframe>
sandbox блокирует скрипты и формы. Разрешайте только нужное: sandbox="allow-scripts".iframe: ленивая загрузка
Не грузить встроенную страницу, пока до неё не доскроллят:
<iframe src="map.html" loading="lazy"></iframe>
iframe: полный экран
Разрешение развернуть встроенное видео:
<iframe src="video.html" allowfullscreen></iframe>
iframe: подпись title
Каждый iframe нуждается в заголовке — его читает скринридер:
<iframe src="map.html" title="Карта офиса"></iframe>
srcset: выбор размера
Несколько версий картинки с дескрипторами ширины:
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
alt="Пейзаж">
sizes: сколько занимает место
Подсказка браузеру, какую версию выбрать под ширину экрана:
<img src="photo.jpg" alt="Фото"
srcset="p-400.jpg 400w, p-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 50vw">
picture: смена композиции
Разные картинки под разные экраны — art direction:
<picture>
<source media="(max-width: 600px)" srcset="vertical.jpg">
<img src="wide.jpg" alt="Баннер">
</picture>
Приоритет загрузки: fetchpriority
Главную картинку можно поднять в очереди:
<img src="hero.jpg" alt="Главная" fetchpriority="high">
Декодирование: decoding
Не блокировать отрисовку тяжёлой картинкой:
<img src="big.jpg" alt="Обзор" decoding="async">
img: crossorigin и реферер
Для работы с картинками из скриптов и приватности:
<img src="avatar.png" alt="Аватар" crossorigin="anonymous" referrerpolicy="no-referrer">
SVG: img или внутри HTML
Вектор двумя путями — выбор зависит от задачи:
<img src="icon.svg" alt="Иконка"> <!-- проще, кэшируется -->
<svg viewBox="0 0 24 24">...</svg> <!-- красится из CSS -->
Иконки для устройств
Favicon для вкладки и «яблочная» иконка на домашнем экране:
<link rel="icon" sizes="32x32" href="favicon-32.png">
<link rel="apple-touch-icon" href="apple-180.png">
Карточка для соцсетей
Отдельные теги для крупного превью:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Заголовок">
Open Graph: url и type
Дополняем карточку превью адресом и типом:
<meta property="og:url" content="https://site.ru/page">
<meta property="og:type" content="article">
Ссылка внутри ссылки
Вложенные <a> запрещены — браузер их разорвёт:
<!-- ТАК НЕЛЬЗЯ -->
<a href="/a">Текст <a href="/b">вложенная</a></a>
<!-- Вместо этого — две ссылки рядом -->
Мини-проект: страница визитка
Попробуйте собрать трёхстраничный мини-сайт. Простой вариант файловой структуры:
my-site/
├── index.html <!-- главная -->
├── gallery.html <!-- галерея -->
├── contacts.html<!-- контакты -->
└── images/
└── avatar.jpg
- На главной — заголовок, абзац и ссылка «Галерея».
- В галерее — три изображения в одну строку.
- В контактах — якорь вниз к блоку с
mailto:-ссылкой. - Между всеми страницами — взаимная навигация.
Ссылка как «прыжок»: что умеет a
Тег <a> — «переброс» на другой адрес: страницу, файл, раздел страницы или почту. Всё, что внутри ссылки, становится кликабельным.
<a href="about.html">О нас</a>
Адрес ссылки: href и его форматы
В href можно положить: путь к файлу, полный URL, якорь (#...), телефон (tel:) или почту (mailto:). Атрибут необязателен: ссылка без href — это «заглушка».
<a href="contact.html">Контакты</a>
<a href="https://mdn.io">MDN</a>
<a href="#top">Наверх</a>
Куда вести: относительные пути на практике
Относительный путь считается от текущего файла: about.html — соседний файл, img/logo.png — папка рядом, ../ — шаг «наверх» из папки. Редко источник битых ссылок начинается именно отсюда.
<!-- из /lessons/lesson-3.html -->
<a href="lesson-2.html">Урок 2</a>
<a href="../index.html">На главную</a>
../ из корня сайта «уходит» вверх мимо сайта — проверяйте, из какой папки считаете.Ссылка-файл: скачивание и атрибуты
<a> может отдавать файл: архив, PDF, отчёт. Атрибут download предлагает сохранить файл, а не открыть, и даже задаёт новое имя.
<a href="price.pdf" download>Прайс-лист (PDF)</a>
target: где открывать результат
Атрибут target выбирает окно: _self — текущая вкладка, _blank — новая. Для внешних сайтов часто используют _blank.
<a href="https://example.org" target="_blank">Сайт партнёра</a>
Ссылка на раздел страницы: якорь
Якорь — скачок к элементу по id: «#faq» приведёт на кусок страницы с id="faq". Часто используется в длинных статьях и оглавлениях.
<a href="#faq">К вопросам</a>
<section id="faq">...</section>
Почему ссылки не бывают «тут» и «жми»
«Подробнее тут» бесполезно и для кликов, и для поисковиков: непонятно, куда ведёт. Пользователь со скринридером часто «проходит по ссылкам» списком — такие тексты выглядят мусором.
<!-- плохо --><a href="...">жми здесь</a>
<!-- хорошо --><a href="...">Скачать прайс</a>
Ссылка «назад»: как делать правильно
«Назад в оглавление» важна на длинных страницах. Стек для неё простой: список ссылок по урокам с якорем наверх или в содержание файла.
<!-- весь раздел вправо, ссылка — в начало -->
<a href="table-of-contents.html#lesson-3">← К оглавлению</a>
Картинка-ссылка: a вокруг img
Оборачивая картинку в <a>, получаем кликабельное изображение: обложку статьи, логотип-домой, миниатюру.
<a href="article.html">
<img src="cover.jpg" alt="Обложка статьи«»">
</a>
Ссылка на почту: mailto
mailto: открывает почтовый клиент с заполненным адресом. Добавите ?subject=... — подставится и тема письма.
<a href="mailto:hello@site.ru">Написать нам</a>
<a href="mailto:hi@site.ru?subject=Вопрос%20по%20уроку">Вопрос по уроку</a>
Ссылка на телефон: tel
tel: на телефоне сразу «звонит», на компьютере — предлагает приложение. Номер пишут в международном формате.
<a href="tel:+74950000000">+7 495 000-00-00</a>
Ссылка на фрагмент другой страницы
Комбинация «путь + якорь» переводит на конкретное место чужой страницы: help.html#советы откроет help.html и проскроллит к id="советы".
<a href="help.html#faq-payment">Как оплатить — сразу к ответу</a>
Что происходит после клика: навигация
Клик по ссылке отправляет браузер по маршруту; сервер отвечает статусом. 200 — отлично, 404 — не нашли, 3xx — редирект («переезд»), 500 — ошибка сервера. «Редирект» — это не «сломалось», а договорённость о новом адресе.
URL, который понятен человеку: слаги
Пути вида /lessons/lesson-3.html — «человечные», в отличие от /p=42&id=7. Когда соберётесь в многостраничник, с самого начала делайте «говорящие» имена файлов и папок.
<!-- читаемо -->
/lessons/lesson-3.html
/lesson-3.html
<!-- не очень -->
/index.php?id=3&ref=utm_1
Меню из ссылок: список и навигация
Меню почти всегда состоит из списка ссылок, обёрнутых в <nav>. Так и семантика чистая, и «пункты» стилизовать легко.
<nav>
<ul>
<li><a href="index.html">Главная</a></li>
<li><a href="lessons.html">Уроки</a></li>
<li><a href="about.html">Обо мне</a></li>
</ul>
</nav>
Хлебные крошки: путь «домой»
«Хлебные крошки» показывает, где вы находитесь: «Главная → Уроки → Урок 3». Это набор вложенных ссылок, обычно с разделителями.
<nav aria-label="Хлебные крошки">
<ol>
<li><a href="index.html">Главная</a></li>
<li><a href="lessons.html">Уроки</a></li>
<li>Урок 3</li>
</ol>
</nav>
Оглавление в начале: якоря для длинного
Длинной статье нужно оглавление сразу после заголовка: список якорей «внутрь страницы». Это и навигация, и краткая выжимка содержания.
<nav aria-label="Содержание">
<ul>
<li><a href="#start">Что понадобится</a></li>
<li><a href="#steps">Пошагово</a></li>
</ul>
</nav>
Внешние ссылки: открывать или уводить
Внешняя ссылка ведёт на чужой сайт. Решение «новая вкладка или туда же» — вопрос удобства: чужие сайты обычно открывают в новой вкладке, чтобы не «потерять» посетителя. Уважайте выбор пользователя — предсказуемость важнее.
rel="noopener" — защита от «кражи» окна.Ссылка на mailto без спама: практика
Почта в коде «собирается» спамерами. Приёмы: писать адрес картинкой, «разбивать» @-символом на два слова, отдавать почту через форму. Начинайте с самого простого: показать адрес текстом и сделать телефон — звонить проще, чем писать.
Стилизация ссылки: стандартные состояния
Псевдоклассы ссылки: :link (обычная), :visited (посещённая), :hover (наведение), :focus (фокус с клавиатуры). Браузер уже дал стили по умолчанию — поправлять их будете в уроке CSS.
/* в следующем уроке */
a { color: #0b7285; }
a:visited { color: #5f3dc4; }
Ссылки и доступность: ошибки понимания
Цветом ссылка отличаться должна не только «в цвете»: при дальтонизме или фокус-навигации нужен подчёркивающий и/или hover-эффект. Смешивайте форму и цвет — так «кликабельность» видна всем.
Проверка битых ссылок: инструменты
Битые ссылки проверяются автоматически: браузерные плагины и консольные «линтеры» просматривают все href на проекте. Найденные 404 — это «мусор» среди ваших страниц, который видит и поисковик.
Изображение как ссылка: уточнение alt
Если картинка — это и есть ссылка, альтернативный текст должен описывать назначение перехода, а не «фотография кота». The alt на ссылке = подпись ссылки.
<a href="recipes.html">
<img src="pie.jpg" alt="Наши рецепты выпечки">
</a>
Ссылка-кнопка и кнопка-ссылка: разница
Ссылка «ходит по сайту», кнопка «делает действие»: отправка формы, отправка скрипта. Разметка разная (<a> против <button>), а выглядеть можно одинаково — хорошо, когда в CSS-урочил вы уже умеете.
Ссылка на «продолжение»: брежневый приём
Пагинация и «далее»: chunk-ссылки «следующая страница/следующий урок» удобны в конце контента. Их поддерживают поисковики (rel="next/prev" устарел, но «правильная» ссылка-контекст остаётся полезной).
<p class="next"><a href="lesson-4.html">Дальше: урок 4</a></p>
Изображение img: что под капотом
Тег <img> вставляет картинку: браузер запрашивает файл по адресу src и рисует его в потоке. Важно: у img нет содержимого — это «пустой» тег, закрывающего тега нет.
<img src="img/logo.png" alt="Логотип курса">
Пути к картинкам: относительные и полные
Картинки подключают теми же путями, что и ссылки: img/pic.png — рядом-файл, ../img/pic.png — выше. Полный URL подходит для внешних CDN, но у «своих» файлов держите локальные пути — сайт не зависит от чужой работоспособности.
<img src="image/photo.jpg" alt="Фото из проекта">
Рабочее место картинки: размеры по умолчанию
Без атрибутов картинка занимает столько места, сколько весит файл. Классы и CSS-правила зададут её размер позже; на старте привыкайте указывать width/height — это «резерв места» и защита от скачущего экрана.
<img src="ava.jpg" width="100" height="100" alt="Аватар">
alt: как писать полезный текст
alt — заменяет картинку для тех, кто её не видит: скринридер, поисковик, слабый интернет. Пишите «что важно» про картинку, а не «img src...». Назначение — это всегда мягкое описание содержания.
<!-- информативная -->
<img src="chart.png" alt="Диаграмма: рост продаж на 20% в июле">
<!-- декоративная -->
<img src="wave.png" alt="">
Форматы изображений одним взглядом
JPEG — фото с потерей качества, PNG — «прозрачность» и графика, WebP — современный компромисс «маленький/красивый», SVG — вектор-код для иконок и логотипов. GIF остался в прошлом, кроме анимаций.
Семейство srcset и picture: картинка на каждый экран
Тег <picture> и атрибут srcset позволяют отдавать разные файлы для разных ширин: телефон получит маленькую, десктоп — большую. Начало пути — добавить srcset с парой размеров на главных картинки.
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(max-width: 600px) 400px, 800px"
alt="Фото">
Фон или контент: когда CSS, а когда img
Если картинка — важная информация (фото товара, иллюстрация инструкции) — это <img> с alt. Если «декор» (кружок, градиент-«фон», узор) — это CSS-фон, alt не нужен.
<!-- контент: img + alt -->
<!-- декор: div с background в CSS -->
Ленивая загрузка: loading="lazy"
Атрибут loading="lazy" просит браузер не тянуть картинку, пока она не «подъедет» к видимой области. На длинных страницах это ощутимо ускоряет открытие.
<img src="gallery/3.jpg" loading="lazy" alt="Фото №3">
Картинка и текст рядом: базовый приём
Картинка «в строке с текстом» получается свойством CSS float/разметки, но на старте не хватайте иголку: просто ставьте img и текст один под другим, обёрткой-карточкой. Раскладку даст урок про CSS.
<figure>
<img src="hero.jpg" alt="Иллюстрация урока">
<figcaption>Пояснение под картинкой</figcaption>
</figure>
SVG: картинка-код
SVG — вектор, записанный текстом: иконка не «размывается» при любом размере и весит килобайты. Его можно класть прямо в HTML через <svg> либо подключить файлом.
<svg viewBox="0 0 24 24" width="24" height="24">
<circle cx="12" cy="12" r="10"/>
</svg>
Иконки: эмодзи, SVG или иконочный шрифт
Для декорирования списков чаще всего хватает эмодзи; для «значков-функций» (поиск, корзина) уместнее SVG. Иконочные шрифты живут в старых проектах. Любимое: эмодзи — быстро, SVG — правильно.
Подпись к картинке: история и данные
У картинок часто есть «пояснение»: источник, дата, автор. Кладите его в <figcaption>. Если подпись «плавает» отдельно — пересоберите: изображение и пояснение должны «ехать» вместе.
Галерея из картинок: заполнение in css
Галерея — список картинок, обычно с одинаковой миниатюрой. Разметка: <ul><li><img>... — и лёгкая CSS-сетка (см. урок 5–6). Каждая миниатюра — «ссылка на большую» или элемент «светового окна».
<ul class="gallery">
<li><img src="thumb-1.jpg" alt="Проект №1"></li>
<li><img src="thumb-2.jpg" alt="Проект №2"></li>
</ul>
Таблица: зачем вообще
Таблица выравнивает данные по строкам и столбцам: цены, расписание, характеристики, рейтинги. Её размечают в HTML, а выглядят «линии» благодаря CSS.
<table>
<tr>
<th>Формат</th>
<th>Цена</th>
</tr>
<tr><td>Курс</td><td>0 ₽</td></tr>
</table>
Основные теги таблицы: table, tr, th, td
<table> — сама таблица, <tr> — строка, <td> — «обычная» ячейка, <th> — ячейка-заголовок (по умолчанию жирная и по центру).
<tr> <!-- строка -->
<th>Урок</th> <!-- заголовок -->
<td>90 минут</td> <!-- данные -->
</tr>
<tr>, каждая ячейка — ровно <td>/<th>, порядок не путайте.Заголовок и подпись: caption
<caption> — название таблицы видимое глазом: «Таблица 3. Прайс на 2026 год». Помогает и людям, и скринридерам понять, о чём таблица.
<table>
<caption>Прайс на курсы</caption>
<tr><th>Название</th><th>Цена</th></tr>
</table>
<table>, до первой строки.Строки и ячейка-столбец: базовые действия
Данные «читаются» по строкам: каждая <tr> — это одна строчка. Столбцы складываются из ячеек «на одном месте»: так в каждой строке первая ячейка — первый столбец. Добавили ячейку — сдвинулись все «по этой позиции».
Логические части: thead, tbody, tfoot
У большой таблицы части: <thead> — шапка, <tbody> — данные (может быть много), <tfoot> — итог. Для стилей и скриптов это «разделённые зоны».
<table>
<thead><tr><th>Показатель</th><th>Январь</th></tr></thead>
<tbody>
<tr><td>Продажи</td><td>120</td></tr>
<tr><td>Заявки</td><td>98</td></tr>
</tbody>
<tfoot><tr><th>Прирост</th><td>22</td></tr></tfoot>
</table>
Объединение столбцов: colspan
colspan="N" растягивает ячейку на несколько столбцов — «заголовок на всю ширину», «общая ячейка итога».
<table>
<tr><th colspan="2">Платежи</th></tr>
<tr><td>Метод</td><td>Сумма</td></tr>
</table>
Объединение строк: rowspan
rowspan="N" — ячейка «вязка» через несколько строк: подпись одной клеткой сбоку или «промо-столбец».
<tr>
<td rowspan="2">Категория А</td>
<td>Первый пункт</td>
</tr>
<tr><td>Второй пункт</td></tr>
Согласование заголовков: scope
Атрибут scope говорит скринридеру, над каким столбцом «властвует» заголовок: scope="col" — столбец, scope="row" — строка. Для простых таблиц достаточно th без scope, но привычка ценна.
<tr><th scope="row">Цена</th><td>100 ₽</td></tr>
Ширина колонок: базовые правила
Колонки сами «подстраиваются» под содержимое. Не задавайте огромную width на каждую ячейку: достаточно пар общих «подписок» на колонку через CSS (см. 5 урок), а на старте — оставьте автоширину.
Горизонтальный скролл для тесной таблицы
Узкий телефон и широкая таблица — конфликт. Обёртка div с прогоняющимся скроллом держит таблицу, не ломая остальную страницу. Понадобится CSS overflow, о котором — в уроке 5.
<div class="table-wrap">
<table>... </table>
</div>
Таблица против вёрстки: когда что
Таблица — для данных. Раскладка страниц (колонки, сетки) — для CSS-флекса/грида. «Разметили страницу таблицей» — это legacy-музей: скринридер читает её как данные, а не как дизайн, и все «ячейки» выстраиваются не так, как планировали.
Таблица с доступностью: сводные правила
Правила за 30 секунд: caption — название, th со scope для «сложных» таблиц, alt-и только для «своих» картинок-в-таблице, не использовать «пустые» ячейки для отступов. Тогда скринридер расскажет таблицу «связно».
Практика: таблица цен
Соберите таблицу «тарифы»: столбец «Название», «Цена», «Фишки», строки «Старт/Про/Бизнес». Подписи через th, последнюю строку — выводом. Разметили? Теперь добавьте по предложению у каждого тарифа: таблица читается как программа.
<table>
<caption>Тарифы</caption>
<tr><th scope="col">Тариф</th><th scope="col">Цена</th></tr>
<tr><td>Старт</td><td>0 ₽</td></tr>
<tr><td>Про</td><td>490 ₽</td></tr>
</table>
Связанные разделы: перекрёстные ссылки
Ссылки «сложнее», чем навигация: свяжите «урок 3» с «уроком 2» фразой «вспомни списки — вот пример». Такие «перекрёстники» держат читателя на материале и помогают поиску связанных страниц.
<p>Списки-«меню» уже были в <a href="lesson-2.html#menu">уроке 2</a>.</p>
Текст ссылки: полный и ожидаемый
Текст ссылки должен почти точно повторять название пары назначения: «Таблица сравнения тарифов» ведёт на страницу с таким заголовком. Пользователя не удивите, поисковик не обманите.
<a href="prices.html#compare">
Сравнение тарифов
</a>
Навигация по урокам: «предыдущий/следующий»
В конце каждого урока прямая пара: «← Урок 2» и «Урок 4 →». Это ожидаемое продолжение пути и верный улучшатель «глубины просмотра». Разметьте так свои страницы уроков.
<nav aria-label="Навигация по урокам">
<a href="lesson-2.html">← Урок 2</a>
<a href="lesson-4.html">Урок 4 →</a>
</nav>
Всплывающая подсказка к картинке: title
Атрибут title на img показывает тултип при наведении. Это «больше деталей», а не замена alt: alt читается всегда, title — только при наведении. Дублируйте не всё, а важное.
<img src="city-map.jpg"
alt="Карта города"
title="Открыть в новом окне">
Практика: галерея с подписями
Сделайте галерею из четырёх картинок: список ul, в каждом li — figure с img и figcaption «название проекта». У каждой картинки — полезный alt. Результат обязан «читаться списком», а не «кучей img» при голом HTML.
<ul class="works">
<li>
<figure>
<img src="w1.jpg" alt="Сайт пекарни «Крендель»">
<figcaption>Пекарня «Крендель»</figcaption>
</figure>
</li>
</ul>
Практика: таблица расписания
Расписание — идеальная таблица: столбцы «День», «Тема», «Домашка». Строки — дни. Добавьте scope="row" для дней и scroll-обёртку под мобильные. Одна таблица — и вы применили половину урока.
<table>
<caption>Расписание недели</caption>
<thead><tr><th scope="col">День</th><th scope="col">Тема</th></tr></thead>
<tbody>
<tr><th scope="row">Пн</th><td>Ссылки</td></tr>
<tr><th scope="row">Вт</th><td>Картинки</td></tr>
</tbody>
</table>
Практика: страница-«ссылочник»
Полезные ссылки «со всего курса» — мини-раздел: список ul ссылок, сгруппированных по темам в details/summary. Заодно потренируете href, якоря и «читаемый текст ссылки».
Связанный контент внизу: «похожее»
Внизу статей «похожее» работает как миниатюры-карточки. Разметка — список из article-карточек: миниатюра-ссылка, заголовок-ссылка, пара слов. Не «мусорьте» карточками — три-четыре связанных записи хватает.
<section aria-label="Похожие статьи">
<h2>Читайте также</h2>
<ul class="related">...</ul>
</section>
Файл с картинками на диске: порядок
Имя файла — «кириллица?» лучше нет: ясные латинские имена и дефисы («lesson-3-pie.jpg»). Папка images/ — внутри урока, а не одна «просто картинки» на весь сайт без структуры.
Что такое «атрибут loading» ещё раз
Итог коротко: loading="lazy" — «тяни, когда понадобится», loading="eager" — тяни сразу (по умолчанию). Сначала термины странные, но это самая простая оптимизация картинок, доступная без сервера.
Нормальная структура «карточки»: мини-обзор
«Карточка» — частный случай: article (самостоятельность) + h3 (название) + img (иллюстрация) + p (описание) + a (подробнее). Применив это связно, вы почти профессионально структурируете контент.
<article class="card">
<img src="img/t-3.jpg" alt="Урок про ссылки и картинки">
<h3>Урок 3: ссылки и картинки</h3>
<p>Краткое описание.</p>
</article>
Итоги урока 3: что вы собрали
По итогам: ссылки (весь спектр href), картинки (src/alt/форматы/srcset/lazy), таблицы (table/thead/colspan/scope). Ваши страницы теперь связаны, иллюстрированы и структурированы данными. Дальше начнётся самое красивое — CSS: цвет, сетки, шрифты, анимации.
Путь против URL: разница в «системе»
URL — «полный адрес» в интернете: протокол + домен + путь. Путь — «дорога» внутри сайта: /images/photo.jpg. В ссылках чаще пишут путь, а URL приходит из «наружи» или соцсетей.
<a href="images/photo.jpg">фото</a> // путь
<a href="https://example.com/">сайт</a> // URL
Протокол-относительные ссылки: //путь
Ссылка вида //example.com/page пропускает протокол: браузер берёт текущий (http/https). Удобно на «двухпротокольных» сайтах, но в вашем коде лучше явно https — без неожиданностей.
href: «что указать» в ссылке
В href кладут: путь к файлу, полный URL, якорь, mailto/tel. Браузер «соберёт» из этого переход. Относительный путь значит «от текущей страницы», абсолютный — «от корня сайта».
Ссылка на скачивание с именем файла
Атрибут download подсказывает браузеру «качаем», а его значение задаёт имя сохраняемого файла. Идеально для PDF, архивов, шаблонов — вместо «открыть в окне».
<a href="kurs.pdf" download="Курс.pdf">
Скачать программу</a>
mailto: тема и текст письма
mailto может подставить тему и текст: mailto:mail@example.com?subject=Привет&body=текст. Аккуратно с «грузом» — длинный кодированный текст отпугивает.
<a href="mailto:hi@site.ru?subject=Вопрос">
Написать нам</a>
tel: международный формат номера
Ссылка на вызов пишется tel:+7... (с кодом страны, без пробелов). На телефоне откроется набор номера, на десктопе — приложение. Формат «международный» работает везде.
<a href="tel:+79000000000">
+7 900 000-00-00</a>
Якорь с переходом: файл#ид
Ссылка «на другую страницу и сразу к разделу»: href="manual.html#chapter2". Адрес состоит из пути и якоря через #. Полезно для «FAQ» и «справки».
<a href="help.html#billing">
К разделу оплаты</a>
Служебная «заглушка»: куда вести href="#"
href="#" — «заглушка» на время разработки: клик уводит «в никуда» (наверх страницы) и добавляет «#» к адресу. Лучше ставить «real» адрес сразу или вешать обработчик, чтобы не пугать пользователя.
Файловые ссылки: .pdf, .zip в href
Ссылка на файл (.pdf, .zip) скачать сработает «по умолчанию»: браузер откроет или загрузит его сам. Продумайте: документ открыть или скачать? Для скачивания используйте download.
Внешние и свои: с trusted-контекстом
Внешней ссылке «не надо верить» по умолчанию: она может «притащить» лишнее. rel="noopener noreferrer" обезопасит открытие в новой вкладке; для «своих» — обычные ссылки.
<a target="_blank"
rel="noopener noreferrer">
внешний сайт</a>
Картинка-превью: маленький размер, большой смысл
Превью — уменьшенная копия: thumbnail-версия картинки на карточке, а полная — по клику. Одна картинка, два размера, один замысел: «показать в обзоре, открыть в деталях».
<a href="big.jpg">
<img src="thumb.jpg" alt="Фото">
</a>
Изображение-спрайт: палитра для иконок
Спрайт — одна картинка с несколькими иконками; CSS «вырезает» нужную фоном. Один файл грузится быстрее N отдельных. Классика производительности для иконочных наборов.
<span class="icon icon-search"></span>
<span class="icon icon-user"></span>
Формат AVIF: претендент на сжатие
AVIF — формат из экосистемы AV1: сильное сжатие без заметных потерь. Поддержка растёт, но «старый» браузер увидит запасной формат. Ставьте в
Картинки «retina»: сколько пикселей нужно
Экран-retina плотнее: на «двукратном» дисплее картинка в 2 раза больше «логических» пикселей. Для чёткости давайте «2x»-размер через srcset. Тяжёлые «топ-картинки» — с расчётом.
<img src="photo.jpg"
srcset="photo@2x.jpg 2x">
Атрибут crossorigin у картинок
crossorigin позволяет браузеру «честно» обращаться к чужим картинкам (и для canvas, и для «правильного» кеша). Без него запрос «анонимный» и упасть может в специфичных сценариях.
Картинка в .webp: когда выбирать
WebP — «середнячок»: хорошее сжатие, широкая поддержка. Выбор: большая фотография → webp (или avif с fallback), «простые» пиктограммы → svg. Всегда с проверкой «как выглядит».
Галерея «легче»: ленивая загрузка каждого
В длинных галереях изображения «внизу» можно грузить по мере скролла: loading="lazy" на каждом. Первая «картинка» отдаётся сразу (lazy не для главной), а «остальные» — по касанию.
<img src="first.jpg" fetchpriority="high">
<img src="rest.jpg" loading="lazy">
Фокус-зона картинки: object-position
object-position выбирает, куда «смотреть» при кадрировании: «лучшее место» лица или продукта остаётся в кадре. «Классика» — кадрировать слева-top для «звёзд/слева».
.card-photo {
object-fit: cover;
object-position: center top;
}
«Изображение» SVG: документация внутри
SVG-файл — это код внутри разметки или файл .svg. Внутри можно вставить понятное описание (title/desc) — «текстовую» версию. Иконка, карта, график — «картинка-документ».
<svg role="img" width="100" height="100">
<title>Иконка дома</title>
<rect ... >
</svg>
Пиктограмма и иллюстрация: alt-разделение
Пиктограмма — «иконка-смысл»: ей довольно пустого alt. Иллюстрация — «картинка-повествование»: ей нужен alt с описанием. Различение определяет, что прочитает скринридер.
Таблица на телефоне: что делать
Узкая таблица на мобильном «ломается». Приёмы: горизонтальный скролл в обёртке, «карточки» из строк при <600px, или скрытие редко-нужных колонок по медиа-запросу. Начните со скролл-обёртки.
<div class="table-wrap">
<table>...</table>
</div>
Таблица-«характеристики»: размещение слева
Технические характеристики читаются «название — значение»: dh — термин, dd — значение. В таблице — тоже «слева тег, справа значение». Разметки: и dl, и table жизнеспособны; выбирайте по ширине контента.
<dl>
<dt>Диагональ</dt>
<dd>27 дюймов</dd>
</dl>
Видео-постер: кадр до воспроизведения
Атрибут poster показывает картинку-«стопкадр» до начала видео. Красивая обложка «приглашает» играть, а не «чёрный квадрат». Дайте постер — и источник «интриги» справится.
<video controls poster="cover.jpg">
<source src="movie.mp4">
</video>
Плеер без контролов: autoplay и controls
controls показывают кнопки; без них видео «молчит» и не имеет управления. autoplay без muted почти всегда блокируется. Решение: controls с «честным» постером — и никаких «некликабельных» плееров.
Звук «в фоне»: autoplay с muted
Фоновая музыка «сама собой» — прошлый век: и раздражает, и блокируется. Единственный автоплей, который браузер терпит, — muted. Любите звук — дайте экранную кнопку «включить».
Видео с переводом: track в действии
track приносит субтитры и перевод: каждый
<video controls>
<source src="lesson.mp4">
<track kind="subtitles" src="ru.vtt"
srclang="ru" label="Русские">
</video>
Субтитры: формат файла .vtt
WebVTT (.vtt) — «простые» субтитры: таймкоды и текст, строки вида 00:01.500 --> 00:04.000. Файл текстовый, его пишут руками или конвертируют из .srt. Кодировка — UTF-8.
WEBVTT
00:01.500 --> 00:04.000
Привет! Добро пожаловать.
Multi-формат: mp4, webm, ogg
Одно видео пишут в пару форматов: mp4 — «везде», webm — «легче», ogg — «старые». source перебираются браузером до первого «понятного». Правило: mp4 всегда «первым, если доступен».
<video controls>
<source src="v.mp4" type="video/mp4">
<source src="v.webm" type="video/webm">
</video>
Стоп-кадр: preload и «видео в ленте»
preload="none" говорит «не грузи видео до клика» — экономия в лентах. Когда нужен «первый кадр», прелоад metadata + постер. Время «тяжёлого видео» из главного потока — на паузу ответа.
SVG-анимация: маленький пример
Внутри SVG работают CSS-анимации и SMIL:
<circle r="20">
<animate attributeName="r"
values="20;25;20"
dur="2s" repeatCount="indefinite">
</circle>
OG-теги: полная карточка
Open Graph описывает, как сайт «выглядит» в мессенджерах и соцсетях: og:title, og:description, og:image, og:type, og:url. Заполните пять базовых — карточка по ссылке станет «живой».
<meta property="og:title" content="Уроки веб-разработки">
<meta property="og:image" content="cover.png">
og:title против title
title — «вкладка» и поиск. og:title — «карточка» в выдаче соцсетей. Совмещать можно, но og:title суше и «со смайлом» часто дружелюбнее. Не путайте: file name vs «витрина».
Иконки: apple-touch-icon
Apple-touch-icon — иконка для «домашнего экрана» iPhone/iPad. Файл 180×180, формат png. Без неё браузер «показывает» скриншот сайта. Мини-деталь «домашнего экрана».
<link rel="apple-touch-icon"
href="icon-180.png">
Web App Manifest: «иконка на главном экране»
Manifest (.webmanifest) делает сайт «приложением»: имя, иконки, цвета, стартовый URL. Ссылка через link rel="manifest". Установка «на экран» — «нативная» без «мобильных» браузеров.
<link rel="manifest"
href="manifest.webmanifest">
Мета-тег theme-color
theme-color «красит» адресную строку телефона в цвет бренда. Поддерживается не всеми, но где работает — даёт «фирменный» штрих. Мелко, а «приятно».
<meta name="theme-color" content="#1a73e8">
dns-prefetch: заранее разогретое подключение
dns-prefetch говорит браузеру «разреши DNS для домена заранее»: внешние шрифты, стоки картинок, аналитика — «первый перелёт» выигрывает. Ставьте на часто заменяемые «внешние» домены.
<link rel="dns-prefetch"
href="https://cdn.example.com">
preload: нужный ресурс раньше всех
preload «поднимает» ресурс в начало очереди загрузки: критический CSS, главную картинку, шрифт. «Тяжёлые», но нужные сразу — кандидаты; не «платите» всякой мелочи.
<link rel="preload" as="image"
href="hero.jpg">
Готовые «превью» сообщений: link-теги
Кроме OG есть «другие» campos превью: Twitter Card (twitter:card, twitter:title) и даже старые link rel="image_src". Заполняйте og + twitter-card — покрытие основным мессенджером.
<meta name="twitter:card" content="summary_large_image">
Проверка OG-карточки: инструменты
Готовую карточку проверьте: подменю «Share debugger» Facebook / «Card validator» Twitter. Вставьте URL — посмотрите, что «вытащит» отладчик и какие поля «пустые». Быстрая правка — и карточка «красивая».
Кэш и версии файлов: «?v=2»
«?v=2» в ссылке на ресурс «ломает» кэш старой версии: браузер скачает файл заново. Удобно при правках: поменяли css → поднимите «версию». На старине — автоматические «хэши» имён (gulp/webpack).
<link rel="stylesheet"
href="style.css?v=2">
Практика: навигация «в три уровня»
Соберите меню глубиной три: главный пункт, в нём подменю с подпунктами. Используйте вложенные списки и, если страниц много, — относительные пути. Проверьте все цепочки кликов.
<ul>
<li>Курсы
<ul>
<li><a href="html.html">HTML</a></li>
</ul>
</li>
</ul>
Практика: галерея с подписями и ссылками
Галерея где каждая картинка-превью ведёт на большую версию, а под ней — подпись figure/figcaption. «Клик-превью → большое → подпись». Это связывает картинки, ссылки и контент.
<figure>
<a href="full1.jpg">
<img src="th1.jpg" alt="Работа 1">
</a>
<figcaption>Первый проект</figcaption>
</figure>
Практика: страница-«линки» со всеми типами ссылок
Соберите «справочник ссылок»: на страницу, на файл, на якорь, в новую вкладку, mailto, tel, на скачивание. К каждому — комментарий в коде: «куда ведёт». Это ваш «линк-арсенал».
Практика: таблица расписания с объединениями
Расписание с «двойными» уроками: rowspan на объединение строк, colspan на объединение столбцов. Держите «логику» слияния в голове: видимая ячейка — «одна» логическая единица на 1–2.
<td rowspan="2">Физкультура</td>
<td colspan="2">Математика</td>
Практика: видео-страница с субтитрами
Страница с видео: заголовок, плеер (video+source+track), описание, транскрипт-текст под видео. Транскрипт — бонус доступности и SEO. Всё — без JS, на чистом HTML.
Чек-лист медиа-контента
Проверьте медиа: фото имеют alt и размеры; превью «ленивые», главная — «быстрая»; форматы — webp/avif с fallback; видео с постером и субтитрами; iframe с title; галереи «живые» на click. Прогнали — «медиа» в порядке.
Ошибки медиа: fileName без alt и sizes
Классика: картинка без alt, без sizes, без ленивости; видео без постара; iframe без title. Каждая ошибка ведёт к «неоптимальному»: доступности, скорости или загрузке «не на то».
Как читать «сетевую» вкладку для медиа
DevTools → Network показывает, что и сколько грузится. Ищите: «толстые» изображения в «первом экране», последовательность загрузки, «продублированные» ресурсы. Знание «веса» ловит десятки мегабайт экономии.
Доступность медиа: subtitles, alt, контраст
Медиа «для всех»: субтитры у видео, осмысленный alt у изображений, контраст текста поверх фото (плиточная плашка), кнопки-«слова» при иконках. Доступность медиа = «медиа понятен всем».
Итоги урока 3: «медиа-голос» вашей страницы
Ссылки, картинки, таблицы, видео/аудио, мета-соцсетей — «текстовая» и «не-текстовая» суть страницы собраны. Проверьте пятёрку своих страниц на чек-листе и выложите «медиа-визитку» на GitHub.
Что такое CSS на самом деле
CSS описывает, как выглядят элементы HTML: цвет, размер, отступы, раскладка. Отдельно от разметки — «одежда» для документа. Внешние стили подключаются через link, внутренние — через style.
Правило, свойство, значение
Правило состоит из селектора и блока: селектор «находит» элемент, внутри — пары свойство: значение. Каждое свойство «своё»: color, margin, font-size. Точка с запятой разделяет свойства.
p {
color: tomato;
margin: 10px;
}
Селектор тега: штамп на всех
Селектор тега красит «все» элементы с этим тегом: p — «все абзацы», a — «все ссылки». Удобно для базовых настроек: базовый цвет, шрифт. «Точечные» правки — классами.
Класс: метка для группы
Класс — «группа» элементов: .card красит все «карточки». Имя класса — ваше, строчными с дефисом. Один элемент может иметь несколько классов через пробел.
.card { border: 1px solid gray; }
id: единственный адрес элемента
id — уникальное имя элемента на странице: #header «достаёт» его одно. Используется для якорей и скриптов. Стили по id «перевешивают» классы — специфичность выше.
Специфичность: кто сильнее
Специфичность «взвешивает» селекторы: id > класс > тег. Что специфичнее — то побеждает. «Счёт» ведут по типам: больше id — сильнее. Поняв вес, перестанете «ругаться» с каскадом.
Порядок: последнее побеждает
При равной специфичности выигрывает последнее правило в потоке. Поэтому важен порядок подключения стилей: «частное» — после «базового». Переопределение — «позже = сильнее».
Каскад в трёх словах
Каскад — «кто выигрывает конфликт»: приоритет, специфичность, порядок. Сначала — источники, потом вес селектора, затем последовательность. Механизм один закон: побеждает «самый конкретный последний».
Комбинация через пробел: потомок
Пробел — «потомок внутри»: .menu a — ссылка где-то внутри .menu. Работает на любую глубину. Строже — «ребёнок» через знак >.
.menu a { color: blue; }
Группировка правил: запятая
Запятая перечисляет несколько селекторов в одном правиле: h1, h2, h3 — «одно стилизуем всё». Сокращает код и держит «общее» в одном месте. Разные теги — одинаковые стили.
h1, h2, h3 { margin-bottom: 12px; }
Наследование: что передаётся детям
Часть свойств наследуется: color, font-family, line-height — «уходят» потомкам. Другие — нет: margin, border, background. Настроите цвет на body — текст «внутри» унаследует.
Наследование через inherit и initial
inherit — «возьми у родителя», initial — «верни значение по умолчанию». Полезно, когда «своё» наследование сломано. Точечная «отмена» стилей — через initial + inheritance.
a { color: inherit; }
Сброс и нормализация стилей
Браузеры «по умолчанию» рисуют по-своему. reset «убирает» все стили в ноль, normalize «выравнивает» различия. Выберите «один» подход и подключите «первым» файлом.
Цвета в CSS: hex, rgb, слова
Цвет задаётся: #ff8800 (hex), rgb(255 136 0) (современный синтаксис), orа также «именованными» словами (tomato). Все они — одно и то же для браузера. Альфа-канал добавляет прозрачность.
Размеры: px, em, rem, проценты
px — «точки», фикс; em — «от родителя»; rem — «от корня»; % — «от контейнера». Для интерфейсов удобны rem (масштаб самого себя); em уместен в «локальных» компонентах.
Относительные единицы: vw, vh, ch
vw — «процент ширины экрана», vh — высоты; ch — «ширина нуля» (для шрифтов). Удобны для «полноэкранных» блоков и «мерной типографики». «Осторожно»: vw на «десктопе» может «сделать» широким.
Прозрачность: opacity и альфа
opacity «гасит» весь элемент вместе с текстом; альфа-канал цвета — «только цвет». Прозрачный фон + явный текст — через rgb(0 0 0 / 0.5). Выбирайте по нужному эффекту.
Комментарии в CSS: заметки в стилях
Комментарии пишутся /* текст */. Помечают «разделы» файла, объясняют «почему», «отключают» правила. Стили «читаются» кодом и «человеком» — комментируйте «намерения».
/* Шапка */
.header { ... }
Шорткаты: короткая запись нескольких свойств
margin: 10px 20px задаёт сразу четыре стороны; border: 1px solid black — три свойства. Шорткаты короче и «устойчивее». Но «пропуски» сбрасывают остальное — будьте внимательны.
Кастомные свойства: переменные CSS
Переменные CSS — значения «по имени»: --main-color: red; внутри :root. Используются через var(--main-color). Один «узел» — глобальный «запас»: смените в одном месте — обновитесь везде.
:root { --accent: #f80; }
.btn { background: var(--accent); }
Коробка вокруг элемента: box-модель
Каждый элемент — «коробка»: контент, внутри — padding, вокруг — border, затем — margin. Браузер «считает» размеры по этой схеме. Понимание «коробки» — база всей раскладки.
Padding: внутренний запас
padding — «воздух» между контентом и рамкой/краем. Четыре стороны своя: padding-top, -right и др. Шорткат: padding: сверху право снизу слева. Не спутайте с полем «снаружи» — margin.
.card { padding: 16px; }
Margin: внешний интервал
margin — «дистанция» до соседей: снаружи рамки. Вертикальный margin у блочных «схлопывается» (берётся больший). margin: 0 auto — «по центру». Понимание margin «спасает» раскладки.
box-sizing: border-box экономит мозг
По умолчанию размер «контентный»; border-box включает padding и border в width/height. С border-box «100%» — ровно «ширина блока». Один глобальный box-sizing — и размеры предсказуемы.
Ширина и высота: width и height
width/height задают размеры «коробки» (с учетом box-sizing). auto — «само по контенту»; фикс — «точное» число/%. Высота редко «нужна»: контент «растёт» сам.
Границы размера: min-width и max-width
min-width «не даёт» сжаться, max-width — «не даёт» разрастись. Классика: max-width: 960px; центрируется; контент «не перегорает» на широких экранах. «Эластичные» границы — лучше фиксаций.
Обводка outline: без влияния на размер
outline — «огранка» вокруг рамки, не занимающая места в коробке. Это «индикатор фокуса» по умолчанию. Не «убирайте» его совсем: оставьте «видимый» стиль фокуса для доступности.
Переполнение: overflow и его значения
Когда контент «больше» коробки — приходит overflow. visible — «вылезает»; hidden — «обрезает»; auto — «скролл по нужде». Прячет боковые «паузы» горизонтального скролла.
Центр по горизонтали: margin auto
Блоковый элемент в «свободной» ширине центрируется: margin-left: auto; margin-right: auto. Условие — больший контейнер. Текст внутри — text-align: center; отдельная история.
.wrap { max-width: 600px; margin: 0 auto; }
Единица измерения отступов: разумный выбор
Отступы «свои» единицы: rem для «масштабируемых», px для «пиксель-точных», % для «резины» в родителе. Единообразие в проекте — читаемость. Определите «меру» и придерживайтесь.
Шрифт: font-family и стек
font-family перечисляет шрифты «по цепочке»: если первого нет — берётся следующий. В конце — «запасной» класс: sans-serif. Имена с пробелами — в кавычках.
body { font-family: Arial, Helvetica, sans-serif; }
Размер шрифта: font-size и масштаб
font-size задаёт высоту букв. База браузеров — 16px. Настроили базу — и всё в rem масштабируется вместе. Не мельчите: основной текст комфортнее 16px и выше.
Жирность: font-weight и начертание
font-weight: 400 — нормаль, 700 — жирный, промежуточные — числами. bolder/lighter — относительно родителя. Жирность даёт акцент, но перебор делает текст «скомканным».
Курсив и наклон: font-style
font-style: italic — курсивный облик шрифта; oblique — «наклонённый» механически. Курсив у терминов и названий — классический приём. Но семантику выделения держит em.
Интервалы букв: letter-spacing
letter-spacing «разряжает» буквы: логотипы, акценты, заголовки. Малые значения — шик, большие — «сумасшедшая разметка». Разряженный «капс» читается хуже.
Расстояние между словами: word-spacing
word-spacing меняет промежутки между словами. Небольшие значения «дышат», большие — «рассыпают» строку. Применяется реже, чем letter-spacing; «дозируйте» осторожно.
Цвет текста и фона вместе
color — цвет букв, background-color — подложка. Эта пара отвечает за контраст: тёмное на светлом, светлое на тёмном. Настроена на блоке — текст наследует.
Оформление текста: text-decoration
text-decoration: underline, line-through, none. Ссылки по умолчанию подчёркнуты — узнаваемый сигнал. line-through — зачёркнутая старая цена. Оформление «линией» — аккуратное.
Выравнивание: text-align
text-align: left, center, right, justify. Заголовки по центру — торжественно; основной текст по левому — удобнее. justify выравнивает и вправо, и влево — возможны «дыры».
Высота строки: line-height
line-height — воздух между строками: 1.5 читается комфортно. Значение без единиц привязано к размеру шрифта. Заголовки «плотнее» (около 1.2), абзацы «воздушнее».
Фон блока: background-color
background-color красит подложку элемента. Прозрачный по умолчанию; можно с альфой: rgb(0 0 0 / 0.4). Фон «внутри» рамки, включая padding. «Пустое место» — тоже «покрашенное».
Фоновая картинка: background-image
background-image: url("путь") — картинка за элементом. По умолчанию «плитка» на весь блок. Хороша для «декора», не для «контента»: контентные картинки — через img.
.banner { background-image: url("header.jpg"); }
Повторение фона: background-repeat
background-repeat: repeat, no-repeat, repeat-x, repeat-y. Без no-repeat картинка «течёт» плиткой. Узоры — repeat; фото и баннеры — no-repeat.
Позиция фона: background-position
background-position двигает картинку в блоке: left center, 50% 50%, px. Удобно «поставить» баннер «по центру». Связка с no-repeat — точечная «установка» фона.
Размер фона: background-size
background-size: cover — «накрыть» весь блок, contain — «вписать целиком». Проценты и px — «свои» размеры. cover обрезает, contain оставляет «пустоты». Выбирайте по задаче.
Градиент фона: linear-gradient
linear-gradient(направление, цвета) — плавный переход. От «светлого к тёмному», из трёх цветов, поворотом. Градиенты «оживляют» кнопки и баннеры без картинок.
.btn { background: linear-gradient(180deg, #fff, #ddd); }
Рамка: border и её стороны
border: ширина стиль цвет — рамка вокруг элемента. Можно отдельно: border-bottom, border-left. Стили: solid, dashed, dotted. Рамки «участвуют» в размерах (box-border учтёт).
Скругление углов: border-radius
border-radius скругляет углы: 8px — «мягкие», 50% — «круг». У картинок и кнопок — «милое» лицо. Без radius — «резкие» коробки старого веба.
Тень блока: box-shadow
box-shadow: смещение-x смещение-y размытие цвет — «глубина» блока. Мягкие тени «поднимают» карточки. Не переборщите: «чёрная дымка» на каждом блоке — «грязный» вид.
Кадрирование медиа: object-fit
object-fit управляет «вписыванием» картинки/видео в рамку: cover — «заполнить», contain — «вся видна». Для img и video в «обложках». Не путайте с background-size: тут — «элемент» медиа.
Главное о display: block, inline, inline-block
display решает «поведение»: block — «весь ряд», inline — «в строке», inline-block — «в строке, но с размерами». Ссылки и strong — inline; p и div — block. Понимание display — база раскладки.
Скрытие: display none против visibility
display: none — «убирает» из потока (место освобождается); visibility: hidden — «прячет», но место остаётся. Для «вкладок» — display; для «тайной» метки — visibility. Выбор по поведению раскладки.
Позиционирование: static и relative
static — «по потоку» (по умолчанию). relative — «тот же», но сдвиг относительно «своего» места: top, left. Полезно для «прицела» абсолютного ребёнка и «тонких» смещений.
Абсолютное позиционирование: absolute
absolute вынимает элемент из потока и «привязывает» к ближайшему позиционированному предку. Положение — top/left/right/bottom. Меню-«выпадашки», иконки «по углу» — его дом.
Закрепление к экрану: fixed
fixed «прибивает» элемент к окну: скроллите — он стоит. Меню-«закреп», кнопки «наверх» — классика. Уточнение: внутри transform-предка fixed ведёт себя иначе.
Липкая шапка: position sticky
sticky «держится» в контейнере, а потом «прилипает» к краю экрана. Выгоднее fixed: не «вылетает» за границы родителя. Оглавление, шапки секций — его стихия.
Слои: z-index и контекст наложения
z-index «поднимает» элемент над соседями (работает с position/display). Больший — «выше». Контексты наложения создаются opacity, transform и др. — «внутренние» порядки «не лезут наружу».
Переполнение контейнера: overflow подробнее
overflow: visible/hidden/scroll/auto для «обеих осей»; overflow-x/y — по одной. auto показывает скролл «по нужде», scroll — «всегда». Горизонтальный «мусор» часто лечится hidden на родителе.
Центрирование: три классических способа
Текст — text-align: center; блок — margin: 0 auto; «по вертикали» — flex (align-items: center). Для «всего сразу» — flex на родителе. Три инструмента — все основные «центры».
Поток документа: как ложатся элементы
Элементы ложатся «потоком»: блочные — столбиком, строчные — строкой. position и float «вынимают» из потока. «Пайплайн» чтения страницы — это и есть поток. Управляете потоком — управляете вёрсткой.
Видовое окно: viewport на мобильных
Без мета-тега viewport мобильные браузеры «сжимают» страницу. <meta name="viewport" content="width=device-width, initial-scale=1"> — «правило» адаптива. С него начинается мобильная жизнь сайта.
Медиазапросы: min-width и max-width
@media (min-width: 768px) применяет стили «от 768px». min-width — «от», max-width — «до». Правила «договариваются» между брейкпоинтами: строчьте «лесенку» размеров.
@media (min-width: 768px) {
.cols { display: flex; }
}
Мобильный-first: от маленького к большому
Мобильный-first — сначала «узкие» стили, затем расширения для широких. Меньше переопределений, быстрее «база». Современный подход: базу пишем для телефона, «ширины» — дозами.
Гибкая сетка: проценты и flex
Процентные ширины «дышат» с контейнером; flex растягивает «вдогонку». Сетка-«резина» без «пиксельных» дублей. Комбинация: flex-wrap + min-ширины — «гибкие» ряды.
Изображения и отзывчивость
img { max-width: 100%; height: auto; } — картинка «не вылезет» из колонки. Высота авто сохраняет пропорции. «Шина» картинок — первый шаг адаптива медиа.
Брейкпоинты: где «ломать» вёрстку
Точки перелома — около «типичных» ширин: 480, 768, 1024, 1280. Лучше «по контенту», чем «по магии»: ломается строка — вот ваш брейкпоинт. Не плодите лишние «переломы».
Резина против отзывчивости
«Резина» — проценты: блок «растягивается-сжимается»; отзывчивость — @media: «меняет» раскладку по размерам. Совместно: «эластичная» основа + «изломы» по запросам. Полный адаптив — оба приёма.
Проверка на устройствах: инструменты
DevTools «телефоны» (toggle device) имитируют экраны; «эмуляция» и «реальность» близки. Проверяйте «свои» брейкпоинты и «повороты» (портрет/ландшафт). Быстрая «оглядка» — в DevTools.
Адаптив: принципы за пять шагов
1) viewport-мета; 2) базовые «узкие» стили; 3) img max-width; 4) flex-wrap-карточки; 5) @media «на изломах». Пять шагов — «скелет» адаптива любой страницы.
Шрифты на экране: масштаб и comfort
Мобильным текстом «16px+» — комфорт чтения без зума. Заголовки — не «гиганты» в угоду «вау». font-size в «единицах rem» масштабирует «в связке». Текст — первичен, размер — на службе.
Практика: цветовая схема страницы
Выберите «палитру»: акцент, основной, фоновый, текст. Задайте переменные в :root и «разложите» по странице. Одной правкой переменной «переоденете» сайт. Практика учит «системе цветов».
Практика: кнопка на чистом CSS
Соберите кнопку: padding, фон, скругление, тень, hover-эффект, :active «нажатие». Кнопка — мини-лаборатория box-model и псевдосостояний. Через час таких — «кнопочная» мускулатура натренирована.
Практика: карточка товара в стилях
Карточка: изображение (cover), название, цена, кнопка. Рамка, скругление, тень, padding. Плюс hover — «приподнять» карточку. Повторите три «экземпляра» в ряд — сетка начнёт работать.
Практика: меню с эффектами
Меню из ul>li>a: распределить в ряд, убрать маркеры, задать отступы. Hover — подчёркивание или «подсветку» пункта. Резина: wrap на узких экранах. Меню — «полигон» каскада и псевдоклассов.
Практика: тени и градиенты
Поиграйте «светом»: мягкая тень, радиальный градиент, «полупрозрачная» подложка. Настройте «своё» свечение/глубину на кнопках и баннере. Баланс: эффекты «по делу», а не «салют» на весь сайт.
Практика: стильная статья
Оденьте «чистую» статью: титул, подзаголовки, списки, цитату, ссылки. Крупный заголовок, воздух line-height, аккуратные подчёркивания. Цель — «красиво читается», а не «пестро». Это — «цивильное» CSS.
Практика: центрирование всеми способами
Сотрите: текст по центру, блок по центру, «и текст, и блок» в flex. Потом — «по вертикали» в фиксированной высоте. Четыре «центра» — четыре инструмента: выучите «когда какой».
Практика: галерея на flex-wrap
Галерея «превью»: flex-wrap + процентные ширины; на «узком» — один столбец. clip-safe: картинки object-fit cover. Перестройка «по ширине» — «живая» демонстрация адаптива.
Оценка стилей: чек-лист качества
Проверьте: единицы «согласованы»; переменные в «одном месте»; классы «по смыслу»; нет «воинственных» важностей; контраст ок. Пять пунктов — «быстрый» осмотр таблицы стилей.
Контрольная работа по уроку 3
Соберите «лендинг»: шапка, главный экран с фоном, карточки-преимущества, форма, футер. Адаптив через @media, палитра через переменные, без «голых» хаков. Контрольная «складывает» весь урок CSS.
Итоги урока 3: стили работают
Урок CSS «запустил» оформление: селекторы, каскад, box-модель, фоны, адаптив. Страницы получили «вид» и «отзывчивость». Дальше — тонкая типографика и шрифты.
Частые ошибки CSS: сборник
Классика: пропущенная точка с запятой, путаница id/class, «случайный» !important, фикс-высоты, забытый box-sizing. Каждая ошибка «лечится» пониманием каскада и boxmodelи. «Болевые точки» — в списке на память.
Дальше: тонкая типографика (урок 4)
Следующий шаг — шрифты и текст: гарнитуры, кегли, интервалы, «хороший» облик. Типографика «правит» страницей в глазах читателя. Урок 4 — «продолжение» одежды, но «для букв».
Закрепление: селекторы без подсказок
Восстановите «по памяти»: тег, класс, id, потомок, ребёнок, группировка, атрибут. Напишите по два примера «своих». Селекторы — «словарь» CSS: чем богаче словарь, тем точнее стили.
Домашнее задание: стиль профильной страницы
Оденьте «страницу-профиль» из урока 2: шапка, карточки, форма. Палитра в переменных, hover-эффекты, адаптив до 320px. Откройте на телефоне — «ходите» по брейкпоинтам. Задание объединяет уроки.
Каскад в реальности: ремонт «поломки»
Возьмите «сломанный» стиль: элемент «не такой». Включите DevTools — «Стили» покажет «виновника». Отключите правила по одному — «вычислите» конфликт. Реальный «ремонт» — лучший тренажёр каскада.
Инструменты CSS: DevTools и препроцессоры
DevTools — «прогон» стилей вживую; препроцессоры (SCSS) — переменные, вложенность, миксины. Начинающим достаточно «чистого» CSS + переменных. Препроцессоры — «удобство», не «магия»: база нужна.
Скорость CSS: вес и производительность
CSS-файл — «вес» и «рender»: селекторы не «глубинные», картинок не «тяжёлых». Осознанность: избегайте «мультяшных» вложенностей и «проценты» масштабов. «Лёгкий» CSS — «быстрый» рендер.
Семантика и классы: связка двух миров
Теги несут «смысл», классы — «стиль»: section «рассказывает», .card «одевает». Не «переименовывайте» смысл в классы (class="important-main"). Согласие двух миров — «чистая» система.
Заключение урока 3: вид имеет значение
Стили «оживили» семантику: страница заиграла цветом, формой, отзывами на действия. CSS — «следующий полёт» вёрстки. Урок 4 развернёт «букву» и «шрифт» — финальный штрих красоты.
Сетка «на» ровных колонках: repeat и «дышащий» ряд курсов
grid-template-columns: repeat(4, 1fr) — четыре «равные» колонки каталога. Практика: ряд курсов в 4 карточки. Скринридер «прочтёт» по DOM-порядку; визуально «плотно» и ровно. Не «плодите» колонки «сверх» нужды — на мобильном схлопывай. Проверка: gap «вместо» хаоса margin’ов. Доступность «сетки». Дисциплина «четвертей». Осмысленный «ряд» продуктов. Практика: align-items: stretch. Уважение к «колонке». Профессиональный «каталог». Гармония «ячеек». Чистый «ритм» ряда.
Центр «для глаза»: place-content и герой-блок
Герой-секция: display:grid; place-items:center; min-height:60vh — «взгляд» падает в центр. Практика: лендинг курса с главным сообщением. Скринридер «не» о геометрии, но «фокус» смысла ясен. Не «мучайте» «ручным» позиционированием. Проверка: по вертикали стабильно. Доступность «вступления». Дисциплина «центра». Осмысленный «акцент» лендинга. Практика: заголовок + подзаголовок + кнопка CTA. Уважение к первому экрану. Гармония «пятна».
Вакансия-карточка: <article> внутри <ul> поста
Список вакансий: <ul><li><article>…</article></li>… — «карточки» — «самостоятельные» единицы. Практика: кадры в ленте. Скринридер «пройдёт» по списку и «внутри» — по вакансии. Не «плодите» div-обёртки ради стилей. Проверка: article автономен в li. Доступность «ленты карточек». Дисциплина «одна вакансия — одна статья». Осмысленный «пост-кадр». Профессиональная «витрина вакансий». Уважение к «ряду».
Заголовок-«вынести» из сетки: order помнить про фокус
<h1> «не» «внутри» колонки? — «вынесите» семантически. Практика: заголовок над grid, «не» в flex-ряду «с» кнопкой. Скринридер «встретит» h1 «первым» в DOM-порядке. Не «переставляйте» визуалом (CSS order) так, чтобы чтение «прыгало». Проверка: Tab/чтение линейно. Доступность «порядка». Дисциплина «выноса» заголовков. Осмысленный «источник». Профессиональная композиция. Гармония «шапки».
Ссылка «в» контексте: <a> «с» точным именем в каталоге
Ссылка на товар: «Кроссовки Nike Air 42 размер» — полное имя. Практика: карточка товара. Скринридер «прочтёт» имя ссылки отдельно в «списке ссылок». Не «называйте» «подробнее» — «плодите» неоднозначность. Проверка: имена ссылок осмысленны сами по себе. Доступность «контекста». Дисциплина «имени». Осмысленный «переход». Профессиональная «ссылка-витрина». Уважение к списку ссылок. Гармония «навигации».
Изображение-«декор» в кнопке: aria-hidden на SVG
Иконка-стрелка «внутри» кнопки «Далее»: <svg aria-hidden="true" focusable="false"> + текст. Практика: кнопки-пагинации. Скринридер «прочтёт» «Далее», «не» споткнётся о декорацию. Не «вешайте» aria-label «на» пустую. Проверка: имя кнопки — текст. Доступность «иконических» кнопок. Дисциплина «тихих» декораций. Осмысленная «миниатюра». Профессиональная «кнопка-стрелка». Гармония «внутренних» значков.
Числа «в» таблице: выравнивание вправо для суммы
Таблица цен/остатков: числовые td text-align:right. Практика: бюджет, каталог с ценами. Скринридер «прочтёт» числа; выравнивание — «для глаза». Не «центрируйте» длинные числа. Проверка: колонка чисел читается «как» столбец. Доступность «сравнения сумм». Дисциплина «правого края». Осмысленная «колонка данных». Профессиональная «таблица». Уважение к цифрам. Гармония «ширины цифр».
Поле с подсказкой «снизу»: helper через small + aria-describedby
<small id="hint">Подсказка…</small> + aria-describedby="hint" на поле. Практика: пароль «8+ символов». Скринридер «прочтёт» подсказку после ввода. Не «плодите» шум: одна связанная подсказка. Проверка: фокус — подсказка озвучена. Доступность «контекста ввода». Дисциплина «помощи». Осмысленная «подсказка». Профессиональная «форма». Уважение к сомнению. Гармония «подсказок».
Состояние dotted: активный пункт «меню» тарифов
Карточка тарифа «выбрана»: aria-current="true" — «пункт». Практика: «Про» выделен в сравнении. Скринридер «прочтёт» состояние выбора. Не «красьте» только цветом без aria. Проверка: состояние озвучено. Доступность «выбора плана». Дисциплина «активного пункта». Осмысленный «акцент тарифа». Профессиональная «полка планов». Уважение к выбору. Гармония «сравнения».
Елка меток: связывание label "с" именем поля через for
<label for="email">Эл. почта</label><input id="email"> — «жёсткая» связь имя↔поле. Скринридер «прочтёт» название и «всё» поле. Практика: форма входа. Не «плодите» «пустые» for/id «без» цели. Проверка: клик по словам — фокус в поле. Доступность «имени» контрола. Дисциплина: один label на одно поле. Осмысленный «аккомпанемент» поля. Гармония «этикеток». Уважение к смыслу. Чистая «пара» имя-значение. Профессиональная «подпись».
Число у метки: порядковый «в» alt у nav точек каталога
Точки-индикаторы слайдера: <ol> «с» <li> и ссылками aria-label="Слайд 2 из 5". Практика: карусель-демо. Скринридер «прочтёт» и положение, «и» «сколько» всего. Не «прячьте» точки в «пустые» дивы. Проверка: имя «Слайд N». Доступность «пагинации» галереи. Дисциплина «счётчиков». Осмысленная «навигация» слайдов. Профессиональный «фильм-строк».
Основной контент «не» «в» div: <main> один на страницу
<main> — уникальный «центр» страницы. Практика: статья/каталог. Скринридер «прыгнет» в main по сочетанию (skip). Один main — на объекте. Не «вкладывайте» main «в» main. Проверка: навигация «вне» main. Доступность «мишени» контента. Дисциплина «главного». Осмысленный «фокус» страницы. Профессиональный «центр». Гармония «ядра».
Ячейка-«заголовок»: th со scope=col для колонок данных
<th scope="col">Прибыль</th> — этот заголовок «именует» колонку. Скринридер «привяжет» «при чтении строки» (чтение «знает» колонку). Практика: таблица отчёта. Не «забывайте» scope у смешанных таблиц. Проверка: заголовок «следует» за ячейкой. Доступность «шапки таблицы». Дисциплина «оси» th. Осмысленное «наименование» столбца.
Инлайн-контраст: <strong> акцент для скринридера
<strong> — «важность» автоматически усилена голосом. Практика: «Не пропустите: скидка до 30%». Скринридер «прочтёт» с интонацией выделения. Не «путайте» «b» (визуальная жирность) со «смыслом» strong. Проверка: содержание без CSS все равно «важно». Доступность «акцентов». Гармония «новостей».
Поле-пароль с «глазом»: aria-pressed на переключателе
Кнопка «показать/скрыть пароль» — aria-pressed «говорит» состояние. Практика: форма логина. Скринридер «озвучит» «нажато/не нажато». Не «двигайте» фокус неожиданно. Проверка: Tab после кнопки — в поле. Доступность «переключателя» видимости. Дисциплина «тумблеров». Осмысленное «состояние» кнопки.
Заголовок-«гнездо»: h2 + подзаголовок через hgroup
<hgroup><h2>Отчёт</h2><p>год спустя</p></hgroup> — пара «заголовок+подзаголовок». Практика: серия докладов. Скринридер «прочтёт» первый заголовок в навигации «заголовков». Не «дублируйте» подзаголовок в h3 «для» «красоты». Проверка: в дерево входит первый. Доступность «пары». Гармония «титулов».
Поле с «маской»: pattern и подсказка формата
<input pattern="[0-9]{5}"> — валидация по шаблону + aria-describedby к подсказке. Практика: индекс. Скринридер «прочтёт» и поле «и» подсказку в контексте. Не «полагайтесь» только на placeholder (исчезает). Проверка: сообщение об ошибке. Доступность «формата». Дисциплина «маски».
Ссылка «бе» художества: обводка фокуса у карточек-ссылок
Карточка-ссылка: <a> «внутри» article — stretched-link плюс outline. Практика: новости. Скринридер «найдёт» ссылку; фокус «виден». Не скрывайте «outline» финально. Проверка: Tab — кольцо «очерчивает» карточку. Доступность «зоны клика». Профессиональный «фокус» на блоке.
Числа «как» список: <ol> для последовательных шагов
<ol> «нумерует» шаги: Практика «Как оплатить» — 1,2,3. Скринридер «прочтёт» «первый шаг», «второй». Не «переделывайте» в «свой счёт» через CSS. Проверка: порядке важен для ol. Доступность «порядка операций». Гармония «гайда».
Кнопка «только» иконкой: aria-label обязателен
Кнопка с крестиком (закрыть): <button aria-label="Закрыть">×</button>. Скринридер «произнесёт» имя, «не» «корявый» символ. Не «полагайтесь» на title/тултип (не клавиатурен). Проверка: имя у кнопки есть. Доступность «иконических» кнопок. Дисциплина «меток».
Карточка «товара»: article + h3 + кнопка «корзины»
Карточка: <article><h3>Худи</h3><p>цена</p><button>В корзину</button>. Скринридер «прочтёт» «карточку» целиком как «статью». Практика: каталог. Не «распыляйте» на голые div. Проверка: названия продуктов — заголовки уровня 3. Гармония «витрины».
Прелоадер «шрифта»: <link rel=preload> до стилей
<link rel="preload" as="font"> — шрифт грузится «раньше» CSS. Практика: иконочный шрифт логотипа. Скринридер «не» о «загрузке», но «чёткие» буквы на старте. Не «прелоадьте» «всё» подряд (лимит соединений). Проверка: crossorigin обязательно у шрифтов. Доступность «визуальной» готовности. Дисциплина «критичного» ресурса. Осмысленный «приоритет».
Табличная «связка»: aria-labelledby «на» table со «скрытой» caption
<table aria-labelledby="t-title"> + <h2 id="t-title" class="visually-hidden">Доходы</h2> — имя таблицы вне caption. Практика: дашборд, где «имя» — заголовок секции. Скринридер «назовёт» таблицу. Не «дублируйте» имя в caption «и» aria-labelledby. Проверка: одно «имя». Доступность «легенды данных».
Кнопка «карусели»: пред/след «с» aria-label и «у» стрелки
Карусель: две кнопки «Назад»/«Вперёд» с aria-label. Практика: слайдер отзывов. Скринридер «прочтёт» «имя» — «не» «стрелку». Не «плодите» дубли «без» смысла. Проверка: фокус в кнопках; Tab-порядок. Доступность «вращения слайдов».
Ошибка «свёрнута»: <details> для «не»обязательной детали
<details><summary>Почему это важно?</summary>…</details> — разворачиваемое «пояснение». Практика: FAQ в форме. Скринридер «прочтёт» summary-кнопку, состояние «свёрнуто/развёрнуто». Не «прячьте» «критичный» контент за свёрнутым. Проверка: ответ доступен. Доступность «спойлера».
Состояние «в процессе» у кнопки: loading и анимация-«спин»
Кнопка «Отправить» при отправке: <button disabled aria-busy="true">Отправка…</button>. Практика: форма обратной связи. Скринридер «озвучит» busy? — «иногда», лучше aria-live «плюс» текст. Не «замораживайте» интерфейс молча. Проверка: повторный клик заблокирован. Доступность «ожидания».
Автозаполнение регионов: <datalist> для «названий» стран
<input list="regions">+<datalist id="regions"><option value="Москва">… — подсказки автокомплита. Практика: форма адреса. Скринридер «не» о datalist «всегда», но «ввод» удобен. Не «заменяйте» им «выбор» из списка (datalist «свободен»). Проверка: значение можно «ввести» любое. Доступность «умного ввода».
Оверлей «модалки»: <dialog> нативный «с» фокус-ловушкой
<dialog> — модальное окно нативно: showModal + закрытие Esc, фокус «внутри». Практика: подтверждение удаления. Скринридер «поймёт» модалку (роль dialog), фон — inert. Не «пишите» «свою» ловушку «без» нужды. Проверка: Tab не «уходит» из окна. Доступность «диалогов».
Аккордеон «чистый»: details+summary с фиксированной высотой
Контент «аккордеона»: <details>. Стиль «анимации» раскрытия — CSS transition «не» работает с height авто — обход через grid-template-rows. Практика: FAQ квартиры. Скринридер «услышит» расширяемое состояние. Не «прячьте» «нужное». Проверка: keyboard — Space. Доступность «свёрнутого» ряда.
Ссылка «на» файл: download + осмысленный текст «имени»
<a href="guide.pdf" download aria-label="Скачать руководство (PDF, 2 МБ)">Руководство</a>. Практика: материалы урока. Скринридер «прочтёт» «имя» «с» типом файла. Не «говорите» «нажми сюда». Проверка: размер и формат «в имени». Доступность «загрузок».
Инлайн-формула: <var> и курсив переменных
<var>x</var> + <sup>2</sup> — переменные «функции». Практика: лекция математики. Скринридер «прочтёт» как текст; скобки/степени — «через» разметку. Проверка: x² «не» «как» x2. Доступность «формул» (MathML — отдельно). Дисциплина «псевдо-степеней».
Результат «поиска»: отметка mark + синтаксис подсветки
<mark>вокруг «найденного» слова — «акцент» совпадения. Практика: страница результатов Google-подобная. Скринридер «не» «особо» о mark («просто» текст), но «глаз» видит. Не «подсвечивайте» «всё» — «только» совпадение. Проверка: контраст «маркера». Доступность «релевантности».
Метка «сдвоенного» поля: одна на серию, но for/id обе
<label>Телефон:</label> + поле «страны» и «номера» — две пары. Практика: регистрация. Скринридер «прочтёт» первую метку и «перейдёт» к полям по порядку. Не «оборачивайте» «обе» одним label (путаница). Проверка: каждая часть «имеет» имя. Доступность «разбитого» поля — сложнее; проще два поля.
Тёмная «кнопка» на светлом: контраст и текстура
Тёмная кнопка-CTA на светлом фоне: контраст текста к кнопке 4.5:1. Практика: «Начать курс» — чёрная на белом. Скринридер «не» о «красоте», но «читаемость» важна. Проверка: белый текст на #222 — ок. Доступность «тёмного акцента». Не «уводите» в «pitch-black» без «контраста».
Таблица «слайдеров»: ul точек пагинации с aria-label на li
Точки-индикаторы: <ul><li aria-current="true">… — «позиция» карусели. Практика: галерея. Скринридер «прочтёт» текущую; «соседние» — ссылки. Не «делайте» точки «недоступными». Проверка: aria-current «текущей». Доступность «индикаторов».
Поле «счет агрегата»: inputmode numeric и step отдельно
<input inputmode="numeric" pattern="[0-9]*"> — цифровая клавиатура для телефона. Практика: кол-во, код. Скринридер «не» о клавиатуре, но «ввод» удобен. Не «заменяйте» type=number «если» нужны «целые». Проверка: клавиатура цифр на мобильном. Доступность «быстрого ввода».
Сетка «на» псевдокнопке: ::before «фон» для «акцента»
Псевдо-украшение кнопки: <button class="accent"> — ::before имитирует «полосу» под текстом. Практика: CTA с подчёркиванием. Скринридер «не» о декоре (aria-hidden понимает? — `::before` не озвучивается). Не «кладите» смысл в псевдо. Проверка: текст кнопки осмыслен. Доступность «декоративных» линий.
Индексируемые списки: <ol> с таргет-«порядка» действий
<ol> для «шагов» инструкции; каждый <li> — этап. Практика: «Как записаться на курс». Скринридер «прочтёт» номера автоматически. Не «рисуйте» числа вручную. Проверка: последовательность «ясна» без CSS. Доступность «нумерации».
Поле «имя» с подписью: label первой строкой, подсказка — второй
label «Имя» + <small> подсказка «как в паспорте». Практика: аккаунт. Скринридер «свяжет» через for/id + aria-describedby. Не «используйте» placeholder как label. Проверка: фокус — имя озвучено. Доступность «меток».
Карусель «без» автоплея: пользователь ведёт
Управляемая карусель: кнопки «Вперёд»/«Назад» и «точки». Практика: отзывы. Скринридер «прочтёт» слайд «по» фокусу; автоплей «мешает». Не «автопрокручивайте» контент — «дороже» чтение. Проверка: пауза при фокусе. Доступность «контроля».
Сводка «и» деталь: <details> вокруг «таблицы»-спойлера
<details><summary>Смотреть данные</summary><table>… — «раскрываемая» детализация. Практика: отчёт. Скринридер «прочтёт» summary, «развернёт» по Enter. Не «прячьте» «нужное» за свёрнутым. Проверка: таблица доступна. Доступность «скрытых данных».
Загрузка «файлов»: <input type=file> с большим label-дивом
<label class="drop"><input type="file" class="visually-hidden">…</label> — «зона перетаскивания». Практика: загрузка аватара. Скринридер «найдёт» контрол по label. Не «делайте» «кликабельным» div без роли. Проверка: фокус + Enter открывает диалог. Доступность «загрузки».
Видео «постер»: poster + <img> запасной для старого
<video poster="intro.jpg"> — обложка до воспроизведения. Практика: лекция. Скринридер «не» о постере, но «кадр» — «информация». Не «полагайтесь» на видео «для» смысла — транскрипт. Проверка: текст описания рядом. Доступность «медиа».
Чекбокс «согласия»: label + ссылка на оферту «внутри»
label «Я принимаю »+<a href>условия</a>. Практика: регистрация. Скринридер «прочтёт» чекбокс и «ссылку». Не «разрывайте» связанный текст. Проверка: фокус идёт по обоим. Доступность «юридического» согласия.
Ссылка-метка «этапа»: <a> «в» аккордеоне-степе
Прогресс-степы: <ol><li><a href="#step1">Корзина</a>… — «якорная» навигация мастера. Практика: оформление заказа. Скринридер «прочтёт» этапы как ссылки. Не «делайте» «неактивный» шаг «недоступным». Проверка: aria-current «на» текущем. Доступность «мастера».
Отображение «кода»: <pre><code> с aria-label на копию
<pre><code>блок кода</code></pre> + кнопка «Копировать». Практика: примеры в уроке. Скринридер «не» «прочтёт» CSS «красиво», но «код» — текст. Не «прячьте» «копию» без имени. Проверка: label у кнопки. Доступность «сниппетов».
Кнопка внутри <form> «сверху»: поиск сразу «у» шапки
Форма поиска в шапке: <form role="search"> + поле + кнопка «Найти». Практика: сайт курсов. Скринридер «найдёт» ориентир search; Enter — отправка. Не «забывайте» label (aria-label="Поиск"). Проверка: фокус лёгкий. Доступность «быстрого поиска».
Тумблер «бургера»: aria-expanded на кнопке меню
<button aria-expanded="false">Меню</button> — телmenu-«переключатель». Практика: мобильная навигация. Скринридер «озвучит» состояние меню. Не «меняйте» имя кнопки «без» смысла. Проверка: aria-expanded истинному состоянию. Доступность «раскрытия».
Иконка «звука» у ошибки: role="img" aria-label с ясным текстом
Иконка-«восклицание» перед сообщением: <span role="img" aria-label="Ошибка">. Практика: поле с ошибкой. Скринридер «прочтёт» «Ошибка, затем текст». Не «дублируйте» aria-label «если» текст рядом. Проверка: сообщение озвучено. Доступность «алертов».
Пагинация «широкая»: lots of <a aria-label> для дальних страниц
<nav aria-label="Пагинация">: страницы + «Вперёд». Практика: каталог из 100 курсов. Скринридер «прочтёт» ссылки по именам. Не «оголяйте» «край». Проверка: aria-current="page" на текущей. Доступность «перемещения по каталогу».
Заголовок «таблицы данных»: caption или aria — две стратегии
caption «видимая» подпись таблицы «в» DOM. Практика: отчёт. Скринридер «прочтёт» caption перед данными. Не «используйте» и caption, и aria-labelledby «разом» (дубль). Проверка: выбрать одно. Доступность «подписи данных».
Ярлык «выбранного» фильтра: aria-pressed на чипсах
Чипс-фильтр «Активный»: <button aria-pressed="true">. Практика: фильтр категорий товара. Скринридер «прочтёт» состояние нажатия. Не «плодите» «вкл/выкл» без aria. Проверка: Tab — цикл; Space — переключение. Доступность «чипсов».
Подсказка «под» полем: <small> + aria-describedby на пару значимых
<small id="hint">Только буквы</small> + aria-describedby. Практика: имя. Скринридер «прочтёт» поле, затем подсказку. Не «навешивайте» «всё» подсказки — шум. Проверка: одна осмысленная помощь. Доступность «контекста ввода».
Ссылка «целой» карточки: <a> stretched + фокус на весь блок
<article class="card"><a class="stretched" href="#">Заголовок</a></article> — «клик» по всей карточке. Практика: новости. Скринридер «прочтёт» ссылку «Заголовок»; клик — вся зона. Не «плодите» ссылки «внутри» stretched. Проверка: фокус виден. Доступность «карточек».
Заголовок «навыка»: <h3> в списке карточек компетенций
Карточка навыка: <h3>HTML</h3> + описание. Практика: страница «что умею». Скринридер «прочтёт» заголовок в навигации. Не «пропускайте» уровни. Проверка: h2 → h3 линейно. Доступность «иерархии».
Числа «с» подписью: data-атрибут — не «смысл» без текста
<td data-label="Цена"> не «видна», а «имя» — атрибут не несёт доступности. Практика: мобильная таблица. Скринридер «не» о data-атрибутах «в» чтении контента. Не «понимайте» их как «скрытую» семантику. Проверка: aria-метки где надо. Доступность «данных».
Поле «поиска» с «лупой»: aria-label и роль search
<form role="search"><input aria-label="Поиск по сайту"> — «лупа»-иконка. Практика: шапка. Скринридер «назовёт» поле «Поиск». Не «прячьте» label в placeholder. Проверка: имя озвучено. Доступность «поиска с иконкой».
Списки «компетенций»: <dl> для свойств-значений навыка
<dl><dt>Уровень</dt><dd>Продвинутый</dd> — «пары» свойство-значение. Практика: CV. Скринридер «прочтёт» пару как определение. Не «используйте» таблицу для «ключ-значение» контента. Проверка: dt/dd связаны. Доступность «характеристик».
Активная «вкладка»: role=tablist + aria-selected правильно
Вкладки: <div role="tablist"> + кнопки role="tab" aria-selected. Практика: «Описание»/«Отзывы». Скринридер «прочтёт» состояние выбора. Не «используйте» role=tab без JS-поведения (стрелки). Проверка: фокус на активном. Доступность «вкладок».
Ошибка «поле»: aria-invalid связь с сообщением
<input aria-invalid="true" aria-describedby="err">+<span id="err">. Практика: валидация формы. Скринридер «прочтёт» «ошибка» при фокусе. Не «красный» один — текст обязателен. Проверка: сообщение осмысленно. Доступность «обратной связи».
Заголовок «статьи» за кадром: <h1> скрытый, но «в» DOM
<h1 class="visually-hidden"> — имя страницы «для» навигации. Практика: лендинг с «epic» hero без видимого заголовка. Скринридер «найдёт» h1 в списке. Не «убирайте» заголовок «совсем». Проверка: aria-навигация по заголовкам. Доступность «имени страницы».
Чекбокс «не все согласны»: роль-смешанное состояние
Чекбокс «выбрать все» с aria-checked="mixed" — «частичное» состояние. Практика: таблица с чекбоксами. Скринридер «прочтёт» «смешанное». Не «подделывайте» indeterminate без aria. Проверка: состояние честное. Доступность «группового выбора».
Ссылка «звук»: <audio> с controls и aria-label на плей
<audio controls aria-label="Урок 3: аудио"> — плеер. Практика: подкаст. Скринридер «прочтёт» имя плеера. Не «прячьте» controls (без них «не» воспроизвести). Проверка: кнопки доступны. Доступность «аудио».
Мини-форма «в» карточке: <form> на «одно» действие
Карточка товара со «в» корзину: <form><label>Кол-во</label><input type=number><button>. Практика: store. Скринридер «прочтёт» форму. Не «плодите» «вложенные» формы. Проверка: один form на действие. Доступность «мини-контролов».
Инлайн-секция «факта»: <blockquote> с cite для источника
<blockquote cite="…"> цитата + <cite> автор. Практика: отзыв клиента. Скринридер «прочтёт» собственно цитату и «автора». Не «путайте» blockquote с «отбивкой текста». Проверка: cite-ссылка валидна. Доступность «цитирования».
Подпись «фото»: figure + figcaption «как» легато-метка
<figure><img alt="…"><figcaption>Подпись</figcaption> — «пара» картинка-подпись. Практика: галерея. Скринридер «прочтёт» alt и подпись. Не «дублируйте» alt в figcaption (шум). Проверка: подпись осмысленна. Доступность «подписей».
Поле «купон» на кассе: скидка «в» форме — <input>+кнопка «Применить»
<label>Промокод</label> + поле + «Применить». Практика: корзина. Скринридер «прочтёт» пару. Не «пишите» «скидка» мёртвым «текстом» без обновления. Проверка: статус «применён/неверен». Доступность «промо».
«Ломаный» рейтинг «в» звёздах: role="img" aria-label="4 из 5"
★★★★☆ + роль-картинка. Практика: обзоры курсов. Скринридер «прочтёт» «4 из 5 звёзд». Не «дублируйте» «в» текст рядом. Проверка: цвета не «нужны». Доступность «рейтинга».
Переключатель «светлой» темы: prefers-color-scheme + кнопка «в» DOM
Кнопка «Тёмная тема» + aria-pressed. Практика: переключение. Скринридер «прочтёт» состояние. Не «программируйте» «сложность» без пользы. Проверка: сохранение выбора. Доступность «тем».
Ссылка «на» почту с «темой»: mailto: + subject «через» URL-encoding
<a href="mailto:help@site.ru?subject=Вопрос%20по%20уроку"> — тема «заранее». Практика: форма «написать». Скринридер «прочтёт» имя ссылки «Написать в поддержку». Не «добавляйте» «и» тело «гигантское». Проверка: почта открывается. Доступность «контакта».
Заголовок-повторение? «Нет»: у артикула «в» карточке «не» надо h каждый раз
Карточка: <h3> названия «достаточно»; «артикул», «цена» — «p/span». Практика: витрина. Скринридер «прочтёт» h3 и детали «в» потоке. Не «лепите» «заголовок» на «каждую» строчку. Проверка: h-уровни «не» «скачут». Доступность «плотности».
Кнопка «поделиться» в соцсети: ссылка-«шаре» с осмысленным aria-label
💡Кнопка-шеринг (VK, Telegram) — ссылки (без формы) + aria-label="Поделиться в ВК". Практика: статья. Скринридер «прочтёт» целевое соц-имя. Не «делайте» иконку «без» слов. Проверка: имя ссылки ясно. Доступность «шаринга».
Псевдо-логика «в» CSS: :checked «выглядит» выбранным в кастом-чекбоксе
Стилизация радио/чекбокса: appearance:none + :checked → «фон+галка». Практика: набор фильтров. Скринридер «не» о визуале, но «состояние» DOM честное (aria-checked). Не «прячьте» «нативный» вид без «полного» кастома. Проверка: фокус виден. Доступность «кастом-галки».
Иконка «уведомления» в шапке: кнопка + aria-label
<button aria-label="Уведомления, 3 новых">🔔</button> — счётчик внутри. Практика: лента. Скринридер «прочтёт». Обновите aria-label при изменении. Проверка: число в имени. Доступность «колокольчика».
Таблица «с» длинным контентом: <th> scope + <caption> «как» имя
Результаты спринта: <caption>Итоговые баллы</caption>. Практика: таблица успеваемости. Скринридер «прочтёт» подпись «перед» данными. Проверка: scope у заголовков. Доступность «данных».
Ссылка «на следующий урок» в конце: <nav aria-label="Уроки"> rel="next"
<a href="lesson-3.html" rel="next" aria-label="Следующий урок: Флексы"> →. Практика: линейный курс. Скринридер «прочтёт» имя. Проверка: rel=next у «вперёд». Доступность «цепочки».
Поле «Год» и <select> «дискретность»: aria-метка как число
<label for="year">Год рождения</label> + select с 1990–2010. Практика: регистрация. Скринридер «именует» селект. Проверка: порядок «возрастает». Доступность «года».
Карусель «review»: <figure> + <figcaption> автор «в» слайде
<figure><blockquote>«Отличный курс»</blockquote><figcaption>— Анна, дизайнер</figcaption>. Практика: лендинг-отзывы. Скринридер «свяжет» цитату с автором. Проверка: порядок тело-подпись. Доступность «отзыва».
Слайдер «цены»: <input type=range> + <output> с aria-live
Диапазон фильтра цены: <input type=range min=0 max=50000 step=500> + <output aria-live="polite">. Практика: каталог. Скринридер «озвучит» значение. Доступность «диапазона».
Поле «поиска» + datalist: «города» с подсказками
<input list="cities"> + <datalist id="cities">. Практика: форма доставки. Скринридер «прочтёт» поле, подскажет список. Не «дублируйте» label. Проверка: выбор «свободен». Доступность «локаций».
Заголовок «свет»-секции и aria-labelledby к ней
Секция «Наши преподаватели» <section aria-labelledby="teachers"> + <h2 id="teachers">. Практика: команда. Скринридер «назовёт» регион. Проверка: id уникален. Доступность «секции».
Мини-навигация «прогресса»: <progress> + aria-label
<progress max="100" value="40" aria-label="Прогресс курса">. Практика: панель пользователя. Скринридер «прочтёт» значение в процентах. Проверка: max не забыт. Доступность «прогресса».
Аккордеон FAQ <details>: summary «имя» вопроса
<details><summary>Что входит в курс?</summary><p>…</p>. Практика: FAQ. Скринридер «прочтёт» вопрос и развернётся. Проверка: Tab — фокус на summary. Доступность «аккордеона».
Колонки «признаков»: <ul> двумерный — не надо, «лучше» grid-section
<section><ul class="features"> в grid на «десктопе». Практика: преимущества. Скринридер «прочтёт» список «как» список «в» DOM-порядке. Проверка: flex-колонки «не» ломают «поток». Доступность «сеток».
Псевдокласс :focus-within для «карточки с кнопкой»
.card:focus-within { outline:… } — фокус «в» любом элементе карточки виден на «внешней» рамке. Практика: карточки-товара. Скринридер «не» о визуале, но «глаз» «найдёт». Проверка: фокус на кнопке — граница карточки «осветилась». Доступность «зоны».
Ссылка «на детальную статью» из preview: карточка-статья с h3
<article><h3><a href="#">…</a></h3><p>анонс</p><p><a href="#">Читать→</a></p>. Практика: блог. Скринридер «прочтёт» заголовок-ссылку. Проверка: «Читать» не «пустой». Доступность «превью».
Поле «Тема» со «списком» datalist: «раздел» обращения
<input list="topics"> «Причина обращения: Оплата» — подсказка. Практика: обратная связь. Скринридер «прочтёт». Проверка: label ясен. Доступность «тикет-тем».
Компетенции «с» прогрессом «в» профиле: <ul> + role="meter" «через» <progress>
<li><label>HTML</label><progress max=100 value=85 aria-label="HTML: 85%">. Практика: профиль студента. Скринридер «прочтёт». Проверка: имя у каждого. Доступность «навыков».
Кнопка «у» поля «пароля» в группе «глаз»: aria-pressed + aria-controls на input
<div><input type=password id=pw><button aria-pressed=false aria-controls=pw>👁</button></div> — aria-controls «связь». Практика: вход. Скринридер «прочтёт». Проверка: фокус на кнопке. Доступность «пароля».
Строка-«промо» у формы: <p> c aria-hidden «и» SVG «баннер»
Баннер-«скидка» над формой: <p class="promo">🔥 −15%</p>. Практика: ранняя пташка. Скринридер «прочтёт» текст «−15%»; «огонёк» — deco. Проверка: имя ясно. Доступность «акций».
Чекбокс «вариант» в карточке: <label> стоит «рядом» с <span> текстом
Карточка-«выбор тарифа» с чекбоксом: <label><input type=checkbox><span>…«10 уроков»</span></label>. Практика: бандл. Скринридер «свяжет». Проверка: фокус. Доступность «бандла».
Счётчик «символов» в textarea: <output> + aria-live polite на остаток
<textarea maxlength=200> + <output aria-live="polite">200 осталось. Практика: отзыв. Скринридер «услышит» обновление. Не «кричите» assertive. Проверка: остаток корректен. Доступность «лимита».
Лайк-кнопка «сердце»: aria-pressed + «счётчик» в aria-label
<button aria-pressed=false aria-label="Лайк: 12">♥</button>. Практика: урок-галерея. Скринридер «прочтёт» состояние «и» число. Проверка: имя осмысленно. Доступность «лайка».
Прогресс «скролла статьи»: <progress> + aria-live только «на» вехе
Прогресс-бар «чтения»: обновляется «в» JS; aria-live polite «на» «Прочитано 50%». Практика: лонгрид. Скринридер «услышит» вехи. Не «сканьте» на каждый пиксель. Проверка: «сообщение» осмысленно. Доступность «чтения».
Меню «в» шапке на мобильном: details+summary «скрывает» пункты
<details><summary>Меню</summary><nav>…</nav></details> — бургер «без» JS. Практика: адаптив. Скринридер «раскроет» summary. Проверка: фокус «внутри». Доступность «бургера».
Псевдо-сайт-«визитки»: binding «имя и должность» через dl в footer
<dl><dt>Автор</dt><dd>Иван</dd>… в <footer>. Практика: подвал. Скринридер «прочтёт» пары. Проверка: «семантика» пары. Доступность «контактов».
Энтузиазм «заголовка» лонгрида: <h1> + <time> рядом «не» в h1
<h1>Полное руководство</h1><time>…</time> — дата «вне» заголовка. Практика: статья. Скринридер «сначала» h1, «потом» дату. Проверка: порядок. Доступность «публикации».
Карточка «урока» как <li>: серия с «порядковым» тайтлом
<ul><li><article><h3>Урок 1: Основы</h3>… или «Урок 1» + <time> м. Практика: курс-ветка. Скринридер «прочтёт» «порядок». Проверка: «номера» честные. Доступность «серии».
Инлайн-«смайл» как метка состояния в таблице: aria-label
<td aria-label="Доставлено">✅</td> — «эмодзи» - декорация. Практика: статус заказа. Скринридер «прочтёт» aria-label, «не» «смайл». Проверка: имя у ячейки. Доступность «статусов».
Заголовок «урока» «в» продающем списке: <ol> + «у» каждого <li> своё h3 «для» имени темы
<ol> «нумерует» уроки; внутри <li> — <h3> «Тема 1: Основы»</h3>. Практика: программа курса. Скринридер «прочтёт» «урок 1, тема…». Проверка: порядок честный. Доступность «программы».
Кнопка «снять выделение» у «цвета» фильтра: aria-pressed на «пипетке»
<button aria-pressed="true">🎨 Цвет: синий ✓</button>. Практика: каталог обоев. Скринридер «прочтёт» состояние. Проверка: имя = цвет. Доступность «пипетки».
Число «книг» «в» читалке: <ol> + aria-label на «главу» самые «без» «плодить» h
Читалка: <ol aria-label="Оглавление"><li><a href="#ch2">Глава 2: flexbox</a>. Практика: учебник. Скринридер «прочтёт» как навигацию. Проверка: aria-label осмыслен. Доступность «оглавления».
Мини-форма «вопрос-голосование»: fieldset+legend «+» радио «с» aria-pressed не надо (radio — сам)
Голосование в уроке: «Понравился ли урок?» — fieldset+legend+radio «Да/Нет». Скринридер «свяжет» группу. Проверка: «отправка» по кнопке. Доступность «голосования».
Ссылка «на» котнракт: <a href="oferta.pdf" aria-label="Оферта — PDF, 310 КБ">
Карточка-заказ: ссылка на оферту. Скринридер «прочтёт» имя «с» форматом. Не «прячьте» формат. Проверка: «скачивание» понятно. Доступность «документов».
Заголовок «в» диалоге «подтверждения»: <h2> внутри <dialog> «+» aria-labelledby
<dialog aria-labelledby="dlg-title"><h2 id="dlg-title">Удалить курс?</h2>… Скринридер «прочтёт» заголовок как имя. Проверка: фокус «в» диалоге. Доступность «подтверждения».
Ссылка «на» подкомментарий «в» ветке: <a aria-label="Ответить на комментарий Ивана">
Ветка обсуждения: <a href="#" aria-label="Ответить на комментарий Ивана">Ответить. Скринридер «цель» поймёт. Проверка: имя уникально. Доступность «ветки».
Чекбокс «Понятно, не показывать»: label — клик «по» слову
<label><input type="checkbox"> Больше не показывать подсказку. Скринридер «прочтёт» label. Проверка: клик точен. Доступность «настроек».
Тег <time> «с» диапазоном «—»: datetime="2025-11-20" у ноябрьской недели курса
<time datetime="2025-11-17">Неделя 3: 17–23 ноября — можно двумя time. Практика: расписание. Скринридер «прочтёт». Проверка: обе даты. Доступность «недели».
Поле «в» карточке-опроснике: radio с осмысленным legend «и» подсказкой
Практика: «Сколько лет учите?» — fieldset legend + radio «<1, 1-3, 3+». Скринридер «прочтёт» группу. Проверка: «одно» значение. Доступность «стажа».
Декоративный «разделитель-звезда» между пунктами: <li> + ::after aria-hidden? — проще «без»
Таймлайн: пункты-«звёзды»: <ul role="list"> + li-карточки. Скринридер «прочтёт» пункты. «Звезда» — aria-hidden/decar. Проверка: поток цел. Доступность «таймлайна».
Строка-«шаг» с <details> «как» раскрывающийся совет в инструкции
<details><summary>Совет: как ускорить</summary>… «в» конце шагов. Практика: монтаж. Скринридер «раскроет». Проверка: «важно» не «спрятано». Доступность «премудростей».
Название «вкладки» «Каталог» с <nav aria-label="Каталог товаров">: не путать с заголовком
<nav aria-label="Каталог товаров"> — ориентир «по» категориям. Практика: магазин. Скринридер «найдёт». Проверка: «заголовок» — отдельно. Доступность «каталога».
Заголовок-«аккордеона» FAQ с «вопросом»: <h3> <span> маленькая «часть» «всё» «в» details
<details><summary><h3>Как вернуть?</h3></summary>. Скринридер «прочтёт» вопрос. Проверка: «не» «плодить» h2. Доступность «FAQ».
Кнопка-«стрелка» «Назад» у микросайта: aria-label + rel="prev"
<a href="lesson.html" aria-label="Назад к списку уроков" rel="prev">←. Практика: курс. Скринридер «прочтёт». Проверка: «не» пустая. Доступность «возврата».
Кнопка «поделиться» «с» иконкой соцсети: aria-label «ВКонтакте»
<button aria-label="Поделиться в ВКонтакте">[svg]</button>. Скринридер «прочтёт». Проверка: «имя» цель. Доступность «шеринга».
Поле «выбора» месяца «и» года: <input type="month"> нативный
<input type="month"> — «месяц+год» одним полем. Практика: подписка. Скринридер «прочтёт» значение. Проверка: формат. Доступность «месяца».
Форма «возврат» товара: label+textarea «почему» аргумент
<label>Причина возврата</label><textarea>. Скринридер «свяжет». Проверка: имя. Доступность «возврата».
Селект «Город» «с» optgroup по области: группировка «плоская»
<optgroup label="Московская область">… Практика: доставка. Скринридер «услышит» группу. Проверка: метки. Доступность «группы».
Заголовок «из» данных ячейки: <th> текст + <abbr> «для» правды
<th><abbr title="Домашнее задание">ДЗ</abbr></th>. Скринридер «расшифрует». Проверка: «не» «шум». Доступность «аббревиатур».
Карусель «без» брата-дубля: aria-roledescription «карусель» + пауза
role="region" aria-roledescription="карусель" aria-label="Отзывы" — «одно» имя. Скринридер «прочтёт». Проверка: «пауза». Доступность «карусели».
Ссылка «в» меню «урока»: aria-current="true" с якорем секции
<a href="#part2" aria-current="true">Часть 2. Скринридер «прочтёт» «текущая». Проверка: «новая позиция» — убрать. Доступность «меню».
Инлайн «кода» в статье: <code> + <span aria-label> не надо — «читается» текст
<p>Используйте <code>display:flex</code>. Скринридер «прочтёт» как код. Проверка: «не» «прятать» семантику. Доступность «кода».
Метка «диапазона» «До X ₽»: <output> + aria-live у суммы слайдера
<output aria-live="polite">до 15000 ₽</output>. Скринридер «услышит». Проверка: «плавно». Доступность «фильтра».
Кнопка-«звезда» — «избранное»: aria-pressed с невидимым label-текстом
<button aria-pressed="false" aria-label="В избранное: Сликер 3">☆</button>. Скринридер. Проверка: имя. Доступность «избранного».
Заголовок «обратного» списка-рейтинга: <ol reversed> «топ»-5 наоборот
<ol reversed> — «5,4,3…» нисходящий. Практика: рейтинг. Скринридер «прочтёт» номера. Проверка: честен. Доступность «рейтинга».
Поле «даты»: <input type="date"> «плюс» label + aria-describedby формата
<label>Дата занятия</label><input type="date">. Скринридер «услышит». Проверка: пример «ДД.ММ.ГГГГ» — describedby. Доступность «даты».
Ссылка «на» описание курса: <a> h2 карточки «О курсе»
Карточка курса: <h3><a href="#detail">Подробнее о курсе</a>. Скринридер «прочтёт». Проверка: имя. Доступность «детали».
Мини-аккордеон «Вопросы и ответы»: <details> + <summary> — без JS
FAQ: 8 details. Скринридер «раскроет». Проверка: стрелки. Доступность «аккордеона».
Заголовок «логина» «без» визуального: aria-label на поле с «иконкой человечка» в форме входа
<input aria-label="Логин или email">. Скринридер «прочтёт». Проверка: имя. Доступность «входа».
Пункт «меню-хлеб» активного «сада»: <a aria-current="page">Плоды</a> «в» крошках «—» по-русски
Крошки: «Главная / Каталог / <a aria-current="page">Плоды</a>. Практика: витрина. Скринридер «прочтёт» «текущее». Проверка: текущее «не» ссылка? — «может» «и» span. Доступность «крошек».
Поле «е-mail» «с» авто-капитализацией «выкл»: autocapitalize="off" для изгороди
<input type="email" autocapitalize="off"> — «мобильная» клавиатура «не» «заглавных». Практика: подписка. Скринридер «не» о, но «ввод» ровнее. Проверка: адрес корректен. Доступность «ввода».
Шрифт «у» пунктов статистики «в» карточке: system-ui + «и» цифры «через» <output> aria-live
«1500+ учеников» — <span aria-hidden>1500+</span>? — «нет»: «это» текст. Практика: лендинг. Скринридер «прочтёт». Проверка: число. Доступность «статистики».
Мини-тест «правда/ложь»: radio «с» фразой «в» legend «весь» вопрос
<fieldset><legend>«CSS «может» «переставлять» «порядок» «чтения»?»</legend> + radio «Да/Нет». Скринридер. Проверка. Доступность «теста».
Карточка «кура»-«со» «скидкой»: div style + <p class="old-price"> «зачёркнутая» старая
«Старая» цена «зачёркнута»: <del>3900 ₽</del> + <ins>2900 ₽</ins>. Скринридер «прочтёт» обе. Проверка: «не» aria-label'ом. Доступность «цены».