Уже многие годы JavaScript остаётся «рабочей лошадкой» веба. Если вам нужно сделать то, что невозможно реализовать средствами HTML и CSS, то обычно найти решение помогает JS. И это замечательно! JS помог расширить возможности пользователей, а также стимулировал прогресс HTML и CSS!
Но время идёт, функции HTML и CSS расширяются, поэтому мы должны начать заменять старые и привычные решения на JS новыми, требующими меньше JS.
Я ничего не имею против JS, но у него есть иные задачи, кроме как управление аккордеонами и внеэкранными меню навигации... Кроме того, JS нужно скачивать, распаковывать, обрабатывать, после чего он ещё часто тратит память на мониторинг и поддержку фич. Если мы сможем перенести какую-то функциональность JS в нативный HTML или CSS, тогда пользователям придётся скачивать меньше данных, а оставшийся JS сможет уделить внимание более важным задачам, с которыми (пока) не справляются HTML и CSS.
В этой статье я приведу несколько примеров; сможете придумать свои?
Аккордеоны/раскрывающиеся панели с контентом
Описание:
HTML-элементы details и summary позволяют заменить типичный JS-аккордеон одним HTML:

Сценарии использования:
Сокрытие/отображение контента
Развёртывание разделов контента
Базовая реализация:
<details>
<summary>Initially closed, click to open</summary>
Content is initially hidden, but can be revealed by clicking the summary.
</details>
Если добавить атрибут open, то по умолчанию контент будет «открыт»:
<details open>
<summary>Initially open, click to close</summary>
Content is initially visible, but can be hidden by clicking the summary.
</details>
Если использовать атрибут name для всех соответствующих details (например, радиокнопок), то одновременно будет открыта только одна панель:
<details name="foo" open>
<summary>Initially open, clicking others will close this</summary>
Content is initially visible, but can be hidden by clicking the summary; only one panel can be open at a time.
</details>
<details name="foo">
<summary>Initially closed, clicking will open this, and close others</summary>
Content is initially hidden, but can be revealed by clicking the summary; only one panel can be open at a time.
</details>
<details name="foo">
<summary>Initially closed, clicking will open this, and close others</summary>
Content is initially hidden, but can be revealed by clicking the summary; only one panel can be open at a time.
</details>
Можно также настроить внешний вид элементов при помощи CSS и выполнять открытие/закрытие через JS.
Подробнее об элементе details можно узнать в опубликованном ранее посте «For the Love of <details>».
Ресурсы:
Совместимость с браузерами:
Поле ввода с раскрывающимся меню рекомендаций автофильтра
Описание:
Скомбинировав HTML-элементы input и datalist, можно создать раскрывающееся меню вариантов, выполняющее автоматическую фильтрацию в процессе ввода:

Сценарии использования:
Поиск по сайту
Поиск или фильтр товаров
Фильтрация любого списка данных
Базовая реализация:
<label for="browser">Browser</label>
<input type="text"
list="browsers"
id="browser" name="browser"
size="50"
autocomplete="off" />
<datalist id="browsers">
<option value="Arc"></option>
<option value="Brave"></option>
<option value="Chrome"></option>
<option value="DuckDuckGo"></option>
<option value="Firefox"></option>
<option value="Microsoft Edge"></option>
<option value="Opera"></option>
<option value="Safari"></option>
<option value="Tor"></option>
<option value="Vivaldi"></option></option>
</datalist>
Также можно использовать другие input type:
<label for="quantity">Quantity</label>
<input type="number"
list="quantity-options"
id="quantity" name="quantity" />
<datalist id="quantity-options">
<option value="1"></option>
<option value="2"></option>
<option value="5"></option>
<option value="10"></option>
<option value="20"></option>
<option value="50"></option>
</datalist>
<label for="appointment">Appointment</label>
<input type="time"
list="appointments"
id="appointment" name="appointment" />
<datalist id="appointments">
<option value="12:00"></option>
<option value="13:00"></option>
<option value="14:00"></option>
</datalist>
Стоит отметить, что на момент написания этого поста Firefox поддерживает только текстовые input type, поэтому пока никаких date, time, range и color...
Также учтите, что на момент написания поста существуют ограничения на мобильных платформах и сложности с accessibility.
Ресурсы:
Совместимость с браузерами:
Модальные/всплывающие окна
Описание:
Атрибуты popover и popovertarget могут заменить традиционные модальные/всплывающие окна/оверлеи на основе JS:

Сценарии использования:
Сокрытие/открытие боковых панелей/дополнительной информации
Базовая реализация
Всплывающее окно auto (используемое по умолчанию) можно закрывать нажатием вне его или клавишей esc. Открытие auto автоматически закрывает все другие открытые всплывающие окна auto. При повторном нажатии на button закрывается окно, которое открывалось этой кнопкой.
<button popovertarget="pop-auto">
Toggle Popover
</button>
<dialog popover id="pop-auto">
I'm an "auto" Popover!
</dialog>
Всплывающее окно hint тоже можно закрывать нажатием вне его или esc. При своём открытии оно не закрывает другие окна hint. При повторном нажатии на button закрывается окно, которое открывалось этой кнопкой.
<button popovertarget="pop-hint">
Toggle Popover
</button>
<dialog popover="hint" id="pop-hint">
I'm a "hint" Popover!
</dialog>
Стоит отметить, что на момент написания поста Firefox и все разновидности iOS не поддерживали всплывающие окна hint.
Всплывающее окно manual нельзя закрывать нажатием вне или esc. При открытии оно не закрывает другие окна manual. При повторном нажатии на button закрывается окно, которое открывалось этой кнопкой.
<button popovertarget="pop-manual">
Toggle Popover
</button>
<dialog popover="manual" id="pop-manual">
I'm a "manual" Popover!
</dialog>
Подробнее об открытии и закрытии диалоговых и всплывающих окон можно узнать из поста «Controlling dialogs and popovers with the Invoker Commands API».
Ресурсы:
Совместимость с браузерами:
Внеэкранная навигация/контент
Описание:
Функциональность модальных/всплывающих окон также можно использовать для создания внеэкранной навигации, не требующей JS:

Сценарии использования:
Сокрытие/отображение меню навигации
Базовая реализация:
<button popovertarget="menu">
Toggle Menu
</button>
<nav popover id="menu">
Nav Content
</nav>
#menu {
margin: 0;
height: 100vh;
translate: -100vw;
}
#menu:popover-open {
translate: 0;
}
Для придания семантического значения я использую элемент nav, но можно использовать любой другой HTML-элемент (div, section, aside и так далее).
Согласно User Agent Stylesheet, для popover по умолчанию используется position: fixed, оно просто выталкивается из экрана при закрытии и возвращается на экран при открытии. Обратите внимание, что для переопределения center-alignment User Agent обязательно использовать margin: 0.
При нажатии вне меню оно закрывается. Можно принудительно оставить панель открытой, чтобы она требовала закрытия вручную, при помощи popover="manual".
Также можно добавить псевдоэлемент backdrop и стилизовать его:
#menu::backdrop {
background: rgb(190 190 190 / 75%);
}
Ресурсы:
Совместимость с браузерами:
Заключение
Все мы любим ту мощь и гибкость, которую даёт нам JS, но также нам стоит уважать его и наших пользователей, ограничивая его только тем, что он должен делать.
За последние годы изменилось очень многое, в том числе появилось и множество областей, в которых теперь достаточно CSS. Если вам хочется большего, то прочитайте мою статью, в которой рассказывается и об этом: https://aarontgrogg.com/blog/2023/05/31/replace-js-with-no-js-or-lo-js-options/.
Комментарии (27)

urvanov
29.12.2025 11:11Функциональность модальных/всплывающих окон также можно использовать для создания внеэкранной навигации, не требующей JS:
Хороший вариант создания меню, кстати. Спасибо. Надо будет попробовать, когда в следующий раз буду что-нибудь делать.

Seregaalex
29.12.2025 11:11Что в нем хорошего? А как ты определишь на какой страничке сейчас пользователь? Роут не меняется, только гребаные кнопки. Правильно, определишь с помощью js. Так а нахрена козе баян, если ты и так можешь с помощью js воткнуть нужный тег и использовать принцип единой ответственности за то нам какой вкладке находится пользователь?

urvanov
29.12.2025 11:11Для меню не обязательно определять, на какой странице пользователь. Там обычно же просто главные навигационные ссылки вида: главная страница, новости, блог, фото, видео, контакты. Ну и в таком плане.

GerrAlt
29.12.2025 11:11Что аккордеон, что всплывающие окна спокойно делаются на html+css без этих вот современных расширений (для состояний радиокнопки и чекбоксы с css правилами на :checked)

inikonzs
29.12.2025 11:11Вот да, чекбоксом под display none это норм можно осуществить. И выпадашку инпуту по фокусу дать можно. И гармошку через радиогруп. Я вообще как то развивал целую парадигму кодинга на реактивном css и она простая и красивая. Но никак не на специальных там тэгах, они вообще криво стилизуются и ни капли не анимируются.

inikonzs
29.12.2025 11:11Я уже давно понял что это все не так. Конечно css может и активно стремится к решению многих задач и многие задачи уже превосходно решает благодаря переменным, обработке эвентов и даже хранении стейта на checked, active, focus, hover, построение логики на has, not в селекторах. Что касается всего кроме div, svg, canvas в хтмл, то все не годится ни на что в реальной задаче кроме скрытого под display: none

dastiw1
29.12.2025 11:11Надеюсь с распространением web components сбудутся мечты тех кто мечтает об универсальных тегах и они поймут что потеряли
NeoCode
Об этом никто никогда не пишет, но если вдуматься... js сделал веб таким какой он есть сейчас. Но если бы js вообще не было, а все веб-страницы были бы чисто декларативными, то веб был бы лучше. Причем лучше именно для конечных пользователей, а не для владельцев сайтов.
js делает веб подконтрольным не пользователям, а владельцам контента. В некотором смысле "телевизирует". Страницы полные по Тьюрингу. Каждый сайт изощряется как может, создавая пользовательский интерфейс с нуля. А ведь могло бы быть иначе - веб как децентрализованная база данных, браузер как инструмент агрегирования этих данных и отображения в виде, наиболее удобном для конкретного пользователя, а владельцы сайтов - лишь безликие поставщики данных. Был период web1.0, когда у многих были свои (как правило вырвиглазные) странички, но с приходом соцсетей оказалось, что большинству достаточно просто стандартной унифицированной страницы. И не так уж много нужно "виджетов" для работы в вебе.
alshinf
Я тоже пришел к выводу, что 99% всех этих креативов, к которым стремятся при создании не сайтов, а веб-приложений, как бы это смешно не звучало. Имхо, пользователям абсолютно не нужны эти уникальные дизайны, им нужно всё на примитивном уровне, но мы имеем всё это в нагроможденном виде лишь с целью удержать посетителя на сайте, потому что мы собираем все возможные метрики, и для нас это важно, а юзабилити это стало всего лишь словом, и не сильно важно...
stozen
Вот только бы тогда существовали только сайты для просмотра статичного контента. Никакого ютюба, гугл карт, веб версий приложений не было. И много чего еще: управление сайтом с клавиатуры, загрузки нового контента без перезагрузки страницы и т.д.
Format-X22
Ну вообще плеер вполне может быть Html в чистом виде. Уверен что если чуть-чуть допилить с буферизацией и прочим - можно было бы получить ютуб. Вот с загрузкой без перезагрузки всей страницы - вопросик. Но в теории можно было бы допилить стандарт до поллинг-тегов или даже реалтайм, на том же xml который представляет html. Гугл карты из чанков картинок состоят и поллинг-тегами решаемо. Поллинг может быть и поточный с тем же вебсокетом.
Ну в общем в принципе с минимальными доработками можно было бы получить большинство типа контента, включая динамический. Разве что вот игры и всякое совсем лютое с канвасами уже не получилось бы.
Так то и представленный тег детейлс можно div и скриптом. И половину анимаций. И даже flex-box был на IE6 и я лично делал, вот прям с той же функциональностью, но через JS используя либу ExtJS.
Просто стандарты не успевали за потребностями, потому появился Тьюринг-полный язык и делайте что хотите, а стандарты потом докрутим. И докручивают, вынося самое популярное в новые теги и css-стили. Просто с отрывом в пяток лет.
NeoCode
Был бы расширенный набор html виджетов. Ютуб - это уже существующий тег video; гугл карты - ну был бы тег map; а загрузка нового контента без перезагрузки страницы это вообще зло - сайты становятся нескачиваемые. А в инете постоянно такое - сегодня сайт есть, завтра нет, и всё, ценная информация пропала навсегда. Да и без скачивания это просто неудобно: крутишь эту бесконечную прокрутку, и нет никакой возможности запомнить текущую позицию и продолжить крутить с этого места скажем завтра. Телевизация в чистом виде.
frostsumonner
Canvas webgl и проч. - это ненужный мусор?
andreymal
Да
Такие вещи должны быть нативными приложениями
(Правда, тут проблема в том, что разработчик может полениться выпускать сборки под редкие платформы)
Dartess
Или у него может не хватить бюджета. Или времени. Или платформа родится уже после окончания разработки. Или ещё чего.
NeoCode
Да все равно новые браузеры требуют новых ОС, под ту же семерку уже не каждый браузер запускается. Так что редкие платформы не аргумент. Проще владельцу редкой платформы виртуалку поставить.
makssof
Эх, вот было хорошо, когда известия доставляли гонцы, а может даже на бересте писали
Было же время
NeoCode
Я предлагаю не регресс, а альтернативный путь. Сайты были бы не закрытыми дизайнерскими приложениями, а открытыми источниками данных. Типа продвинутого RSS. Чистая семантика. Такой веб был бы гораздо ближе к семантической паутине, гораздо удобнее для того же ИИ, гораздо пригоднее для децентрализации и оффлайнового хранения. Представьте к примеру что весь Хабр автоматически сохранялся бы вам на диск, и ваш личный локальный ИИ мог извлечь из него любую интересующую вас информацию.
urvanov
Согласен. Для новостных сайтов, для статейников и для личных блогов было бы идеально.
OldNileCrocodile
Аатор переизобрëл Prolog - японские велосипеды в студию!
350str
Если бы мы жили в мире одностраничинков - вопросов нет. Но как вы предлагаете реализовать, например, торговый терминал без js? Или какие-нибудь гугл-таблицы. Веб такой какой он есть именно из-за перечня задач, которые приходится на вебе решать. И реальность такова, что существуют приложения с очень большим количеством фронтовой логики, и от этого никуда не уйти
NeoCode
Не в браузере, а отдельным приложением? Таких специфических задач не так уж много, и ИМХО десктопные приложения для того и существуют чтобы их решать.
vorant
Я не хочу ставить десктоп приложения на любой чих. Я хочу открыть браузер и решить свою задачу. Именно за это я и люблю современный веб.
У веб приложений слишком много плюсов чтобы от него совсем отказываться
Format-X22
Кстати, раньше для этого был флеш и джава аплеты. Ну и во времена совсем доминации майкрософта - актив икс. Не могу сказать что так лучше, а умерло по сути потому что не шло из коробки с браузером. Можно сказать про тормоза и дыры, но можно и на современные сайты-приложения посмотреть и сравнить потребление памяти - флеш не такой и суровый был. Впрочем, решение через JS мне нравится больше.
winorun
Создать например специализированное приложения для написания сетевых приложений. Которое будет поддерживать загрузку данных по специализированному протоколу.