Уже нет необходимости в этом input[type=radio]:checked + label ~ label со всякими + и ~. У радиокнопки достаточно указать appearance: none и она превращается в бокс, который можно стилизовать практически как угодно.
Я поэтому и пишу, что HTMX решает одну простую задачу — отправка HTTP-запросов, получение HTML и вставка в нужные места DOM. Тут нет разницы, делает он это при помощи XHR, fetch и какого синтаксиса JS. Взгляните на код, который выдают сборщики для prod: там тоже все спреды, классы, фетчи и прочее могут превращаться в старый добрый ES5, а то и ещё ниже бывает.
Тут важна сама идея. HTMX лишь один из вариантов реализации. Есть предшественник intercooler, есть идейный наследник alpine-ajax, есть похожие по концепции hotwire и livewire. Все они вполне используются и решают конкретные задачи. Миксовать пакеты, микрофронтенды, direct DOM — это вообще не про эту идею и HTMX в частности.
И да, HTMX не подходит для каких-то вещей, но также для каких-то подходит. Автор на сайте честно об этом написал, что круто, потому что почти ни у кого нет страницы, где было бы описано, где инструмент не подходит. Если HTMX не для вас, круто, просто не используйте его. Но вы написали статью, где сравниваете HTMX с Vue и HMPL, хотя эти инструменты лежат в разных плоскостях.
иногда требуются дополнительные настройки, современные функци, идующие с fetch, и ещё плюшки работы с javascript и DOM деревом
Сам HTMX в чистом виде решает одну простую задачу: сходить на сервер по такому-то адресу, получить ответ и вставить его в указанное место. То есть эдакий декларативный сахар для fetch(). Интерактивность при этом реализуется средствами сервера. То есть если вы нажали кнопку и под ней появился текст, это произошло, потому что сервер нарисовал кнопку вместе с текстом, отдал её в ответ на запрос и HTMX вставил это вместо исходное кнопки.
А если нужно что-то сделать с DOM на клиенте, то к HTMX берут дополнение в виде hyperscript (своего рода SQL для работы с DOM от того же автора) и пишут логику на нём. Или берут какой-то микрофреймворк, например alpine, petite-vue, или просто пишут на Vanilla JS.
HTMX — это попытка (и достаточно успешная на мой взгляд) привнести новый подход к разработке веб-приложений, ориентированый на серверный рендеринг, с добавлением некоторых недостающих вещей в HTML.
Идея в том, чтобы дать браузерам выдохнуть и не перемалывать мегабайты JavaScript на устройствах пользователей, чтобы отрисовать интерфейс. Вместе с этим уйти от издержек, которые приносят современные JavaScript-комбайны.
Вместо этого пусть браузеры делают то, что было заложено в них при создании — слать HTTP-запросы к серверу, получать в ответ HTML и рендерить его. А браузеры делают это чертовски хорошо и быстро. И пусть логика отрисовки и работы с данными будет на сервере, где ей и место. А тонкая библиотека JavaScript будет инициировать нужные HTTP-запросы и вставлять результат в нужные места документа.
Подход не новый, так делали деды ещё до появления всяких React-ов. HTMX просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.
Вот это то, что мне не нравится во многих фреймворках. Код нужно писать в специально придуманном файле. Для подсветки синтаксиса нужен специальный плагин с Language Server и IDE, которая поддерживает плагин. Разметку нужно писать на специальном диалекте при наличии HTML. Для стилей нужны какие-то пакеты, иначе нельзя писать CSS. Вместо JavaScript нужно писать на каком-то мета-языке. Для перехода между страницами нужен ещё один пакет, потому что нельзя использовать a[href]. И чтоб всё это заработало, ещё нужен сборщик, десять плагинов для него, пять конфигов, npm и node нужных версий и 5 минут билда. Утрирую, но суть примерно такая.
WP использует рендер на сервере, что на текущий момент является моветоном
А по-моему наоборот все потихоньку возвращаются на сервер. Уже пару лет есть мода на SSR и всякие там Next/Nuxt/etc, потому что SEO, производительность, кэш, Server Components и т.д. Тот же нашумевший HTMX предлагает рендерить фрагменты HTML на сервере классическим бекендом с шаблонизаторами.
Ну а что да WP, он живёт себе, спокойно развивается, всё ещё занимает огромную нишу и используется на трети сайтов в интернете. Кривой, косой по историческим причинам, но простой, работает и решает огромное количество задач, при этом не стоит как крыло самолёта.
Можно использовать <picture> + батарею <source> с разными форматами + <img> фоллбэк. Браузеры, которые умеют, загрузят WebP, которые не умеют, откатятся к JPEG/PNG.
Либл можно на сервере читать заголовок Accept, там будет список поддерживаемых форматов. И отдавать разные форматы в зависимости от заголовка.
А для старых устройств можно под картинкой ссылку на скачивание старого доброго JPEG сделать.
На мой взгляд причина та же, почему когда-то в PHP, Java и других языках ушли от шаблонов с вставками кода к шаблонизаторам. Язык даёт слишком большую гибкость и это не всегда нужно.
Об этом говорил создатель Vue в одном из своих докладов.
Байндинга с шаблоном, директив в шаблоне, реактивных переменных, не строковых пропсов. Добавляем это и получаем Vue
Или Lit. Он, всё же, by design разработан для создания веб-компонентов и приложений на их базе. Vue всё же был создан несколько для другого, что не отменяет возможности скомпилировать Vue-компонент в веб-компонент.
Здесь важно нарисовать кнопку на экране и раскасть её, максимум отправить AJAX-запрос на сервер.
А вы уверены? Тут в соседней статье человек, практикующий найм, делится довольно внушительным списком навыков, которыми должен обладать хороший фронтенд-разработчик. В то же время соискатели жалуются на возросшую сложность всего этого и завышенные требования от работадателей. Где же правда?
Например, можно изобрести своё собственное пространство имён для работы с параметрами CSS, что повышает читаемость
Вообще по стандарту HTML нельзя. У элемента могут быть указаны глобальные атрибуты, специфические для этого элемента атрибуты и любые data-* атрибуты. Любые другие атрибуты с точки зрения стандарта считаются невалидными. Из-за лояльности HTML как-бы и ладно, ничего не будет, а селекторы по атрибуту и JS сработают. Но всё-таки так нельзя делать.
любой тег, не распознанный парсером — это неизвестный элемент, который можно свободно стилизовать как угодно
Не совсем так. Элемент считается неизвестным HTMLUnknownElement, если он не является одним из стандартных или не содержит в названии как минимум одного дефиса. Если дефис есть, то парсер рассматривает элемент как потенциальный пользовательский элемент, который пока ещё не зарегистрирован. В таком случае он будет HTMLElement.
С точки зрения HTML всё может быть сделано правильно. Но это лишь один из факторов. Текст может быть уникальным, и описания по 1200 символов, но само содержание текстов, ключевые слова, формулировки могут не нравиться гуглу.
Также сайт может иметь все метатеги и правильную иерархию заголовков, но быть медленным как для пользователя, так и с точки зрения метрик Lighthouse.
Если сайт работает как SPA на модных фреймворках, это тоже может свести на нет усилия по созданию структуры и уникальных текстов. В общем нужно детальнее копать.
Вы ссылаетесь на устаревшую и уже не актуальную версию спецификации, ещё и на снапшот от 2013 года. Официальная спецификация — HTML Living Standard.
В старых стандартах действительно можно было использовать сколько угодно <h1>, это относилось к попытке реализации алгоритма outline с вычислением уровня заголовка на основе вложенности секционных элементов.
Но этот алгоритм не был реализован ни одним из браузеров, и в конечном счёте его удалили из стандарта. Сейчас в примерах используются уровни заголовков, хотя и есть один пример с несколькими <h1>.
Но если выйти за пределы стандартов HTML и посмотреть на те же обшепринятые практики SEO или стандарты доступности, то всё-же правило "один <h1> на страницу" актуально. Более того, это даже логично.
С похожей темой был доклад на Frontendconf. Автор в рамках эксперимента попытался использовать современные стандарты для разработки приложения без зависимостей и этапа сборки.
HTML ведь тоже производный от XML язык. Проблема в том, что Тим Бернерс-Ли делал HTML для разметки научных документов, состоящих в основном из текста. Он не предполагал, что с его помощью будут делать веб-интерфейсы. Уже потом на скорую руку добавили формы, поля ввода в стиле Windows98 и прочее, потому что на HTML пытались делать интерфейсы.
А XAML и другие подобные языки изначально создавались для разработки интерфейсов и там by design были продуманы соответствующие механизмы.
он же все равно его генерирует и далее этот код существует и отправляется на клиент, а можно вообще жить без это кода.
А почему это стало проблемой? Вы в статье указали, что подход с кастомными элементами априори эффективнее по всем метрикам, а в комментариях указали, что смысла в <div class> вообще нет. Но я могу привести некоторые аргументы за то, что смысл есть
Первый аргумент — компрессия. Алгоритмы сжатия (gzip, brotli) работают на словарях, а они формируются из повторяющихся токенов. Большое количество повторяющихся div, class и подчеркиваний (в подходе с БЭМ) приводит к более эффективному словарю и сжатию соответственно. В итоге получается забавная ситуация. Ваш лаконичный код, где вы боролись за лишние символы, будет сжат хуже и весить больше, чем такой же код с div и class.
Второй аргумент — User Agent Stylesheet. <div> по умолчанию block, кастомные элементы по умолчанию inline. Если вы предлагаете менять <div class> на кастомные элементы, то чтобы это было эквивалентно, для некоторых кастомных элементов нужно будет дописывать в CSS display: block, 14 дополнительных символов. В итоге в одном месте сэкономили, в другом дописали.
Третий аргумент — утилитарные классы и микроформаты. Даже если заменить <div class="card"> на <app-card>, может возникнуть желание использовать микроформаты на основе классов. Или размечать классами-модификаторами разные варианты карточек. Или использовать утилитарные классы для текста. Во всех случаях добавляется один или несколько классов. Получаем <app-card class="text-italic color-secondary">. Вернулся к атрибуту class. Сильно ли это отличается по объёму от <div class="card text-italic color-secondary"> и стоит ли оно того?
Вы можете возразить, что можно применять кастомные атрибуты. Но классы универсальны, они могут использоваться как на кастомных элементах, так и на стандартных. Кастомные атрибуты же будут невалидны для стандартных элементов. Можно вместо классов использовать data-*. Но если мы говорим про лаконичность, то это точно не про data-*.
Я надеялся что кто-то такой же дотошливый как и я сможет скинуть ссылку на программу которая текст из div class=text может прочитать, а из тега text или my-text не может.
А зачем такая программа должна существовать? DOM будет построен, а значит прочитать свойство textContent или innerText можно будет. Я не говорил, что текст кастомных элементов прочитать нельзя.
Специальным браузерам точно так же, что прост div что кастомный тег, нет разницы
Разница есть. Как пример специального браузера возьму Reader Mode. Он в разных браузерах реализован по-разному. Но общая суть одна: разобрать страницу, вычленить из неё основной контент и отобразить его в специальном виде, отбросив всё остальное.
Для этого Reader Mode полагается на эвристики, в первую очередь на семантику. Если использовать кастомные элементы вообще для всего сайта (я помню, что вы так делать не предлагали), то браузер просто ничего не распознает и не предложит включить Reader Mode. Если заменить только некоторые элементы, то Reader Mode просто выкидывает все кастомные элементы из итогового результата. А вот <div> с определёнными классами или без них в некоторых ситуациях не выкидывает.
То есть вы тот описанный в статье человек, который боится что где-то, когда-то , "на умном холодильнике" что-то пойдет не так
Нет, я не тот человек из статьи. Я активно использую веб-компоненты на своих проектах, но в виде интерактивных элементов. Я ровно так же, как и вы, задумывался об использовании валидных кастомных элементов в качестве альтернативы для некоторых generic-контейнеров.
Но я более прагматичен и придерживаюсь стандартов HTML. Поэтому я за использование валидных имён кастомных элементов и за замену ими нативных элементов только в ограниченном ряде случаев. Но в целом для меня достаточно много аргументов против, чтобы не заменять массово все <div> на кастомные элементы.
Уже нет необходимости в этом
input[type=radio]:checked + label ~ label
со всякими+
и~
. У радиокнопки достаточно указатьappearance: none
и она превращается в бокс, который можно стилизовать практически как угодно.Я поэтому и пишу, что HTMX решает одну простую задачу — отправка HTTP-запросов, получение HTML и вставка в нужные места DOM. Тут нет разницы, делает он это при помощи XHR, fetch и какого синтаксиса JS. Взгляните на код, который выдают сборщики для prod: там тоже все спреды, классы, фетчи и прочее могут превращаться в старый добрый ES5, а то и ещё ниже бывает.
Тут важна сама идея. HTMX лишь один из вариантов реализации. Есть предшественник intercooler, есть идейный наследник alpine-ajax, есть похожие по концепции hotwire и livewire. Все они вполне используются и решают конкретные задачи. Миксовать пакеты, микрофронтенды, direct DOM — это вообще не про эту идею и HTMX в частности.
И да, HTMX не подходит для каких-то вещей, но также для каких-то подходит. Автор на сайте честно об этом написал, что круто, потому что почти ни у кого нет страницы, где было бы описано, где инструмент не подходит. Если HTMX не для вас, круто, просто не используйте его. Но вы написали статью, где сравниваете HTMX с Vue и HMPL, хотя эти инструменты лежат в разных плоскостях.
Сам HTMX в чистом виде решает одну простую задачу: сходить на сервер по такому-то адресу, получить ответ и вставить его в указанное место. То есть эдакий декларативный сахар для
fetch()
. Интерактивность при этом реализуется средствами сервера. То есть если вы нажали кнопку и под ней появился текст, это произошло, потому что сервер нарисовал кнопку вместе с текстом, отдал её в ответ на запрос и HTMX вставил это вместо исходное кнопки.А если нужно что-то сделать с DOM на клиенте, то к HTMX берут дополнение в виде hyperscript (своего рода SQL для работы с DOM от того же автора) и пишут логику на нём. Или берут какой-то микрофреймворк, например alpine, petite-vue, или просто пишут на Vanilla JS.
HTMX — это попытка (и достаточно успешная на мой взгляд) привнести новый подход к разработке веб-приложений, ориентированый на серверный рендеринг, с добавлением некоторых недостающих вещей в HTML.
Идея в том, чтобы дать браузерам выдохнуть и не перемалывать мегабайты JavaScript на устройствах пользователей, чтобы отрисовать интерфейс. Вместе с этим уйти от издержек, которые приносят современные JavaScript-комбайны.
Вместо этого пусть браузеры делают то, что было заложено в них при создании — слать HTTP-запросы к серверу, получать в ответ HTML и рендерить его. А браузеры делают это чертовски хорошо и быстро. И пусть логика отрисовки и работы с данными будет на сервере, где ей и место. А тонкая библиотека JavaScript будет инициировать нужные HTTP-запросы и вставлять результат в нужные места документа.
Подход не новый, так делали деды ещё до появления всяких React-ов. HTMX просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.
Проблема с
prefers-reduced-motion
в том, что многие как раз об этом не заботятся.Вот это то, что мне не нравится во многих фреймворках. Код нужно писать в специально придуманном файле. Для подсветки синтаксиса нужен специальный плагин с Language Server и IDE, которая поддерживает плагин. Разметку нужно писать на специальном диалекте при наличии HTML. Для стилей нужны какие-то пакеты, иначе нельзя писать CSS. Вместо JavaScript нужно писать на каком-то мета-языке. Для перехода между страницами нужен ещё один пакет, потому что нельзя использовать a[href]. И чтоб всё это заработало, ещё нужен сборщик, десять плагинов для него, пять конфигов, npm и node нужных версий и 5 минут билда. Утрирую, но суть примерно такая.
А по-моему наоборот все потихоньку возвращаются на сервер. Уже пару лет есть мода на SSR и всякие там Next/Nuxt/etc, потому что SEO, производительность, кэш, Server Components и т.д. Тот же нашумевший HTMX предлагает рендерить фрагменты HTML на сервере классическим бекендом с шаблонизаторами.
Ну а что да WP, он живёт себе, спокойно развивается, всё ещё занимает огромную нишу и используется на трети сайтов в интернете. Кривой, косой по историческим причинам, но простой, работает и решает огромное количество задач, при этом не стоит как крыло самолёта.
Можно использовать
<picture>
+ батарею<source>
с разными форматами +<img>
фоллбэк. Браузеры, которые умеют, загрузят WebP, которые не умеют, откатятся к JPEG/PNG.Либл можно на сервере читать заголовок Accept, там будет список поддерживаемых форматов. И отдавать разные форматы в зависимости от заголовка.
А для старых устройств можно под картинкой ссылку на скачивание старого доброго JPEG сделать.
На мой взгляд причина та же, почему когда-то в PHP, Java и других языках ушли от шаблонов с вставками кода к шаблонизаторам. Язык даёт слишком большую гибкость и это не всегда нужно.
Об этом говорил создатель Vue в одном из своих докладов.
Или Lit. Он, всё же, by design разработан для создания веб-компонентов и приложений на их базе. Vue всё же был создан несколько для другого, что не отменяет возможности скомпилировать Vue-компонент в веб-компонент.
Хотел уточнить у вас один момент, но случайно оставил отдельным комментом, он ниже.
А вы уверены? Тут в соседней статье человек, практикующий найм, делится довольно внушительным списком навыков, которыми должен обладать хороший фронтенд-разработчик. В то же время соискатели жалуются на возросшую сложность всего этого и завышенные требования от работадателей. Где же правда?
Вообще по стандарту HTML нельзя. У элемента могут быть указаны глобальные атрибуты, специфические для этого элемента атрибуты и любые
data-*
атрибуты. Любые другие атрибуты с точки зрения стандарта считаются невалидными. Из-за лояльности HTML как-бы и ладно, ничего не будет, а селекторы по атрибуту и JS сработают. Но всё-таки так нельзя делать.Не совсем так. Элемент считается неизвестным
HTMLUnknownElement
, если он не является одним из стандартных или не содержит в названии как минимум одного дефиса. Если дефис есть, то парсер рассматривает элемент как потенциальный пользовательский элемент, который пока ещё не зарегистрирован. В таком случае он будетHTMLElement
.Не сломается, если использовать CUSTOM_ELEMENTS_SCHEMA
С точки зрения HTML всё может быть сделано правильно. Но это лишь один из факторов. Текст может быть уникальным, и описания по 1200 символов, но само содержание текстов, ключевые слова, формулировки могут не нравиться гуглу.
Также сайт может иметь все метатеги и правильную иерархию заголовков, но быть медленным как для пользователя, так и с точки зрения метрик Lighthouse.
Если сайт работает как SPA на модных фреймворках, это тоже может свести на нет усилия по созданию структуры и уникальных текстов. В общем нужно детальнее копать.
Вы ссылаетесь на устаревшую и уже не актуальную версию спецификации, ещё и на снапшот от 2013 года. Официальная спецификация — HTML Living Standard.
В старых стандартах действительно можно было использовать сколько угодно
<h1>
, это относилось к попытке реализации алгоритма outline с вычислением уровня заголовка на основе вложенности секционных элементов.Но этот алгоритм не был реализован ни одним из браузеров, и в конечном счёте его удалили из стандарта. Сейчас в примерах используются уровни заголовков, хотя и есть один пример с несколькими
<h1>
.Но если выйти за пределы стандартов HTML и посмотреть на те же обшепринятые практики SEO или стандарты доступности, то всё-же правило "один
<h1>
на страницу" актуально. Более того, это даже логично.С похожей темой был доклад на Frontendconf. Автор в рамках эксперимента попытался использовать современные стандарты для разработки приложения без зависимостей и этапа сборки.
HTML ведь тоже производный от XML язык. Проблема в том, что Тим Бернерс-Ли делал HTML для разметки научных документов, состоящих в основном из текста. Он не предполагал, что с его помощью будут делать веб-интерфейсы. Уже потом на скорую руку добавили формы, поля ввода в стиле Windows98 и прочее, потому что на HTML пытались делать интерфейсы.
А XAML и другие подобные языки изначально создавались для разработки интерфейсов и там by design были продуманы соответствующие механизмы.
Да, имена элементов с дефисом считаются валидными кастомными элементами и это не приводит к ошибкам в валидаторе.
А почему это стало проблемой? Вы в статье указали, что подход с кастомными элементами априори эффективнее по всем метрикам, а в комментариях указали, что смысла в
<div class>
вообще нет. Но я могу привести некоторые аргументы за то, что смысл естьПервый аргумент — компрессия. Алгоритмы сжатия (gzip, brotli) работают на словарях, а они формируются из повторяющихся токенов. Большое количество повторяющихся
div
,class
и подчеркиваний (в подходе с БЭМ) приводит к более эффективному словарю и сжатию соответственно. В итоге получается забавная ситуация. Ваш лаконичный код, где вы боролись за лишние символы, будет сжат хуже и весить больше, чем такой же код сdiv
иclass
.Второй аргумент — User Agent Stylesheet.
<div>
по умолчаниюblock
, кастомные элементы по умолчаниюinline
. Если вы предлагаете менять<div class>
на кастомные элементы, то чтобы это было эквивалентно, для некоторых кастомных элементов нужно будет дописывать в CSSdisplay: block
, 14 дополнительных символов. В итоге в одном месте сэкономили, в другом дописали.Третий аргумент — утилитарные классы и микроформаты. Даже если заменить
<div class="card">
на<app-card>
, может возникнуть желание использовать микроформаты на основе классов. Или размечать классами-модификаторами разные варианты карточек. Или использовать утилитарные классы для текста. Во всех случаях добавляется один или несколько классов. Получаем<app-card class="text-italic color-secondary">
. Вернулся к атрибутуclass
. Сильно ли это отличается по объёму от<div class="card text-italic color-secondary">
и стоит ли оно того?Вы можете возразить, что можно применять кастомные атрибуты. Но классы универсальны, они могут использоваться как на кастомных элементах, так и на стандартных. Кастомные атрибуты же будут невалидны для стандартных элементов. Можно вместо классов использовать
data-*
. Но если мы говорим про лаконичность, то это точно не проdata-*
.А зачем такая программа должна существовать? DOM будет построен, а значит прочитать свойство
textContent
илиinnerText
можно будет. Я не говорил, что текст кастомных элементов прочитать нельзя.Разница есть. Как пример специального браузера возьму Reader Mode. Он в разных браузерах реализован по-разному. Но общая суть одна: разобрать страницу, вычленить из неё основной контент и отобразить его в специальном виде, отбросив всё остальное.
Для этого Reader Mode полагается на эвристики, в первую очередь на семантику. Если использовать кастомные элементы вообще для всего сайта (я помню, что вы так делать не предлагали), то браузер просто ничего не распознает и не предложит включить Reader Mode. Если заменить только некоторые элементы, то Reader Mode просто выкидывает все кастомные элементы из итогового результата. А вот
<div>
с определёнными классами или без них в некоторых ситуациях не выкидывает.Нет, я не тот человек из статьи. Я активно использую веб-компоненты на своих проектах, но в виде интерактивных элементов. Я ровно так же, как и вы, задумывался об использовании валидных кастомных элементов в качестве альтернативы для некоторых generic-контейнеров.
Но я более прагматичен и придерживаюсь стандартов HTML. Поэтому я за использование валидных имён кастомных элементов и за замену ими нативных элементов только в ограниченном ряде случаев. Но в целом для меня достаточно много аргументов против, чтобы не заменять массово все
<div>
на кастомные элементы.