Адаптаванне сучаснага CSS для безпечной роботы: анкіры, сеткавые ляйны, дапамога Scope і функцыя light-dark()
Дазвольце даклэ научыцца, як пазіцыянаванне анкараў, попап-вікна, муравлярная структура з сеткавымі лянамі, пераходы между відзорамі, функцыі light-dark() і @scope заменяюць бібліятэкі JavaScript, а таксама як выкарыстоўваць кожную з іх з альтернатывамі.
Крыніцы: CSS Can Already Do This. Developers Are Still Scared to Ship It.
Большынства пакетаў фронт-энда яшчэ маюць бібліятэкі, чыя ўзгаледна задача — вылучыць месца для падказак, такія як Floating UI або ўсё той жа Popper, а таксама іншыя бібліятэкі, якія аранжуюць карточкі у сетку у стыле Pinterest. Адныя браузеры тепер можаць выканаць абе ція заведамыя задачы самы, а таксама кальколькі іншых задач, якія раней выкарыстоўвалі JavaScript, пры тым малая колькасць команды ўсё ж зняла гэтыя залежнасці. У гэтым кансультатывным матэрыяле рассказваецца пра пяць функцыяй CSS, якія можуць заменіць распашчасты код бібліятэкаў, пояснюецца, як кожная з іх працуе, і паказваецца, як ўжываць іх без рызыка з-бягу падтрымкі ў разных браузерах.
Якія жаданыя, але водночас ухіляюцца
Рэзультаты апытакоў дэвелопераў добра падметляюць гэты напянот. У рэзультатах даследжэння «State of CSS» за 2026 год пазычаннікаванне анкараў было выбрана як найболей цікавая новая функцыя для дэвелопераў, заменіўшая :has(), якая зараз настолькі шырока вжываецца, што больш не здаецца новай. У тым жа апытакоўзе таксама спыталі, якія функцыі людзі намеравана адхоўляюць, таму што ўсё яшчэ не верыць у падтрымку з боку прыгледачаў, і пазычаннікаванне анкараў таксама стала лідерам у гэтым списку. Закрыць гэтую прыему значнаю часткай адбываецца за дапамогою функцый, якія працуюць за дапамогою фічар-запытак. Цифры апытакоў і статус падтрымкі быстра зменяюцца, таму трэба спрыймать іх як момантальныя даны і пераканацца ў актуальных данных прыдатнасі пры выкарыстоўванні будзь-якай функцыі.
Пазычаннікаванне анкараў заместо бібліятэкі падказак
Падчынныя методы JavaScript прыкладваюць елемент, який плавае, да свайго трыгеру, вымерваючы абодву вялічыны і пераскладваючы пазыцію з кожнай перезапісу сторанкі чыста ў вялічыну. Пазыціонаванне анкора пераносіць гэтыя взаўзаёмныя зв’язкі ў CSS.
У прыкладзе нижэй трыгер задае імя, а меню пазыціонуе ся ўзгодна з ім. Пасляльнее заданне заменяе функцію выкрытыя бібліятэкі для выкрытчыка зіштовхнення:
.trigger {
anchor-name: --menu-trigger;
}
.menu {
position: fixed;
position-anchor: --menu-trigger;
top: anchor(bottom);
left: anchor(center);
position-try-fallbacks: flip-block, flip-inline;
}
Кожны элемент выпаловае адзін конкрэтны ролю:
anchor-nameдае элементу ідэнтыфікатор у вигляде пунктыроў, за які іншы элементы можаць пазыціонавацца.position-anchorпаведамляе элементу, які знаходзіцца ў пазыцыі, які анкор з заданым іменем ён павінен следаваць.anchor()чытае координаты, такія як нижняя грань анкора чыста ў горизонтальны цэнтр, безпасоверхнева з таго элемента.
position-try-fallbacks паказвае альтернатывы, якія выкарыстоўвае браузер, калі элемент можа перапыліць вікнапраэкт; flip-block і flip-inline перавертаюць яго верхняй або горизантальны спакой.Супрацоўка з атрыбутам popover
Атрыбут popover, які таксама ўключаны, але часта ігноруецца, керуе прыемамі выпадаючага меню: кнопка з popovertarget актывае элемент з адпаведным id, не трэба ніякога скрыпту:
<button popovertarget="menu">Options</button>
<div id="menu" popover anchor-name-target="--menu-trigger">...</div>
Будзьце абярожны з гэтым фрагментам: anchor-name-target не ўзьлеглая атрыбут HTML, таму не копіюйце яго такім, які ён. З’яўляйце поп-ап, выкорыстоўваючы CSS і атрыбуты anchor-name та position-anchor, як паказана вышэй. Дзеякія браузеры таксама спрыймаюць кнопку, якая запускае поп-ап, як неявны анкер для поп-апа, адкрытага за дапамой popovertarget; пераканайцеся ў актуальной даследчыцы, прытаму як вы хочаце на гэта раслучыцца.
Тое, што popover задае ў сваім стандарцы, — это адрасаванне на верхнім слое, таму меню апыяўляецца над усім, без супербора значэння z-index у всім прыкладзе, лёгкае закрыцце, калі корыстувач нажме за межамі або клавішу Escape, і правильна обработка фокуса пад час адкрыцья та закрыцья. Ён не захопляе фокус, як модальны dialog, таму для сапраўдная модальнаяе інфармацыі выкорыстоўвайце dialog у замену.
Ёсць большая інфармацыя пра API прыгледачаў, якія робяць пакеты npm непатрэбнымі; адзін раз прыгляніце нашаму аптаварысу пра вялікія API прыгледачаў, якія заменяюць популярныя пакеты.
Натыўнае мазання з сеткавымі лянкамі
З таго часу, як CSS Grid з’явіўся ў прыгледачах у 2017 годзе, для стварэння мазаных лейаутаў яшчэ быў неабходны JavaScript, і самэ гэта стала прычыной таго, што бібліятэкі на кшталт Masonry і падобныя пакеты былі запусцаны мільйонамі разоў. Адныя гэта зменяецца. Наступная правіла ўтвараюць цэлы лейаут:
.gallery {
display: grid-lanes;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
Кожная карточка размешчаецца ў тым столбце, які нараз чыяе большайшы прастор, таму элементы розташоўваюцца ўжоўку без неравнамерных празораў. Не існуе ResizeObserver, а таксама няма перакалібравання столбцоў у скрыптазе пасля завершэння загрузкі карточкі. Синтаксіс гэтага элемента стварыўся пасля гадоўых дыскусый між виробнікамі прыгледачаў, калі Apple і Google падтрымвалі розныя падходы, прычым display: grid-lanes стаў компромісам.
За данымі пра падтрымку на момент напісання, Safari першы ўключыў гэты элемент, тады як Chrome і Firefox заставілі яго ў режыме пробнай роботы. Гэта поясняе, чаму так мало сайтов яго викорыстоўвае, і чаму зараз варта яго реалізаваць. Павінны быць размешчаны grid-lanes у блоке @supports (display: grid-lanes), а як альтэрнатыва — звычайная сетка.
Пераходы між відобразамі, з высокай абераганосцю
Хутчэй заўсёды трэба быць астатрактычным. Хоць існуе падтрымка API View Transition, яна ў розных браузерах разніцягаецца, таму гэта явышчаеся сярод найбольш ухілваных функцый, нароўна з пазыціонаваннем анкора, і такая астатракцыя ўсё ж разумна.
Базавы механізм прост: апошню змяну DOM трэба абгортаваць у document.startViewTransition(), і тады браузер стварае ксэранкі старага і новага стану, пасля чога пераходзіць межы імі плавна, без неабяжнай бібліятэкі анімацый і без ручнага фіксавання стану да і пасля змян. Наступныя псэуда-элементы кантролююць гэты стандартны пераход, тут яго скорачваючы да 0,3 секунды:
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0.3s;
}
Сёньдзе можна на яго паложыцца як на метод прагрэсіўнага падвышэння якасці. Браузер, у которам няма данай API, проста пераходзіць у новы стан, таму нічога не ламаецца. Гэта робіць яго безпечным для некритычных момантав, такіх як змена стороніцы або пераранжаванне спісу. У скрыптах паказваецца, каб пераканацца, што document.startViewTransition існуе, прычым яго вызываюць, а ў разе проблем — застосаваць змены без яго.
Одна палітра для светлага і темнага режыма за дапамою light-dark()
Тыповы темны режым выкарыстоўвае два цэлых калеровыя системы: адну ў медыа-запите prefers-color-scheme: dark і другую паўтарна. Функцыя light-dark() злучае кожную пару ў адну декларацыю.
У прыводзе нижэй спачатку задаецца документу оба режымы за дапамою color-scheme, які неабходны для работы light-dark(), а пасля кожнай власці прызначаюцься яе значэння для светлага і темнага режыма паўтарна:
:root {
color-scheme: light dark;
}
body {
background: light-dark(#ffffff, #1a1a1a);
color: light-dark(#111111, #eeeeee);
}
Калі color-scheme ўстановлена, кожны вызов light-dark() дае правильную значэння, якая адпавядае настройкам системы пользователя, і больш не трэба дублюваць запиты да медыя-запісоў у файле стайла. Па іншым способам рэалізаціі темавання можна паглядзець у нашай статыце пра методы рэалізаціі темнага режыму.
Адгрупаванне стаяў за дапамогою @scope
Однай з галоўных прычынах викорыстання CSS-у-JS чыстага падчынення BEM є прасачанне спецыфічнасці: правіла .card, прызначаныя для аднаго компонента, таксама стаяляюць некаляжны элемент .card, які знаходзіцца глыбэй у маркапе іншага компонента. @scope натычна обмежвае стаяў толькі ў паддрэве.
У прыказе нижчэй стаяў параграфаў прыменяюцца ўнутрь .card, але не праходзяць далей да элемента .card-nested:
@scope (.card) to (.card-nested) {
p {
color: var(--card-text);
}
}
Першы выбірач задае коран тэриторіі. Клаза to задае нижнюю межу, залишаючы прастор, дзе вкладаны компонент можа кераваць своімі стылямі замест таго, каб спадзяцца ў стылі свайго родніка. Для всьога гэтаго не трэба крока будовы, стварання імен класоў чы JavaScript у час выконання. Гэта не заменіць усё, што робіць CSS-in-JS, напрыклад, стылі, вычысляваныя на адзе з параметраў компонента, але гэта усуне адну з галоўных прычынаў, чаму команды яго адбіраюць.
Браузер — гэта экасістэма
Усе пяць функцыяй вже ўсталяныя прынеймна ў аднам рэальным браузеры сёгодні, і ні адна з іх не залежыць ад React, плагіну для бандлера чы выдання фрэймворку. Разлік межы таго, што можа CSS, і таго, што команды выкорыстоўваюць, здарожае пераважна прыzwычкай: прыблізна дзесяць гадоў рашэнне проблемы інтэрфейсу значыла установку пакета.
Выберыце адзін месца, дзе ваш проект выкарыстоўвае альтернатыўны спосаб на JavaScript для рашэння адной з гэтых проблем, заменіце яго пасля @supports і пагледзіце, што зламаецца. Зазвычай — менш, чым вы спакульвалі.
Частае запытанні
Чы ўсталяванне анкера готава да выкарыстання ў прымэтнае робота?
Яна вже выдана і можа быць выкарыстоўваная сёння пасля пераконтролу @supports. Яе месца ў спісе самых абмежана выкарыстоўваемых функцый паказвае абераганне ў зв’язку з неоднаковым распространенням між прыгледчыкамі, а не брак функцый. Яе союз з альтернатыўным рашэнням, напрыклад простым статычным размешчэнням, ёсць належным рывенем аберагання.
Чы вам яшчэ патрэбна бібліятэка для мазонкі?
Для новага проекту, верагодна, няма, за ўмовы, што display: grid-lanes знаходзіцца ў блоке @supports з звычайной сеткой як альтернатывай. Для існуючага лейауту, які выкарыстоўваецца ў прымэтнае робота і мае строгую матрыцу падтрымкі прыгледчыкаў, краща заставіць бібліятэку ў вжыцці яшчо калькі часу.
Калькі функцыяў калі лепш заўсёды спачатку?
light-dark(). эта адмена ў аднай лініі для кожнага значэння калеру; на момент напісання яна мела найшырэйшую падтрымку з усіх пяці, а таксама дазволяе адмахнуцца вялікага блака дуплікатаваных CSS-кодав для темнага режыму без рызыку для макета.
Галоўныя выводы
- Спрыяйце поступовам удосконаленню кожной функцыяў: викорыстоўвайце натыўнае падзеянне там, дзе яно падтрымванае, а іншыя рашэнні — там, дзе яны вядомы.
- Пазіцыонаванне анкера паўсюду разам з
popoverзадовольняе большасць патрэб да інфармацыйных панелей та выпадаючых меню, але пры неабходнасці справжняго модальнага вікна наладзіце анкер у CSS і викорыстаўцеdialog. grid-lanesта пераходы між відобразамі ўсё яшчэ не ўсталіліся; адключайце іх за дапамогою@supportsабо пераканальнага чэку падчас выконання.light-dark()та@scopeнегайна адмахваюцца коду і несу мінімальны рызык.