! Please make sure that you are using the latest version of Sass, LESS, or Stylus transformer before doing the setup. !
Using postcss-css-variables you can use most of CSS variables features, including selector cascading with some caveats, because this can only see the CSS, not the potentially dynamic HTML and DOM the CSS is applied to.
If you are already using react-native-css-transformer
, then need to switch to use react-native-postcss-transformer
(please refer to the setup documentation) and add a PostCSS config with postcss-css-variables plugin.
If you are using the typed transformers (e.g. generates mystyles.d.scss
typings for Sass files), then you can use the normal transformers for Sass/Less/Stylus and a typed transformer for PostCSS. This is because with CSS variables you are using two transformers together and only one of the transformers needs to create the types file.
For example when using Sass: react-native-sass-transformer
+ react-native-typed-postcss-transformer
.
- Setup React Native CSS modules with CSS support
- Setup React Native CSS modules with PostCSS support
- Setup React Native CSS modules with Sass support
- Setup React Native CSS modules with Less support
- Setup React Native CSS modules with Stylus support
Install PostCSS, postcss-css-variables plugin, and react-native-postcss-transformer.
yarn add postcss postcss-css-variables react-native-postcss-transformer --dev
Add postcss-css-variables
to your PostCSS configuration with one of the supported config formats, e.g. package.json
, .postcssrc
, postcss.config.js
, etc.
This example is for Sass, if you are using Less or Stylus, switch react-native-sass-transformer
to react-native-less-transformer
/react-native-stylus-transformer
and change the file extensions .scss
and .sass
to .less
/.styl
.
To make CSS variables work, we first need to render Sass to CSS, and then pass that to PostCSS.
Create a transformer.js
file to your project's root and do the following:
// For React Native version 0.59 or later
var upstreamTransformer = require("metro-react-native-babel-transformer");
// For React Native version 0.56-0.58
// var upstreamTransformer = require("metro/src/reactNativeTransformer");
// For React Native version 0.52-0.55
// var upstreamTransformer = require("metro/src/transformer");
// For React Native version 0.47-0.51
// var upstreamTransformer = require("metro-bundler/src/transformer");
// For React Native version 0.46
// var upstreamTransformer = require("metro-bundler/build/transformer");
var sassTransformer = require("react-native-sass-transformer");
var postCSSTransformer = require("react-native-postcss-transformer");
module.exports.transform = function ({ src, filename, options }) {
if (filename.endsWith(".scss") || filename.endsWith(".sass")) {
return sassTransformer
.renderToCSS({ src, filename, options })
.then((css) =>
postCSSTransformer.transform({ src: css, filename, options })
);
} else {
return upstreamTransformer.transform({ src, filename, options });
}
};
In metro.config.js
point the babelTransformerPath
to transformer.js
file:
-babelTransformerPath: require.resolve("react-native-sass-transformer")
+babelTransformerPath: require.resolve("./transformer.js")