Наткнулся в LinkedIn на пост с рецептом пропорционально масштабируемой карточки на основе единиц
cqi и математики. Но меня зацепило не это, а разметка карточки:<div class="card">
<div class="card-inner">
<img
class="card-img"
alt=""
src="..."
>
<div class="card-content">
<div class="card-title">
Добро пожаловать!
</div>
<div class="card-desc">
Это масштабируемая карточка.
</div>
<a
class="card-button"
href="..."
target="_blank"
>
Подписаться
</a>
</div>
</div>
</div>
<div> в <div>-е сидит и <div>-ом погоняет. Понятно, что разметка иллюстративная, а суть поста в CSS-технике. Иллюстративная ведь, да? Я не смог пройти мимо и решил сделать из этого пост. Итак, чиним семантику карточки.Элемент
.card может быть размечен как <article>, если карточка представляет независимый контент, который можно вырвать из контекста без потери смысла. Альтернатива — <div role="group">.Возможен вариант с
<section>, если карточка — большой тематический раздел. Если карточка находится в <li>, то <div> остаётся как обёртка компонента или сам <li> берёт на себя эту функцию.Элемент
.card-inner кажется лишним. Возможно, это требуется для стилей. Но выглядит так, что можно использовать родительский .card, а .card-inner можно удалить. Чем меньше узлов, тем лучше.С
.card-img всё ок. Пустой alt уместен для декоративных изображений, иначе нужно описание. Но можно лучше: добавить адаптивность за счёт атрибутов srcset и sizes, хотя-бы с x-дескриптором.Можно добавить
width и height для предотвращения сдвигов макета. Если карточка находится за пределами начальной области просмотра, loading="lazy" отложит загрузку картинки, а fetchpriority и decoding дадут больше контроля.Элемент
.card-content так же выглядит лишним. Расположить изображение и остальной контент можно с помощью flex или grid у .card, без лишних обёрток. В таких мелочах раздувается размер DOM..card-title надо заменить на заголовок, title в названии класса намекает. Скорее всего, <h3>, карточка обычно находится в разделе с <h2>. Но возможен вариант с <h2>, всё зависит от структуры.Судя по классу и короткому тексту без дополнительной разметки, элемент
.card-desc принимает обычный текст. Тут больше подойдёт элемент <p>. <div> уместен для rich-контента из WYSIWYG.У ссылки
.card-button не хватает информации об открытии страницы в новой вкладке для удобства пользователей вспомогательных технологий. Дополнительная иконка со стрелкой обеспечит визуальную подсказку.Картинку и заголовок можно поменять местами в DOM и инвертировать порядок через CSS. Чтобы при быстром переходе к заголовку в скринридерах картинка не затерялась. Это имеет смысл для контентных картинок с
alt-текстом.К
<article> можно привязать заголовок с помощью aria-labelledby для дополнительного контекста. Можно попробовать aria-roledescription для уточнения роли элемента. Но такие моменты желательно тестировать.<article
class="card"
aria-labelledby="heading"
>
<h3
class="card-title"
id="heading"
>
Добро пожаловать!
</h3>
<img
class="card-img"
alt=""
src="..."
srcset="... 1x, ... 2x"
sizes="..."
width="380"
height="380"
loading="lazy"
decoding="async"
>
<p class="card-desc">
Это масштабируемая карточка.
</p>
<a
class="card-button"
href="..."
target="_blank"
>
Подписаться
<svg
role="img"
aria-label="(откроется в новой вкладке)"
>
<!-- ... -->
</svg>
</a>
</article>
Лучше? Лучше! Конечно, важно учитывать контекст. Где-то
<article> будет не уместен, у изображения должно быть описание, а заголовок должен быть другого уровня. Также это моя версия разметки, кто-то может не согласиться.В
<div> нет ничего плохого. Но когда почти всё — <div>, вот это плохо. Плохо для SEO, вспомогательных технологий, расширений, парсеров, ИИ, специальных браузеров и режимов отображения веб-контента.(Отредактировано, чтобы влезло в один пост)
#html