Как применить глобальные стили с модулями CSS в приложении React?

В настоящее время я использую CSS-модули с React для своего стиля. Итак, каждый из моих компонентов импортируется в свой файл css для конкретного компонента, например:

import React from 'react';
import styles from './App.css';

const example = () => (
  <div className={styles.content}>
    Hello World!
  </div>
);

export default example;

Это отлично работает при стилизации отдельных компонентов, но как применить глобальный стиль (html, body, теги заголовков, div и т. Д.), Не зависящий от компонента?


person hidace    schedule 01.10.2016    source источник
comment
Почему бы не сделать require('./App.css'); в корневом компоненте?   -  person elmeister    schedule 01.10.2016


Ответы (6)


Поскольку вы используете синтаксис импорта ES6, вы можете использовать тот же синтаксис для импорта своей таблицы стилей.

import './App.css'

Кроме того, вы можете обернуть свой класс :global, чтобы переключиться на глобальную область видимости (это означает, что модуль CSS не будет модулировать его, например: добавление случайного идентификатора рядом с ним)

:global(.myclass) {
  background-color: red;
}
person felixyadomi    schedule 16.10.2016
comment
Для меня имена классов из файла, импортированного как import './App.css', просто не имеют никакого эффекта. Он работает только со вторым фрагментом кода. Это мое первое знакомство с этой штукой с модулями CSS, и я уже ненавижу ее за то, что она ломает вещи, которые работали тысячелетиями. - person Mikhail Batcer; 31.03.2019
comment
@MikhailBatcer То же самое произошло и со мной. На самом деле мне нужно использовать именованный импорт, а затем применять классы. import classes from './App.css', а затем примените classes.Myclass - person Faizan Mubasher; 24.07.2019
comment
@FaizanMubasher Да, именованный импорт у меня тоже сработал. - person Mikhail Batcer; 25.07.2019
comment
@felixyadomi спасибо большое, чувак! Это было именно то, что я искал! - person Gustavo Garcia; 21.10.2019

Это можно сделать, просто добавив:

require('./App.css');

(спасибо @elmeister, правильно ответившему на этот вопрос.)

person hidace    schedule 06.10.2016
comment
Или, чтобы не смешивать модули es с commonjs, просто import './App.css' - person riscarrott; 15.10.2016

Я столкнулся с той же проблемой и нашел следующие способы решения проблемы, вы можете выбрать то, что подходит вам лучше всего

  1. Define two sets of rules in your webpack config for parsing css/less files.
    • The first rule should be to include all global styles, assuming it's kept in /styles/ or similar directory.
    • Второе правило - обрабатывать все стили CSS с локальной областью видимости, в идеале они должны находиться рядом с их компонентами.
    • Это можно сделать с помощью параметра включить и исключить при определении правила.
    • или путем обеспечения соблюдения соглашения об именах и правила записи соответственно, например, все модули css будут иметь формат [name] .module.css, и ваш тест будет проверять наличие /.module.(less|css) $ / и проанализируйте его.

Ниже приводится образец:

      // exclude all global styles for css modules
      {
        test: /\.(less|css)$/,
        exclude: path.resolve(__dirname, './src/styles'),
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]'
                }
            }
          },
          "postcss-loader",
          "less-loader"
        ]
      },
      // process global styles without css modules
     {
        test: /\.(less|css)$/,
        include: path.resolve(__dirname, './src/styles'),
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          "css-loader",
          "postcss-loader",
          "less-loader"
        ]
      }
  1. Используйте : local и: global при написании css / less. Если модули css включены, по умолчанию используется локальный режим, вы можете указать режим в параметрах, как показано ниже:
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]', 
                    mode: 'global',
                }
            }
          },

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

/* this will remain as is */
.header {
   color: blue;
}

:local {
  /* this will become something like item_xSH2sa */
  .item {
   color: yellow;
  }
}

  1. Определите функцию, которая проверяет ваш файл, чтобы решить, является ли он модулем css или глобальным, используя параметр getLocalIdent. Это метод, который я сейчас использую в своей настройке. Это также требует, чтобы ваши файлы имели некоторое соглашение об именах: [name] .module.less для модулей css и [name] .less для обычных файлов. См. Пример ниже:
// regex to test for modules, loaderUtils is part of webpack dependencies
const cssModuleRegex = new RegExp(/\.module\.(less|css)$/);
const loaderUtils = require("loader-utils");

// inside webpack rules
      {
        test: /\.(less|css)$/,
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]', 
                    getLocalIdent: getLocalIdent
                }
            }
          },
          "postcss-loader",
          "less-loader"
        ]
      }

// this is a copy of the default function, modified slightly to achieve our goal
function getLocalIdent(loaderContext, localIdentName, localName, options) {

    // return local name if it's a global css file
    if (!cssModuleRegex.test(loaderContext.resourcePath)) {
        return localName;
    }

    if (!options.context) {
      // eslint-disable-next-line no-param-reassign
      options.context = loaderContext.rootContext;
    }

    const request = path
      .relative(options.context, loaderContext.resourcePath)
      .replace(/\\/g, '/');

    // eslint-disable-next-line no-param-reassign
    options.content = `${options.hashPrefix + request}+${localName}`;

    // eslint-disable-next-line no-param-reassign
    localIdentName = localIdentName.replace(/\[local\]/gi, localName);

    const hash = loaderUtils.interpolateName(
      loaderContext,
      localIdentName,
      options
    );

    return hash
      .replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-')
      .replace(/^((-?[0-9])|--)/, '_$1');
  }

person ksankar    schedule 01.10.2019
comment
Последнее решение - прелесть, спасибо, что поделились! - person Ege; 26.01.2021

Единственный способ, который я нашел для глобального импорта стилей, но только для определенного маршрута, - это добавить:

<style dangerouslySetInnerHTML={{__html: `
  body { max-width: 100% }
`}} />

внутри возврата метода render.

В противном случае тег style будет добавлен к <head>, и стили будут применены для всех следующих маршрутов.

Из https://medium.learnreact.com/the-style-tag-and-react-24d6dd3ca974

Возможно, стили можно будет импортировать в виде строки из файла, чтобы код был более организованным.

person Manolo    schedule 17.04.2018

Другой простой способ использовать модуль css:

<style jsx global>{`
     .slick-prev:before,
     .slick-next:before {
         color: somecolor;
      }
`}</style>
person shahryar ab    schedule 07.01.2021

Решение 1.

Импортируйте глобальные стили в начальную точку reactapp.
, где все приложение React было wrapped в корневом компоненте.
это может быть index.js, app.js или index.html

Решение 2:

используйте scss и создайте main.scss файл и импортируйте все другие особо необходимые custom scss файлы в main.scss

person Naveen Jain    schedule 01.10.2019