TGViewer
<divelopers> <divelopers> @alexnozer_dev · 1.18K subscribers
Post #174 540
Link Area Delegation

Есть распространённый паттерн карточки товара, статьи и так далее. Обычно это картинка, заголовок, ссылка и дополнительные элементы. Верстают их по-разному, но в целом выработан паттерн, который выглядит примерно так:

<article>
<img src="..." alt="">
<h3>
<a href="/catalog/76345865">Title</a>
</h3>
<p>99$</p>
<p>Description</p>
<a href="/cart/add/76345865">Add to cart</a>
</article>


Хочется, чтобы при клике в любое место карточки открывалась детальная страница. Пользователи привыкли к этому. В примере попасть на детальную страницу можно только кликнув по заголовку. Фикс часто сводится к оборачиванию всего ссылкой. Спецификация HTML допускает размещение внутри ссылки того, что можно размещать в её родителе.

Но внутри интерактивных элементов нельзя размещать другие интерактивные элементы. В примере это “Add to cart”. Вложенные интерактивные элементы приводят к плохому пользовательскому опыту и проблемам с доступностью. Кроме того, весь текстовый контент ссылки становится её доступным именем, что крайне избыточно. Иногда от ссылки отказываются, меняя на <div> с обработчиками кликов. Тоже плохо.

Хейдон Пикеринг предложил компромиссное решение. Если кратко, то ссылка остаётся внутри заголовка. К ней добавляется псевдо-элемент ::before и растягивается на всю карточку. Другие интерактивные элементы поднимаются на слой выше, чем ::before. Клик по псевдо-элементу делегируется ссылке и всё работает.

Паттерн рабочий, я им пользуюсь, но есть неудобства. Нужно добавлять ::before, работать с position: absolute и z-index, не забыть поднять другие интерактивные элементы выше, правильно настроить рамку фокуса и т.д.

Группа OpenUI поделилась идеями по улучшению и выпустила предложение Link Area Delegation. Суть сводится к тому, чтобы предоставить декларативный механизм делегирования кликов с других элементов на ссылку. Предложено несколько вариантов, которые ещё будут прорабатываться.

Вариант 1: атрибуты

<article linkarea>
...
<h3>
<a href="/catalog/76345865" defaultlink>Title</a>
</h3>
...
</article>

<article linkarea="link_id">
...
<h3>
<a href="/catalog/76345865" id="link_id">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>


Клик по элементу с атрибутом linkarea делегируется ссылке с атрибутом defaultlink или ссылке, id которой указан в атрибуте linkarea.

Вариант 2: новый элемент

<article>
<linkarea>
...
<h3>
<a href="/catalog/76345865" defaultlink>Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</linkarea>
</article>


Вместо атрибута предлагается элемент <linkarea>. Клики по нему делегируются ссылке с атрибутом defaultlink. Это менее удобно, не всегда можно что-то обернуть, например, строку таблицы, у которой жёсткие правила вложенности.

Вариант 3: CSS вместо HTML

<article class="card">
...
<h3>
<a href="/catalog/76345865">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>

<style>
.card {
pointer-area: contain;
}

.card h3 a {
pointer-area: expand;
}
</style>


Первая ссылка внутри карточки расширяет (pointer-area: expand) свою область клика на элемент, который содержит (pointer-area: contain) расширяемый элемент.

Вариант 4: использование Invokers

<article commandfor="link_id" commands="click contextmenu">
...
<h3>
<a href="/catalog/76345865" id="link_id">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>


Invokers — это декларативный механизм добавления действий к элементам. Я делал пост с обзором ранней версии этого предложения. Частично Invokers уже реализованы в Chrome Canary, Firefox Nightly и Safari TP. В ближайшем будущем стоит ожидать полноценного внедрения в стабильные браузеры.

Я думаю, что у четвёртого варианта больше всего шансов на реализацию. Нужно будет расширить API, которое уже внедряется в браузеры. Но идеи ещё будут обсуждаться и возможны изменения. В целом предложение звучит круто и полезно.
  • ❤ 16
  • 🔥 4
  • 🌚 3
  • 👍 1
More from @alexnozer_dev
  1. Sep 21, 2026Реализация пользовательских атрибутов Под конец прошлого года я рассказывал об API пользов…
  2. Sep 14, 2026Подклассы Event вместо CustomEvent Многие библиотеки предоставляют систему событий в качес…
  3. Sep 11, 2026Эволюция стилей в темах Shopify Адам Ватан на днях поделился новостью, что Shopify выкупил…
  4. Sep 9, 2026Persistent Widgets Многие сайты не должны быть SPA. Но иногда эта архитектура продиктована…
  5. Sep 7, 2026Processing Instructions и маркеры В DOM всё представлено в виде узлов (Node) разных типов.…
  6. Sep 1, 2026@scope и потоковая передача HTML Ноам Розенталь поделился интересной техникой, в которой с…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →