<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arif Balaev</title>
    <description>The latest articles on DEV Community by Arif Balaev (@balaevarif).</description>
    <link>https://dev.to/balaevarif</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F276627%2Fe4a9179e-a09f-49e0-a694-9795a9ed6638.jpeg</url>
      <title>DEV Community: Arif Balaev</title>
      <link>https://dev.to/balaevarif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/balaevarif"/>
    <language>en</language>
    <item>
      <title>Работа с внешними библиотеками</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Mon, 10 Apr 2023 07:01:00 +0000</pubDate>
      <link>https://dev.to/balaevarif/rabota-s-vnieshnimi-bibliotiekami-4n60</link>
      <guid>https://dev.to/balaevarif/rabota-s-vnieshnimi-bibliotiekami-4n60</guid>
      <description>&lt;p&gt;Как разработчикам, нам важно иметь контроль над внешними библиотеками, которые мы используем в своих проектах. Один из способов достижения этого - обернуть эти библиотеки в самостоятельно созданные фасады.&lt;/p&gt;

&lt;p&gt;Фасад - это архитектурный паттерн, который предоставляет упрощенный интерфейс к сложной системе. В контексте внешних библиотек фасад действует как обертка вокруг API библиотеки, предоставляя более простой и последовательный интерфейс к библиотеке. Создавая фасад для внешней библиотеки, мы можем получить следующие преимущества:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Независимость от API библиотеки:&lt;/strong&gt; Используя фасад, мы можем защитить свой код от изменений API внешней библиотеки. Это означает, что если библиотека изменит свой API в будущей версии, вам нужно будет обновить только свой фасад для адаптации к изменениям, а не обновлять весь код, который использует библиотеку напрямую.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Контроль над изменениями:&lt;/strong&gt; Обернув внешнюю библиотеку в фасад, мы получаем полный контроль над тем, как мы используем библиотеку. Это означает, что мы можем выбрать, какие части библиотеки мы хотим выставлять наружу, и как мы хотим, чтобы код взаимодействовал с этими частями. Мы также можем добавлять дополнительную функциональность к фасаду, такую как кэширование или обработку ошибок, не влияя на остальной код.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Поддержка кода:&lt;/strong&gt; Используя фасад, мы можем упростить свой код и снизить его сложность. Это упрощает его поддержку в долгосрочной перспективе, а также делает его более понятным и удобным для работы другим разработчикам.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;В дополнение к этим преимуществам, есть несколько других причин, по которым может захотеться создать фасад для внешней библиотеки. Например:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Тестирование:&lt;/strong&gt; Используя фасад, мы можем мокать API внешней библиотеки в своих тестах, что делает процесс написания и поддержки тестов проще.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Безопасность:&lt;/strong&gt; Контролируя, как наш код взаимодействует с внешней библиотекой, мы можем снизить риск уязвимостей безопасности, вызванных неожиданными взаимодействиями с библиотекой.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Производительность:&lt;/strong&gt; Создавая фасад, мы можем оптимизировать использование библиотеки для улучшения производительности вашего кода.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Поэтому рекомендуется обернуть все внешние библиотеки в фасады, чтобы достичь этих преимуществ.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Controlling External Libraries: Why It's Important for Developers</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Sun, 09 Apr 2023 07:45:42 +0000</pubDate>
      <link>https://dev.to/balaevarif/controlling-external-libraries-why-its-important-for-developers-4kjl</link>
      <guid>https://dev.to/balaevarif/controlling-external-libraries-why-its-important-for-developers-4kjl</guid>
      <description>&lt;p&gt;As a developer, it's important to have control over the external libraries that you use in your projects. One way to achieve this is by wrapping those libraries into self-created facades.&lt;/p&gt;

&lt;p&gt;A facade is a design pattern that provides a simplified interface to a complex system. In the context of external libraries, a facade acts as a wrapper around the library's API, providing a simpler and more consistent interface to the library. By creating a facade for an external library, you can gain the following benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Independence from the library's API:&lt;/strong&gt; By using a facade, you can shield your code from changes to the external library's API. This means that if the library changes its API in a future version, you only need to update your facade to accommodate the changes, rather than updating all the code that uses the library directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control over changes:&lt;/strong&gt; When you wrap an external library in a facade, you have complete control over how you use the library. This means that you can choose which parts of the library to expose to your code, and how you want your code to interact with those parts. You can also add additional functionality to the facade, such as caching or error handling, without affecting the rest of your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved code maintainability:&lt;/strong&gt; By using a facade, you can simplify your code and reduce its complexity. This makes it easier to maintain in the long term, as well as easier for other developers to understand and work with.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In addition to these benefits, there are several other reasons why you might want to create a facade for an external library. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Testing:&lt;/strong&gt; By using a facade, you can mock the external library's API in your tests, making it easier to write and maintain your test suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; By controlling how your code interacts with an external library, you can reduce the risk of security vulnerabilities caused by unexpected interactions with the library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; By creating a custom facade, you can optimize the library's usage to improve the performance of your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you create a simpler and more consistent way to use an external library, it can help you manage your code better. &lt;/p&gt;

&lt;p&gt;Therefore, it is recommended that you wrap all your external libraries in facades to achieve these benefits.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Критическое мышление</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Mon, 27 Mar 2023 05:03:00 +0000</pubDate>
      <link>https://dev.to/balaevarif/kritichieskoie-myshlieniie-5m8</link>
      <guid>https://dev.to/balaevarif/kritichieskoie-myshlieniie-5m8</guid>
      <description>&lt;p&gt;Мы ежедневно сталкиваемся с огромным потоком данных, новостей, мнений и рекомендаций.&lt;/p&gt;

&lt;p&gt;Чтобы избежать манипуляций и логических ошибок, нам нужно научиться тщательно фильтровать информацию. Необходимо оценить и проанализировать, прежде чем принимать её за истину.&lt;/p&gt;

&lt;p&gt;На наших глазах происходит нечто невообразимое. Мы начинаем чаще спрашивать что-то у ChatGPT и его “друзей”, чем искать самостоятельно в гугле. И под всем этим мы не замечаем, что начинаем полностью доверять его ответам.&lt;/p&gt;

&lt;p&gt;Здесь есть большой риск.&lt;/p&gt;

&lt;p&gt;Хотя AI-модели и обучаются на огромных массивах информации, мы не можем быть уверены в том, что они не подвержены влиянию специально подобранных данных или предвзятых алгоритмов. &lt;/p&gt;

&lt;p&gt;Навык критического мышления сейчас становится намного востребованнее, чем любой hard skill.&lt;/p&gt;

&lt;p&gt;Попробуй следовать следующим правилам:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Полностью понимай, о чём идёт речь&lt;/em&gt;. Если непонятно, задавай вопросы. Вопросы - ключ к истине.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Не спеши принимать утверждения за истину&lt;/em&gt;. Ищи доказательства, факты, статистику, мнения экспертов и реальные примеры, подтверждающие аргументы.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Подумай об альтернативных решениях&lt;/em&gt;. Так примешь более взвешенные и обоснованные выводы.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;С появлением AI мы должны стать более эффективными, но не стоит бездумно делегировать всю ответственность на него.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Доверяй, но проверяй.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Критическое мышление - это нечто, что мы развиваем и совершенствуем на протяжении всей нашей жизни.&lt;br&gt;
Начни с сегодняшнего дня.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Critical Thinking</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Sun, 26 Mar 2023 14:36:31 +0000</pubDate>
      <link>https://dev.to/balaevarif/critical-thinking-j4j</link>
      <guid>https://dev.to/balaevarif/critical-thinking-j4j</guid>
      <description>&lt;p&gt;We are bombarded daily with a huge amount of data, news, opinions and recommendations.&lt;/p&gt;

&lt;p&gt;To avoid manipulation and logical errors, we need to learn how to carefully filter information. It is necessary to evaluate and analyze before accepting it as truth.&lt;/p&gt;

&lt;p&gt;We are finding ourselves asking ChatGPT and its AI friends more often than searching Google ourselves these days. We are coming to fully trust their answers without realizing it.&lt;/p&gt;

&lt;p&gt;This could be dangerous.&lt;/p&gt;

&lt;p&gt;We cannot guarantee that AI models are unbiased, even though they are trained on massive amounts of data. Their algorithms or the information used to develop them could be wrong or outdated.&lt;/p&gt;

&lt;p&gt;The skill of critical thinking is now becoming even more in demand than any hard skill.&lt;/p&gt;

&lt;p&gt;Follow these simple rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get clear understanding of message. If unsure, ask questions. Questions unlock understanding.&lt;/li&gt;
&lt;li&gt;Don't just take things at face value. Look for proof, hard facts, expert opinions, statistics, and real examples to support what people say.&lt;/li&gt;
&lt;li&gt;Consider other options. This will lead you to make more balanced and reasonable decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As AI progresses, we must streamline our work. But we should not blindly hand over all accountability to AI.&lt;/p&gt;

&lt;p&gt;Trust, but verify. Think critically.&lt;br&gt;
Start now.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Почему React не реактивен?</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Tue, 21 Mar 2023 13:57:55 +0000</pubDate>
      <link>https://dev.to/balaevarif/pochiemu-react-nie-rieaktivien-40ig</link>
      <guid>https://dev.to/balaevarif/pochiemu-react-nie-rieaktivien-40ig</guid>
      <description>&lt;p&gt;Хотя в названии библиотеки React присутствует слово «РЕАКТ», её связь с парадигмой реактивного программирования куда интереснее, чем кажется на первый взгляд. Давайте разберемся, является ли React реактивным в классическом понимании этого слова.&lt;/p&gt;

&lt;h4&gt;
  
  
  Что такое реактивное программирование?
&lt;/h4&gt;

&lt;p&gt;Для начала, что такое «реактивность»? В широком смысле, это парадигма программирования, ориентированная на &lt;strong&gt;автоматическое распространение изменений&lt;/strong&gt;. Самый простой пример — электронная таблица. Вы меняете значение в одной ячейке, и все ячейки, которые от неё зависят, мгновенно пересчитываются. Им не нужно давать команду «обновись!», они сами реагируют на изменение источника данных.&lt;/p&gt;

&lt;p&gt;В программировании эта идея чаще всего реализуется через &lt;strong&gt;потоки данных (streams)&lt;/strong&gt; — асинхронные последовательности событий, которые происходят во времени. На эти потоки можно подписываться и реагировать на них.&lt;/p&gt;

&lt;p&gt;Представьте ленту новостей в приложении. Новостной сервер — это &lt;strong&gt;Observable&lt;/strong&gt; (наблюдаемый источник), который испускает события (новые статьи). Вы, как пользователь, — это &lt;strong&gt;Observer&lt;/strong&gt; (наблюдатель), который подписан на этот источник и получает обновления, как только они появляются. Источник «проталкивает» (&lt;code&gt;push&lt;/code&gt;) данные к наблюдателю. Это классическая, &lt;strong&gt;push-based модель&lt;/strong&gt; реактивности, которую популяризировали такие библиотеки, как RxJS.&lt;/p&gt;

&lt;p&gt;Ключевая особенность этой модели — полный контроль над потоком. События можно фильтровать (&lt;code&gt;filter&lt;/code&gt;), преобразовывать (&lt;code&gt;map&lt;/code&gt;) и даже группировать по времени (например, оператор &lt;code&gt;bufferTime&lt;/code&gt; в RxJS может собрать все события за 2 секунды и выдать их одной пачкой).&lt;/p&gt;

&lt;h4&gt;
  
  
  Как работает React?
&lt;/h4&gt;

&lt;p&gt;React построен вокруг простой идеи: ваш UI — это функция от вашего состояния (&lt;code&gt;state&lt;/code&gt;). Изменилось состояние — изменился UI.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;UI = f(state)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Событие из внешнего мира (клик мыши, ответ от сервера) вызывает изменение состояния через &lt;code&gt;setState&lt;/code&gt;. Это, в свою очередь, запускает процесс обновления UI.&lt;/p&gt;

&lt;p&gt;Внешне это выглядит как та самая реакция на изменения. Но дьявол, как всегда, в деталях. Нюанс заключается в том, &lt;strong&gt;КАК&lt;/strong&gt; React решает обновить UI.&lt;/p&gt;

&lt;p&gt;Когда вы вызываете &lt;code&gt;setState&lt;/code&gt;, React не бросается сломя голову перерисовывать DOM. Вместо этого он &lt;strong&gt;планирует обновление&lt;/strong&gt;. Он как бы ставит себе пометку: «Ага, состояние изменилось. Скоро нужно будет обновить интерфейс». Если вы вызовете &lt;code&gt;setState&lt;/code&gt; несколько раз подряд в одном и том же обработчике, React окажется достаточно умён, чтобы объединить (сбатчить) их все в одно-единственное обновление.&lt;/p&gt;

&lt;p&gt;Это фундаментальное отличие. В отличие от классической push-модели, где данные &lt;em&gt;проталкиваются&lt;/em&gt; к подписчику, модель React можно назвать &lt;strong&gt;pull-based&lt;/strong&gt; (основанной на запросе). React получает уведомление об изменении, но сам решает, когда &lt;em&gt;запросить&lt;/em&gt; (pull) новое состояние и как наиболее эффективно обновить UI на его основе.&lt;/p&gt;

&lt;h4&gt;
  
  
  Так реактивен ли React?
&lt;/h4&gt;

&lt;p&gt;Да, но он реализует свою, особую модель реактивности.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React реактивен в своей декларативной сути.&lt;/strong&gt; Вы описываете, &lt;em&gt;как&lt;/em&gt; должен выглядеть UI для определённого состояния, и доверяете React синхронизировать реальный DOM с этим описанием. В этом смысле он полностью соответствует широкому определению реактивности — UI автоматически реагирует на изменения данных.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Однако React не является «реактивным» в классическом, потоковом смысле, как RxJS.&lt;/strong&gt; Он не предоставляет из коробки мощных инструментов для управления потоками событий. Его реактивность узко специализирована и нацелена на одну задачу: эффективное обновление дерева компонентов.&lt;/p&gt;

&lt;p&gt;Пакетная обработка обновлений (batching) — это не то, что делает React «нереактивным». Как мы помним из примера с &lt;code&gt;bufferTime&lt;/code&gt; в RxJS, управление потоком и группировка событий — это часть инструментария реактивных систем. Это лишь подчёркивает, что React выбрал конкретную стратегию управления изменениями, поставив во главу угла производительность и предсказуемость рендеринга.&lt;/p&gt;

&lt;h4&gt;
  
  
  Итог
&lt;/h4&gt;

&lt;p&gt;Разобравшись в моделях реактивности, мы можем сделать вывод: React — это реактивная библиотека, но её реактивность не та, что в классических push-библиотеках вроде RxJS.&lt;/p&gt;

&lt;p&gt;React использует &lt;strong&gt;pull-based модель с планированием обновлений&lt;/strong&gt;, идеально заточенную под задачи построения пользовательских интерфейсов. Именно поэтому для сложных сценариев управления асинхронными потоками (например, при работе с WebSockets или сложными анимациями) разработчики часто комбинируют React с библиотеками вроде RxJS, получая лучшее из двух миров.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AI - это всего лишь инструмент, а не замена</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Fri, 17 Mar 2023 15:28:03 +0000</pubDate>
      <link>https://dev.to/balaevarif/ai-eto-vsiegho-lish-instrumient-a-nie-zamiena-2m0d</link>
      <guid>https://dev.to/balaevarif/ai-eto-vsiegho-lish-instrumient-a-nie-zamiena-2m0d</guid>
      <description>&lt;p&gt;Технологии развиваются ежедневно. Мы можем заменить то, что все стремятся сделать свою жизнь и жизнь других эффективнее. Это означает, что все направлено на сокращение использования ресурсов для достижения тех же результатов.&lt;/p&gt;

&lt;p&gt;В разработке мы всегда стремимся использовать что-то новое, потому что это новое экономит нам ресурсы (время, деньги, стресс).&lt;/p&gt;

&lt;p&gt;Среды разработки развиваются, системы сборки конкурируют за миллисекунды, системы деплоя и хостинга пытаются сократить время доставки контента. Всё стремится быть эффективнее.&lt;/p&gt;

&lt;p&gt;Что такое AI для разработчика?&lt;/p&gt;

&lt;p&gt;Это такой же инструмент, который может значительно ускорить разработку. Не заменить разработчика, а ускорить (или даже свести к нулю) его рутинную работу. Google и StackOverflow - отличные примеры этого.&lt;/p&gt;

&lt;p&gt;Задачи разработчиков будут немного смещаться к более высокоуровневым. Это здорово! Мы превращаемся в людей, принимающих решения и фокусирующихся на более структурных аспектах.&lt;/p&gt;

&lt;p&gt;Но здесь есть один важный момент. Чтобы это работало и чтобы мы делегировали рутинные задачи AI, мы должны понимать, что он пишет.&lt;/p&gt;

&lt;p&gt;Программисты никуда не денутся. Простые сайты и до AI можно было создавать через Тильду или no-code решения людям, которые ничего не понимают в разработке.&lt;/p&gt;

&lt;p&gt;А вот сложные системы с персональными, специфическими характеристиками создать будет очень сложно без участия программиста.&lt;/p&gt;

&lt;p&gt;Поэтому AI - это инструмент, который в понимающих руках станет турбоускорителем. Его однозначно нужно уметь использовать. И это плюс.&lt;/p&gt;

&lt;p&gt;Минусом всей этой ситуации является повышение требований только для входящих в индустрию IT. К сожалению, теперь будет недостаточно просто знать язык и уметь выполнять тривиальные задачи. Думаю, это работу в скором времени сможет выполнить искусственный интеллект. Теперь Junior специалист должен уметь использовать искусственный интеллект, чтобы выполнять в два раза больше задач, чем этого ожидали от него в прошлом году.&lt;/p&gt;

&lt;p&gt;Junior разработчики будут еще менее востребованы. Требования к среднему уровню станут базовыми, а старший уровень должен будет решать более комплексные задачи построения глобальных систем.&lt;/p&gt;

&lt;p&gt;AI — это всего лишь инструмент, а не замена. Сейчас происходит переходный период. Кто раньше его освоит, будет намного эффективнее тех, кто не освоил его на текущем рынке. Пользуйтесь этим!&lt;/p&gt;

&lt;p&gt;Таким образом, AI может значительно ускорить и улучшить фронтенд разработку, но полностью заменить человека пока не может. AI и веб-разработчики будут работать в тандеме, повышая скорость разработки и качество конечных продуктов.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Не стой на месте 🤌</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Wed, 15 Mar 2023 19:06:26 +0000</pubDate>
      <link>https://dev.to/balaevarif/nie-stoi-na-miestie-340o</link>
      <guid>https://dev.to/balaevarif/nie-stoi-na-miestie-340o</guid>
      <description>&lt;p&gt;Если мы не развиваемся, мы деградируем. Нет другого выхода. Оставаться на месте также считается деградацией, потому что мир и технологии продолжают двигаться вперед.&lt;/p&gt;

&lt;p&gt;С каждым годом скорость перемен ускоряется, и новые вещи появляются все быстрее и быстрее. Если их не изучать и не применять на практике, то мы быстро станем обладателями устаревших или неэффективных знаний.&lt;/p&gt;

&lt;p&gt;Наше развитие зависит от задач, которые мы решаем.&lt;/p&gt;

&lt;p&gt;Если задачи слишком сложные и значительно превосходят наши способности, это может вызвать беспокойство и стресс. Такие задачи кажутся нам невыполнимыми, и мы рискуем потерять мотивацию из-за частых неудач.&lt;/p&gt;

&lt;p&gt;Простые задачи не мотивируют нас развиваться и могут быть скучными. Они не требуют улучшения наших навыков или изучения чего-то нового. Несмотря на их легкость, они не ведут к прогрессу.&lt;/p&gt;

&lt;p&gt;Чтобы развивать новые умения и улучшать имеющиеся, нам нужны задачи, немного сложнее, чем мы можем сделать сейчас. Они заставляют нас выйти из зоны комфорта, но не вызывают сильного дискомфорта.&lt;/p&gt;

&lt;p&gt;Только так мы можем оставаться эффективными на долгий срок и постепенно, но регулярно повышать свои навыки.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlf1uei6c6cnmd2cdjq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlf1uei6c6cnmd2cdjq1.png" alt="Image description" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>3 вещи, которые продуктовые фронтенд разработчики часто недооценивают</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Mon, 13 Mar 2023 08:09:40 +0000</pubDate>
      <link>https://dev.to/balaevarif/3-vieshchi-kotoryie-produktovyie-frontiend-razrabotchiki-chasto-niedootsienivaiut-3nnb</link>
      <guid>https://dev.to/balaevarif/3-vieshchi-kotoryie-produktovyie-frontiend-razrabotchiki-chasto-niedootsienivaiut-3nnb</guid>
      <description>&lt;p&gt;Мы привыкли считать, что фронтенд разработчик работает только с HTML, CSS и JS для клиентской части сайта. Но на самом деле он работает и отвечает за гораздо большее.&lt;/p&gt;

&lt;p&gt;1️⃣ Дизайн&lt;/p&gt;

&lt;p&gt;Давно одним из преимуществ продуктового дизайнера на рынке является понимание основ вёрстки. Для эффективной работы аналогичная работа должна идти и со стороны фронтендеров. Основы дизайна помогают общаться на одном языке, исправлять небольшие ошибки и предлагать менее ресурсоемкие решения с точки зрения разработки для достижения тех же целей.&lt;/p&gt;

&lt;p&gt;Изучай UI и UX. Не будь только исполнителем.&lt;/p&gt;

&lt;p&gt;2️⃣ Бэкенд&lt;/p&gt;

&lt;p&gt;Из каких компонентов состоит бэкенд? Какие задачи обычно решают бэкенд разработчики? &lt;/p&gt;

&lt;p&gt;Знание бэкенда позволяет лучше понимать и формулировать требования к API, быстрее находить ошибки и предлагать масштабируемые решения. &lt;/p&gt;

&lt;p&gt;3️⃣ Продукт&lt;/p&gt;

&lt;p&gt;Ты понимаешь, что твой продукт может предложить. Ты также знаешь, на что способен фронтенд. Умей соединять эти две вещи и предлагать решения, которые продукт-менеджерам может быть сложно придумать самим.&lt;/p&gt;

&lt;p&gt;В общем, я не утверждаю, что нужно быть экспертами в этих областях или полностью сосредоточиться на их развитии. Тем не менее, они позволяют достигать целей быстрее, потому что способ общения меняется. Оно переходит от "задача-решение" к "понимающему взаимодействию".&lt;/p&gt;

</description>
    </item>
    <item>
      <title>System</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Thu, 09 Mar 2023 05:20:16 +0000</pubDate>
      <link>https://dev.to/balaevarif/system-5gmk</link>
      <guid>https://dev.to/balaevarif/system-5gmk</guid>
      <description>&lt;p&gt;Я эмоциональный человек.&lt;/p&gt;

&lt;p&gt;Эмоции не всегда приводят к лучшим решениям. Если полностью поддаваться им и просто следовать потоку событий, то, через пару лет я страдал бы от депрессии.&lt;br&gt;
Кроме того, неэффективно расходуется время и ресурсы, когда полагаюсь исключительно на эмоции. &lt;/p&gt;

&lt;p&gt;Лично мне помогает решить эту проблему систематизация: система управления финансами, система привычек, питания, временем, а также системы критериев выбора и так далее.&lt;/p&gt;

&lt;p&gt;Для начала разберемся, как устроена система.&lt;/p&gt;

&lt;p&gt;Она принимает данные, делает с ними что-то (надеюсь) полезное и возвращает обработанный результат. При этом ее работу можно настраивать.&lt;/p&gt;

&lt;p&gt;Например, кофемашина. На вход поступают зерна кофе и вода. На выходе - кофе и кофейная гуща. Внутри есть взаимосвязанные элементы, которые всё это готовят. А регулятором служит степень мелкости помола и крепости кофе. &lt;/p&gt;

&lt;p&gt;Шик! Выпьем кофе и двинемся дальше.&lt;/p&gt;

&lt;p&gt;Идеальная система редко строится с первого раза. Нам нужно как-то понимать, где она требует улучшений, а где и так отлично справляется с задачей. Всё линейно.&lt;/p&gt;

&lt;p&gt;"Если вы не можете измерить это, вы не можете управлять им" - Питер Друкер.&lt;/p&gt;

&lt;p&gt;Для контролируемых улучшений нужно иметь показатели. Систему проще покрыть нужными метриками, чем набор хаотичных действий. &lt;/p&gt;

&lt;p&gt;Допустим, я построил систему и покрыл её показателями. В чём прикол?&lt;/p&gt;

&lt;p&gt;Построив систему один раз, мы исключаем эмоциональные решения, потому что сама система говорит нам, что и как делать. Всё происходит намного быстрее и исключает много рисков. Гениально!&lt;/p&gt;

&lt;p&gt;Мы привыкли думать, что системы - это про сложные процессы, схемы и проекты. Однако системный подход можно и нужно использовать повсеместно, чтобы эффективнее распределять свои ресурсы: создавать новое и избегать рутинной работы.&lt;/p&gt;

&lt;p&gt;Подумай, на что ты тратишь много времени и эмоций. Можно ли это систематизировать?&lt;/p&gt;

&lt;p&gt;Дай знать, что думаешь по этому поводу 👇&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Overengineering</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Thu, 02 Mar 2023 13:53:48 +0000</pubDate>
      <link>https://dev.to/balaevarif/overengineering-27d9</link>
      <guid>https://dev.to/balaevarif/overengineering-27d9</guid>
      <description>&lt;p&gt;Over engineering - проблема каждого.&lt;br&gt;
Термин подразумевает создание более сложных вещей, чем этого требовалось. Ресурсы тратятся на менее важные вещи. Время проходит неэффективно. Ожидания не оправдываются, и ты огорчаешься. Узнаешь себя?&lt;/p&gt;

&lt;h3&gt;
  
  
  Откуда это берется?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Задача нечетко определена. Нет ясности, зачем ты это делаешь. Какую проблему решаешь? Решаются другие проблемы или тратится время на ненужное.&lt;/li&gt;
&lt;li&gt;Плохая коммуникация. Бизнес меняется. Завтра появляются новые требования или задача устаревает. Если мы вовремя не получим обратной связи, мы потеряем время.&lt;/li&gt;
&lt;li&gt;Перфекционизм. Все готово, но не идеально. Мы тратим время на поиск ошибок и задерживаем сроки.&lt;/li&gt;
&lt;li&gt;Иррациональное мышление Мы пытаемся предвидеть будущее и облегчить работу. "Один раз сделаю и больше не буду трогать годами." Но мы смотрим слишком далеко и тратим время на "что если".&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Последствия
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Тратим больше времени. Время = деньги. Потеряли время - потеряли деньги.&lt;/li&gt;
&lt;li&gt;Наше "Изобретение" нужно поддерживать. Чем дальше от даты создания, тем меньше помним, как это работает.&lt;/li&gt;
&lt;li&gt;Не уложились в сроки. Задача устарела. Снижается мотивация и эффективность.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Выход
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Не выдумывай и не планируй слишком далеко. Разработка решает проблемы бизнеса. Сделай требования прозрачными.
Дай бизнесу, что он хочет, в кратчайшие сроки и получи обратную связь. Думай над оптимизацией, если это актуально. Почитай про Закон Парето.&lt;/li&gt;
&lt;li&gt;Обзаведись критическим мышлением. Что мы решаем? Какой самый важный сценарий? Можно ли сделать решение проще и выполнить требования? Почему мы выбрали этот подход? Какие альтернативы мы могли бы выбрать?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Привет, CSS Cascade Layers (Каскадные слои)</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Wed, 16 Feb 2022 14:43:49 +0000</pubDate>
      <link>https://dev.to/balaevarif/priviet-css-cascade-layers-kaskadnyie-sloi-4ggj</link>
      <guid>https://dev.to/balaevarif/priviet-css-cascade-layers-kaskadnyie-sloi-4ggj</guid>
      <description>&lt;p&gt;Вольный перевод статьи &lt;a href="https://ishadeed.com/article/cascade-layers/" rel="noopener noreferrer"&gt;Hello, CSS Cascade Layers&lt;/a&gt; от &lt;a href="https://twitter.com/shadeed9" rel="noopener noreferrer"&gt;Ahmad Shadeed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/balaevarif" rel="noopener noreferrer"&gt;Мой twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Одной из наиболее распространенных путаниц в CSS является специфичность (specificity) при написании стилей. Например, меняя значение &lt;code&gt;display&lt;/code&gt; для элемента никогда не сработает, если другой элемент в каскаде переопределяет его по причине более высокой специфичности. Или когда какой-то элемент имеет &lt;code&gt;!important&lt;/code&gt;. Обычно это происходит, когда кодовая база растет и мы не структурируем CSS по пути избежания (или сокращения) таких проблем.&lt;/p&gt;

&lt;p&gt;Чтобы преодолеть проблемы с каскадом и специфичностью, нам нужно быть осторожными в местах, где мы пишем CSS. В малых проектах всё может быть в порядке, однако в больших проектах задача может оказаться трудоёмкой. В результате стали появляться различные методы для организации CSS и, соответственно, сокращения проблем с каскадом. Первые три, что приходят мне на ум, это &lt;a href="http://getbem.com/introduction/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt;, &lt;a href="http://smacss.com/" rel="noopener noreferrer"&gt;Smacss&lt;/a&gt; от Jonathan Snook и &lt;a href="https://itcss.io/" rel="noopener noreferrer"&gt;Inverted Triangle CSS&lt;/a&gt; от Harry Roberts&lt;/p&gt;

&lt;p&gt;В этой статье мы рассмотрим, как работают каскадные слои и как они помогут нам писать CSS с большей уверенностью, а также примеры их использования.&lt;/p&gt;

&lt;h3&gt;
  
  
  Проблема
&lt;/h3&gt;

&lt;p&gt;Основная проблема, которую решают каскадные слои, это гарантированный способ написания CSS, не беспокоясь о специфичности и порядке исходного кода. Давайте обратимся к примеру, чтобы проиллюстрировать проблему.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zhscgsk6ao1ohsd0a51.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zhscgsk6ao1ohsd0a51.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;У нас есть кнопка с двумя стилями: default и ghost. В HTML мы будем их использовать следующим образом:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-actions"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Save edits&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button button--ghost"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cancel&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Всё отлично работает в этом случае. Но что, если у нас появился третий вариант кнопки и мы не можем написать его сразу после селектора &lt;code&gt;.button&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yvnnjb26qycw27dtypq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yvnnjb26qycw27dtypq.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.button&lt;/code&gt; идёт после &lt;code&gt;.button--facebook&lt;/code&gt;. В итоге он будет переопределён. В данном случае можно найти решение через повышение специфичности для &lt;code&gt;.button-facebook&lt;/code&gt;, например:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.some-parent&lt;/span&gt; &lt;span class="nc"&gt;.button--facebook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--brand-fb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Или можно сделать так (не повторяйте это в домашних условиях!):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.button--facebook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--brand-fb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Оба решения не так уж хороши. Намного лучше расположить их в корректном месте, прямо после &lt;code&gt;.button&lt;/code&gt;. Непростая работа без помощи CSS препроцессора  (например, Sass), который поможет разделить файлы CSS на части и компоненты.&lt;/p&gt;

&lt;h3&gt;
  
  
  Введение в CSS Cascade Layers (каскадные слои)
&lt;/h3&gt;

&lt;p&gt;Каскадные слои это новая CSS фича, которая позволяет разработчикам получать больший контроль над написанием CSS в больших проектах. По словам &lt;a href="https://www.w3.org/2021/10/TPAC/demos/css-architecture.html" rel="noopener noreferrer"&gt;автора спецификации&lt;/a&gt; Miriam Suzanne: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Каскадные слои позволят авторам управлять своей внутренней каскадной логикой, не полагаясь полностью на эвристику специфичности или исходный порядок.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Давайте применим каскадные слои для предыдущего примера.&lt;/p&gt;

&lt;p&gt;Для начала надо обозначит слой. Чтобы это сделать, мы напишем &lt;code&gt;@layer&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Я обозначил слой с именем &lt;code&gt;components&lt;/code&gt;. Внутри этого слоя мне нужно определить default стили кнопки.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d73a7c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Шик. Далее нужно добавить слой для вариаций.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d73a7c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button--ghost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#474747&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#e0e0e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Вот визуализация слоев. Они аналогичны слоям Photoshop, поскольку то, что определено последним в CSS, будет первым в списке слоев визуально.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesf52dhd8mceiuy5wze6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesf52dhd8mceiuy5wze6.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;В нашем примере &lt;code&gt;variation&lt;/code&gt; слой определен последним, поэтому он будет иметь более высокий приоритет, чем слой &lt;code&gt;components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Существует также другой способ организации того, какой слой переопределяет другой, путем одновременного определения слоев.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Вернёмся к нашему примеру. Основная проблема была в том, что нам нужно было создать новую вариацию кнопки, поместив её в место, где вариация бы имела меньшую специфичность (до &lt;code&gt;.button&lt;/code&gt;). С каскадными слоями мы можем добавить этот кусок в слой &lt;code&gt;variations&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d73a7c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button--ghost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#474747&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#e0e0e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.button--facebook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--brand-fb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Таким образом, мы всегда можем гарантировать, что вариация &lt;strong&gt;всегда&lt;/strong&gt; будет иметь приоритет над default стилями. Давайте рассмотрим объяснение выше визуально.&lt;/p&gt;

&lt;p&gt;Обратите внимание, как каждая кнопка живет в слое. Порядок соответствует определению &lt;code&gt;@layer&lt;/code&gt; вверху.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng94zjbzawf9n48aogrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng94zjbzawf9n48aogrp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Если поменять порядок, то слой &lt;code&gt;components&lt;/code&gt; будет переопределять слой &lt;code&gt;variations&lt;/code&gt; и default стили "победят". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcugfljpzcqtrvodragop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcugfljpzcqtrvodragop.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Добавление стилей в слои
&lt;/h3&gt;

&lt;p&gt;В каскадных слоях браузер комбинирует стили из одних и тех же селекторов &lt;code&gt;@layer&lt;/code&gt; и считывает их сразу в соответствии с их порядком.&lt;/p&gt;

&lt;p&gt;Рассмотрим следующее: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;..&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button--ghost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;..&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* 500 lines later */&lt;/span&gt;
&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;variations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button--facebook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;..&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Браузер поместит &lt;code&gt;.button--facebook&lt;/code&gt; прямо после &lt;code&gt;.button--ghost&lt;/code&gt; в слое &lt;code&gt;variations&lt;/code&gt;. Изображение для большей ясности:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtth8jx9no9m78dacg84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtth8jx9no9m78dacg84.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Поддержка браузеров
&lt;/h3&gt;

&lt;p&gt;Это самый важный вопрос, чтобы задуматься над новой фичей CSS. Согласно &lt;a href="https://caniuse.com/css-cascade-layers" rel="noopener noreferrer"&gt;Can I Use&lt;/a&gt; на момент написания этой статьи, она поддерживается в Firefox, Chrome, Safari TP. Можем ли мы использовать их в качестве enhancement? Нет, мы не можем. Если только мы не используем полифилл Javascript (которого пока нет).&lt;/p&gt;

&lt;h3&gt;
  
  
  Где в каскаде живут слои?
&lt;/h3&gt;

&lt;p&gt;Чтобы ответить на этот вопрос, давайте рассмотрим каскад в CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/TR/css-cascade-5/#cascading" rel="noopener noreferrer"&gt;CSS каскад&lt;/a&gt; упорядочен следующим образом (первые имеют больший приоритет):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Origin и importance&lt;/li&gt;
&lt;li&gt;Инлайн стилизация&lt;/li&gt;
&lt;li&gt;Слои&lt;/li&gt;
&lt;li&gt;Специфичность&lt;/li&gt;
&lt;li&gt;Порядок в коде
Рассмотрим следующий рисунок. Чем толще линия, тем приоритетнее стиль в каскаде.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzx1fa1wozxhft3nh9xnd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzx1fa1wozxhft3nh9xnd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Origin и importance
&lt;/h3&gt;

&lt;p&gt;Это две разные (но связанные) вещи, так что разберем каждую по-отдельности.&lt;/p&gt;

&lt;p&gt;Origin стили приходят из следующих вещей (сначала более приоритетные):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Стили разработчика (AKA авторские)&lt;/li&gt;
&lt;li&gt;Стили пользователя&lt;/li&gt;
&lt;li&gt;Стили браузера&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Это означает, что CSS, написанный разработчиком, всегда будет побеждать стили пользователя и браузера.&lt;/p&gt;

&lt;p&gt;Посмотрим пример.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Если пользователь попробует поменять стили браузера (font-size по-умолчанию в данном примере), то CSS выше всё равно его переопределит, так как стили разработчика приоритетнее пользовательских и браузерных.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3mk1nrfmgyl4osw1zc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3mk1nrfmgyl4osw1zc4.png"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Это плохая практика для accessibility (доступности). Пожалуйста, не делайте этого в продакшене. Я просто добавил это ради объяснения origin стилей.&lt;/p&gt;

&lt;p&gt;Что касается стилей браузера, они предназначены для user agent стилей. Например, по-умолчанию стиль &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; выглядит по-разному в браузерах. Мы можем его переопределить, как вы уже догадались, потому что стили разработчика имеют преимущество над стилями браузера.&lt;/p&gt;

&lt;p&gt;Если вы посмотрите на дефолтные стили кнопки, то увидите user agent stylesheet, которые как раз и показывают стили браузера у кнопки. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoynnrqs18p7oytki6l0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoynnrqs18p7oytki6l0.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Всё вышеописанное касалось &lt;strong&gt;стандартных/нормальных/обычных&lt;/strong&gt; правил. Это значит, что они не имеют ключевого слова &lt;code&gt;!important&lt;/code&gt;. В случае, если оно есть, то порядок приоритета будет следующим:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Стили браузера с important&lt;/li&gt;
&lt;li&gt;Стили пользователя с important&lt;/li&gt;
&lt;li&gt;Стили разработчика с important&lt;/li&gt;
&lt;li&gt;Обычные стили разработчика&lt;/li&gt;
&lt;li&gt;Обычные стили пользователя&lt;/li&gt;
&lt;li&gt;Обычные стили браузера&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Инлайн (inline) стили
&lt;/h3&gt;

&lt;p&gt;Если элемент имеет инлайн стили, то у него большая специфичность по сравнению с другими правилами того же importance уровня. &lt;/p&gt;

&lt;p&gt;В примере ниже, цвет кнопки будет &lt;code&gt;#fff&lt;/code&gt; так как инлайн стили в приоритете.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: #fff;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;От себя&lt;/em&gt;: Importance обеих стилей относятся к "Обычные стили разработчика", следовательно далее по уровню проверяется inline. Если бы был у них разный уровень importance, например  &lt;code&gt;color: #222; !important&lt;/code&gt;, то это правило отнеслось бы к категории "Стили разработчика с important", что приоритетнее, чем "Обычные стили разработчика". Тогда был бы цвет &lt;code&gt;#222&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Слои
&lt;/h3&gt;

&lt;p&gt;О, привет слои! Это новый гость в каскаде. Каскадные слои имеют больший приоритет, чем специфичность селектора. В следующем примере сможете ли вы угадать размер шрифта элемента &lt;code&gt;p&lt;/code&gt; в слое &lt;code&gt;custom&lt;/code&gt;?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;#page&lt;/span&gt; &lt;span class="nc"&gt;.prose&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Шрифт будет &lt;code&gt;2rem&lt;/code&gt;. В каскадных слоях не важна специфичность. Она будет проигнорирована, если элемент переопределен последующим слоем.&lt;/p&gt;

&lt;h3&gt;
  
  
  Специфичность
&lt;/h3&gt;

&lt;p&gt;После слоёв браузер смотри на правила CSS и определяет, какой из них побеждает по сравнению с другими, отталкиваясь от специфичности.&lt;/p&gt;

&lt;p&gt;Вот простой пример. &lt;code&gt;.button&lt;/code&gt; внутри &lt;code&gt;.newsletter&lt;/code&gt; имеет большую специфичность чем просто &lt;code&gt;.button&lt;/code&gt;. В итоге верхнее правило будет переопределено. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Побеждает */&lt;/span&gt;
&lt;span class="nc"&gt;.newsletter&lt;/span&gt; &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Порядок в коде
&lt;/h3&gt;

&lt;p&gt;Наконец порядок вступает в силу. Когда два элемента имеют одинаковую специфичность, тогда их порядок в документе определяет победителя (тот, что ниже "сильнее").&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.newsletter&lt;/span&gt; &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Побеждает */&lt;/span&gt;
&lt;span class="nc"&gt;.newsletter&lt;/span&gt; &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Теперь у вас есть понимание, где слои находятся в каскаде. Обратимся к нескольким примерам их использования. &lt;/p&gt;

&lt;h3&gt;
  
  
  Применение каскадных слоёв
&lt;/h3&gt;

&lt;p&gt;Я попробовал посмотреть в текущих проектах, где бы каскадных слои могли пригодиться и придумал несколько случаев.&lt;/p&gt;

&lt;h4&gt;
  
  
  Переключение UI темы
&lt;/h4&gt;

&lt;p&gt;В проекте, над которым я работаю, использование каскадных слоев для темизации UI будет идеальным решением. Проблема, которую он решает здесь, состоит в том, чтобы позволить мне, как разработчику, переключаться между темами без изменения CSS или изменения их порядка тем или иным образом.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;У меня есть несколько слоёв и последний это &lt;code&gt;themes&lt;/code&gt;. Слой &lt;code&gt;themes&lt;/code&gt; может в себе иметь несколько слоев (да, каскадные слои поддерживают вложенность).&lt;/p&gt;

&lt;p&gt;Обратите внимание, что вверху я определил &lt;code&gt;@layer custom, default&lt;/code&gt;. &lt;code&gt;default&lt;/code&gt; будет переопределять &lt;code&gt;custom&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;themes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1877f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d73a7c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Если вам потребуется переключить темы, нужно просто &lt;strong&gt;поменять порядок слоев&lt;/strong&gt; в первой строчке &lt;code&gt;@layer themes&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;themes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* Custom is active */&lt;/span&gt;
    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1877f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d73a7c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Сторонний CSS
&lt;/h4&gt;

&lt;p&gt;Я взял пример, в котором используется карусель &lt;a href="https://github.com/metafizzy/flickity" rel="noopener noreferrer"&gt;flickity&lt;/a&gt;. Посмотрите на все &lt;code&gt;! important&lt;/code&gt; значения.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.flickity-page-dots&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flickity-page-dots&lt;/span&gt; &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.35&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flickity-page-dots&lt;/span&gt; &lt;span class="nc"&gt;.dot.is-selected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;С каскадными слоями мы можем добавить сторонний CSS перед слоем компонентов. Мы можем импортировать внешний файл CSS и задать ему слой.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vendors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* Base styles */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Import a .css file and assign it to a layer */&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url(flickity.css)&lt;/span&gt; &lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vendors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.flickity-page-dots&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.dot.is-selected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Меньше переживать об ошибках специфичности
&lt;/h4&gt;

&lt;p&gt;Допустим, у нас есть компонент списка, и нам нужен вариант, в котором список имеет меньший margin.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__item list__item--compact"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Other items --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Поскольку псевдоселектор &lt;code&gt;:not&lt;/code&gt; придает элементу большую специфичность, его нельзя переопределить без повторного использования &lt;code&gt;:not&lt;/code&gt;. Рассмотрим следующее:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* Побеждает */&lt;/span&gt;
&lt;span class="nc"&gt;.list__item&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="m"&gt;#222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.list__item--compact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;.list__item--compact&lt;/code&gt; не будет переопределять &lt;code&gt;.list__item&lt;/code&gt;^ так как последний имеет большую специфичность из-за использования &lt;code&gt;:not&lt;/code&gt;. Чтобы все заработало, нам нужно написать следующее:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.list__item&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="m"&gt;#222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.list__item--compact&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Посмотрим, как с этой проблемой справятся каскадные слои.&lt;/p&gt;

&lt;p&gt;Представим, что &lt;code&gt;@layer list&lt;/code&gt; содержит &lt;code&gt;base&lt;/code&gt; и &lt;code&gt;overrides&lt;/code&gt; слои. В &lt;code&gt;overrides&lt;/code&gt; я написал альтернативный способ, и он работал, как и ожидалось, поскольку &lt;code&gt;overrides&lt;/code&gt; является последним слоем.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overrides&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;.list__item&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;overrides&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;.list__item--compact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Вложенные компоненты
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik3t8012ncsooy3sqi4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik3t8012ncsooy3sqi4c.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;В данном примере у нас есть список действий (лайк, комментарий) для основного элемента социальной ленты и еще один список для каждого комментария.&lt;/p&gt;

&lt;p&gt;Иконка у блока элемента ленты имеет размер &lt;code&gt;24px&lt;/code&gt;. В компоненте комментариев размер меньше.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.feed-item&lt;/span&gt; &lt;span class="nc"&gt;.c-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;comments&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.comment__icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Обратите внимание, что &lt;code&gt;.feed-item .c-icon&lt;/code&gt; имеет большую специфичность, чем &lt;code&gt;.comment__icon&lt;/code&gt;, но в этом фишка использования каскадных слоев!&lt;/p&gt;

&lt;h4&gt;
  
  
  Служебный (утилитный) CSS
&lt;/h4&gt;

&lt;p&gt;Мы привыкли добавлять &lt;code&gt;!important&lt;/code&gt; к служебным классам CSS, чтобы они &lt;strong&gt;всегда применялись&lt;/strong&gt; к элементу. С каскадными слоями мы можем разместить слов на последнем месте. &lt;/p&gt;

&lt;p&gt;Рассмотрим следующий пример. У нас есть header страницы с утилитным классом &lt;code&gt;p-0&lt;/code&gt;. Мы хотим сбросить padding до 0.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"c-page-header p-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Content --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Вот как это выглядит с каскадными слоями.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vendors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;page-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;.c-page-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.p-0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Больше подробностей о каскадных слоях
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Стили без слоя имеют большую специфичность
&lt;/h4&gt;

&lt;p&gt;Если есть стили CSS, которые не назначены слою, то они будут добавлены к неявному &lt;strong&gt;последнему&lt;/strong&gt; слою.&lt;/p&gt;

&lt;p&gt;Рассмотрим следующий пример.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;lightgrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c"&gt;/* Base styles */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;В этом примере правило &lt;code&gt;.button&lt;/code&gt; определено без &lt;code&gt;@layer&lt;/code&gt;, однако браузер поместит его в неявный слой.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c"&gt;/* Base styles */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;/* Implicit layer */&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;lightgrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Вывод&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Каскадные слои — обалденная CSS фича, и, как вы видели в примерах, она может быть весьма полезной. Единственным ограничением для меня является то, что мы не сможем использовать его как улучшение (enhancement) только с помощью CSS. Это может немного замедлить внедрение слоев в веб-сообществе.&lt;/p&gt;

&lt;h3&gt;
  
  
  Для дальнейшего изучения
&lt;/h3&gt;

&lt;p&gt;-&lt;a href="https://www.bram.us/2021/09/15/the-future-of-css-cascade-layers-css-at-layer/" rel="noopener noreferrer"&gt;The Future of CSS: Cascade Layers&lt;/a&gt; by Bramus Van Damme&lt;br&gt;
-&lt;a href="https://www.smashingmagazine.com/2022/01/introduction-css-cascade-layers/" rel="noopener noreferrer"&gt;Getting Started With CSS Cascade Layers&lt;/a&gt; by Stephanie Eckles&lt;br&gt;
-&lt;a href="https://developer.chrome.com/blog/cascade-layers/" rel="noopener noreferrer"&gt;Cascade layers are coming to your browser&lt;/a&gt; by Una Kravets&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>NPM dependencies. В какую категорию импортировать пакет?</title>
      <dc:creator>Arif Balaev</dc:creator>
      <pubDate>Tue, 23 Nov 2021 20:08:38 +0000</pubDate>
      <link>https://dev.to/balaevarif/npm-dependencies-v-kakuiu-katieghoriiu-importirovat-pakiet-18dm</link>
      <guid>https://dev.to/balaevarif/npm-dependencies-v-kakuiu-katieghoriiu-importirovat-pakiet-18dm</guid>
      <description>&lt;h2&gt;
  
  
  Какие есть категории зависимостей?
&lt;/h2&gt;

&lt;p&gt;Обратимся к &lt;a href="https://docs.npmjs.com/cli/v7/configuring-npm/package-json"&gt;официальной документации от NPM&lt;/a&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;dependencies&lt;/li&gt;
&lt;li&gt;devDependencies&lt;/li&gt;
&lt;li&gt;peerDependencies&lt;/li&gt;
&lt;li&gt;peerDependenciesMeta&lt;/li&gt;
&lt;li&gt;bundledDependencies&lt;/li&gt;
&lt;li&gt;optionalDependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Отличия
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;dependencies - то, что реально нужно проекту в production режиме. Например, утилитные библиотеки react, lodash, classnames итп&lt;/li&gt;
&lt;li&gt;devDependencies - нужны во время разработки (dev). К таким библиотекам могут отнестись: 

&lt;ol&gt;
&lt;li&gt;библиотеки форматирования - eslint, prettier, ... &lt;/li&gt;
&lt;li&gt;сборщики: webpack, rollup, ...&lt;/li&gt;
&lt;li&gt;babel&lt;/li&gt;
&lt;li&gt;всё, что связано с тестированием&lt;/li&gt;
&lt;li&gt;другие библиотеки, такие как storybook&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;peerDependencies - нужен для публикации своего пакета. В эту категорию попадают зависимости, без которых ваш пакет будет работать некорректно. Проекту, устанавливающему ваш пакет нужно убедиться, что у него загружены все зависимости из peerDependencies&lt;/li&gt;
&lt;li&gt;peerDependenciesMeta - мета-данные для peerDependencies. Например, чтобы сделать какую-то зависимость опциональной. Хотя, тогда не понятно, зачем она находится в peerDependencies. &lt;/li&gt;
&lt;li&gt;bundledDependencies - выполняют схожую функциональность, что и обычные dependencies - входят в финальную сборку. Но они решают следующий пример: проект использует пакет1, в котором есть зависимость пакет2 внутри bundledDependencies. Если по каким-то причинам пакет2 будет снят с пубикации и до него не будет доступа, то пакет1 будет всё равно иметь эту зависимость внутри себя до тех пор, пока явно не почистить node_modules или не убрать пакет2 из зависимости пакета1. &lt;/li&gt;
&lt;li&gt;optionalDependencies - то же, что и dependencies, только в случае ошибки их подгрузки сборка не падает&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Перед тем как импортировать зависимость в свой проект, не забудьте спросить себя "А она точно мне нужна?". Может быть вам нужна какая-то малая ее часть, которую вы сможете написать самостоятельно. Но выбор между собственной имплементацией и сторонней - это уже отдельная тема.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;twitter &lt;a href="https://twitter.com/balaevarif"&gt;@balaevarif&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
