В чем преимущество использования :local в CSS-файлах?

#css #reactjs #webpack

Вопрос:

Я изучал использование CSS в React и столкнулся с идеей модулей CSS, в рамках которой я наткнулся на эту статью https://blog.fearcat.in/a?ID=00550-af5ece9b-eb49-4e13-8711-26e00c48c84e в котором обсуждается использование :global и :local в файлах CSS, но в одном месте упоминается об этом

:локальный(.className) , что эквивалентно .className

Итак, из этой статьи я понимаю, что использование :global приведет к тому, что правило CSS будет на глобальном уровне, но зачем использовать :local, если это эквивалентно просто наличию .className? похоже, нет никакой функциональной разницы.

Ответ №1:

По умолчанию CSS в модулях CSS является локальным. Но когда вы используете :global классификатор/блок, и внутри этого, если вы хотите вернуться к local CSS, вам следует это сделать.

Представьте, что вы используете global режим для модулей CSS с использованием css-loader опций:

 module: {
  rules: [
    {
      test: /.css$/i,
      use: [
        MiniCssExtractPlugin.loader,
        {
          loader: 'css-loader',
          options: {
            // THIS IS IMPORTANT
            modules: 'global'
          }
        }
      ],
    }
  ]
}
 

Для приведенной выше конфигурации рассмотрим следующий пример:

 .abc { color: red; }

:global(.abc) { color: green; }

:local .xyz { color: blue; }

:local(.xyz) .pqr { color: yellow; }

.abc :local .xyz .pqr { color: cyan; }
 

Он будет скомпилирован в следующий CSS.

 /* Since it is global model for CSS modules, classname is not hashed */
.abc { color: red; }

/* .global(.abc) has no effect here */
.abc { color: green; }

/* :local .xyz means anything after :local will be hashed */
.dkzEiLgPjIar3vTOyiHv { color: blue; }

/* .local(.xyz) .pqr means only .xyz is hashed */
.dkzEiLgPjIar3vTOyiHv .pqr { color: yellow; }

/* Everything after the :local is hashed i.e. both .xyz and .pqr */
.abc .dkzEiLgPjIar3vTOyiHv .k3SKPTpkzRcircxhU4Dd { color: cyan; }
 

Разница между :локальным и :локальным(селектор) неуловима. Первый является агрессивным (хэшированный селектор после него), а второй-снисходительным. Та же, но обратная логика применима, если я использую область CSS как локальную, т. Е. modules: true или modules: 'local' .

Теперь к вашему вопросу, зачем мне использовать :локально внутри :глобально, когда у меня есть какой-то компонент, стили которого следует изменять, когда он находится внутри какого-либо компонента или компонента верхнего уровня. Представьте себе, размер a .text должен быть 18 пикселей, когда он находится внутри .blogArticle . В противном случае этот компонент по умолчанию должен отображаться как 14px :

 :local .text { font-size: 14px; }
.blogArticle :local(.text) { font-size: 18px ;}
 

Но в целом вы правы. Вам редко нужно было бы помещать local внутрь global . Единственная причина, по которой вы будете это делать, — это устаревший сложный CSS, который вы переносите на более новую кодовую базу и хотите, чтобы связанные блоки CSS были ближе друг к другу для лучшей читаемости. И последнее, но не менее важное: рассмотрите глубокий вложенный устаревший CSS, подобный этому:

 .abc :local .xyz .pqr :global(.def) {
  color: cyan;
}
 

Я начинаю global , затем переключаюсь на :local , а затем снова на :global(.def) . Но необходимость сделать это-хороший случай защиты от запаха шаблона/кода.

Комментарии:

1. Спасибо, Харшал, не могли бы вы дать мне представление о том, во что это будет скомпилировано в качестве CSS? потому что вы смешиваете локальный класс внутри глобального, который кажется запутанным, изложенным вот так. Был бы отличный пример того, как его можно использовать, спасибо

2. @jobe обновил ответ.

3. Однако они компилируются в 2 отдельных класса? какой смысл помещать :локальный внутри :глобального здесь, если они используются отдельно, один, похоже, не влияет на другой в вашем примере. Извините, это было неясно

4. @jobe Я так и думал, что ты спросишь. Обновил ответ с более подробным объяснением.

5. @jobe Действительно прав. При использовании :global , а затем вы захотите переключиться обратно :local , тогда вам это понадобится.

Ответ №2:

Существует разница, когда у вас будет одно и то же имя класса в нескольких компонентах. Например, у вас есть compoment A с <div className={classes.wrapper}> , а затем у вас есть Component B с <div className={classes.wrapper} . При обычном css, если атрибуты в файле css этого класса «оболочки» будут отличаться, они будут превосходить первый последним. Это похоже на заблокированную область в вашем компоненте и не «живет» вдали от компонента. И, конечно, вы можете добавить любой другой атрибут в файл global.css, который будет присутствовать во всем проекте

 .wrapper{                //component A
  display:flex;
  flex-direction:column;
}

.wrapper {              //component B
  display:flex;
  flex-direction:column;
  width:60%;
}
 

При обычном css последние атрибуты будут совпадать с первыми .wrapper , поэтому с модулями на 100% не совпадает ваш стиль div .