Когато се изучават принципите на основния CSS, човек се учи да пише модулни, многократно използвани и описателни стилове, за да се гарантира поддръжка. Но когато разработчиците започнат да се занимават с приложения от реалния свят, често се чувства невъзможно да се добавят UI функции без стилове да изтекат в непредвидени области. Този проблем често се превръща в самоизпълняващ се цикъл; стилове, които теоретично са обхванати от един елемент или клас, започват да се показват там, където не им е мястото. Това принуждава разработчика да създаде още по-специфични селектори, за да замени изтеклите стилове, които след това случайно заменят глобалните стилове и т.н. Твърдите конвенции за имена на класове, като BEM, са едно теоретично решение на този проблем. Методологията BEM (Block, Element, Modifier) е систематичен начин за именуване на CSS класове, за да се гарантира многократна употреба и структура в CSS файловете. Конвенции за именуване като тази могат да намалят когнитивното натоварване чрез използване на езика на домейна за описание на елементите и тяхното състояние, и ако се прилагат правилно, могат да направят стиловете за големи приложения по-лесни за поддръжка. В реалния свят обаче не винаги се получава така. Приоритетите могат да се променят и с промяната изпълнението става непоследователно. Малки промени в структурата на HTML може да изискват много ревизии на името на CSS класа. При силно интерактивни приложения отпред, имената на класове, следващи модела BEM, могат да станат дълги и тромави (напр. app-user-overview__status--is-authenticating), а непълното придържане към правилата за именуване нарушава структурата на системата, като по този начин отрича ползите от нея. Като се имат предвид тези предизвикателства, не е чудно, че разработчиците са се обърнали към рамки, като Tailwind е най-популярната CSS рамка. Вместо да се опитвате да се борите с нещо, което изглежда като неспечелима война за специфичност между стиловете, по-лесно е да се откажете от CSS Cascade и да използвате инструменти, които гарантират пълна изолация. Разработчиците разчитат повече на помощните програми Как да разберем, че някои разработчици се стремят да избягват каскадните стилове? Това е възходът на „модерните“ предни инструменти – като CSS-in-JS рамки – проектирани специално за тази цел. Работата с изолирани стилове, които са тясно обвързани с конкретни компоненти, може да изглежда като глътка свеж въздух. Премахва необходимостта да се наименуват неща — все още една от най-мразените и отнемащи време задачи от предния край — и позволява на разработчиците да бъдат продуктивни, без да разбират напълно или да използват предимствата на CSS наследяването. Но отказът от CSS Cascade идва със собствени проблеми. Например, съставянето на стилове в JavaScript изисква тежки конфигурации на компилация и често води до неудобно смесване на стилове с маркиране на компоненти или HTML. Вместо внимателно обмислени конвенции за именуване, ние позволяваме инструменти за изграждане за автоматично генериране на селектори и идентификатори за нас (напр. .jsx-3130221066), изисквайки от разработчиците да бъдат в крак с още един псевдоезик сам по себе си. (Сякаш когнитивното натоварване от разбирането какво правят всички useEffects на вашия компонент вече не е достатъчно!) По-нататъшното абстрахиране на работата по именуване на класове към инструменти означава, че основното отстраняване на грешки често е ограничено до конкретни версии на приложения, компилирани за разработка, вместо да се използват собствени функции на браузъра, които поддържат отстраняване на грешки на живо, като Инструменти за разработчици. Това е почти като да трябва да разработим инструменти за отстраняване на грешки в инструментите, които използваме, за да абстрахираме това, което мрежата вече предоставя – всичко това в името на бягството от „болката“ при писането на стандартен CSS. За щастие модерните CSS функции не само правят писането на стандартен CSS по-гъвкав, но също така дават на разработчиците като нас много повече власт да управляват каскадата и да я накарат да работи за нас. CSS Cascade Layers са чудесен пример, но има друга функция, която получава изненадваща липса на внимание - въпреки че това се променя сега, след като наскоро стана съвместима с Baseline. CSS @scope At-Rule Смятам, че CSS @scope at-rule е потенциален лек за тревожността, предизвикана от изтичане на стилове, която разгледахме, която не ни принуждава да компрометираме естествените уеб предимства за абстракции и допълнителни инструменти за изграждане. „Правилото @scope CSS at ви позволява да избирате елементи в конкретни поддървета на DOM, като насочвате елементите прецизно, без да пишете прекалено специфични селектори, които е трудно да се отменят, и без да свързвате вашите селектори твърде тясно към структурата на DOM.“— MDN
С други думи, можем да работим с изолирани стилове в конкретни случаи, без да жертваме наследяването, каскадирането или дори основното разделяне на проблемитетова е дългогодишен ръководен принцип на разработката на предния край. Освен това има отлично покритие на браузъра. Всъщност Firefox 146 добави поддръжка за @scope през декември, правейки го съвместим с Baseline за първи път. Ето едно просто сравнение между бутон, използващ модела BEM, спрямо правилото @scope:
<стил> .button .button__text { /* стилове на текст на бутона */ } .button .button__icon { /* стилове на икона на бутон */ } .button--primary { основни стилове на бутон */ }
<стил> @scope (.primary-button) { span:first-child { /* текстови стилове на бутон */ } span:last-child { /* стилове на икона на бутон */ } }
Правилото @scope позволява прецизност с по-малко сложност. Разработчикът вече не трябва да създава граници, използвайки имена на класове, което от своя страна им позволява да пишат селектори, базирани на естествени HTML елементи, като по този начин елиминира необходимостта от предписващи CSS модели на име на клас. Чрез просто премахване на необходимостта от управление на имена на класове, @scope може да облекчи страха, свързан с CSS в големи проекти. Основна употреба За да започнете, добавете правилото @scope към вашия CSS и вмъкнете основен селектор, към който стиловете ще бъдат обхванати: @scope (<селектор>) { /* Стилове с обхват към <селектор> */ }
Така че, например, ако обхванем стилове към елемент
@scope (навигация) { a { /* Стилове на връзки в обхвата на навигация */ }
a:active { /* Активни стилове на връзки */ }
a:active::before { /* Активна връзка с псевдо-елемент за допълнителен стил */ }
@media (максимална ширина: 768px) { a { /* Адаптивни корекции */ } } }
Това само по себе си не е новаторска функция. Въпреки това, втори аргумент може да бъде добавен към обхвата, за да се създаде долна граница, ефективно определяйки началната и крайната точка на обхвата.
/* Всеки елемент вътре в ul няма да има приложени стилове */ @scope (nav) to (ul) { a { размер на шрифта: 14px; } }
Тази практика се нарича обхват на поничка и има няколко подхода, които човек може да използва, включително поредица от подобни, силно специфични селектори, свързани тясно с DOM структурата, псевдо-селектор :not или присвояване на специфични имена на класове на елементи в рамките на
Заключение Основните CSS рамки, като Tailwind, работят добре за създаване на прототипи и по-малки проекти. Техните ползи обаче бързо намаляват, когато се използват в по-големи проекти, включващи повече от двама разработчици. Разработката на предния край става все по-сложна през последните няколко години и CSS не прави изключение. Въпреки че правилото @scope не е лек за всичко, то може да намали нуждата от сложни инструменти. Когато се използва вместо или заедно със стратегическото именуване на класове, @scope може да направи по-лесно и по-забавно писането на поддържан CSS. Допълнително четене
CSS @scope (MDN) „CSS @scope“, Хуан Диего Родригес (CSS-трикове) Бележки по изданието на Firefox 146 (Firefox) Поддръжка на браузър (CanIUse) Популярни CSS рамки (състояние на CSS 2024) „С“ в CSS: Cascade“, Томас Ип (CSS-трикове) Въведение в BEM (Вземете BEM)