The `css-loader` interprets `@import` and `url()` like `import/require()` and will resolve them.
## Getting Started
> **Warning**
>
> To use css-loader, webpack@5 is required
To begin, you'll need to install `css-loader`:
```console
npm install --save-dev css-loader
```
or
```console
yarn add -D css-loader
```
or
```console
pnpm add -D css-loader
```
Then add the plugin to your `webpack` config. For example:
**file.js**
```js
import css from "file.css";
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
```
And run `webpack` via your preferred method.
If, for one reason or another, you need to extract CSS as a file (i.e. do not store CSS in a JS module) you might want to check out the [recommend example](https://github.com/webpack-contrib/css-loader#recommend).
Allow to enable/disables handling the CSS functions `url` and `image-set`.
If set to `false`, `css-loader` will not parse any paths specified in `url` or `image-set`.
A function can also be passed to control this behavior dynamically based on the path to the asset.
Starting with version [4.0.0](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md#400-2020-07-25), absolute paths are parsed based on the server root.
Allows to enable/disable CSS Modules or ICSS and setup configuration:
- `undefined` - enable CSS modules for all files matching `/\.module\.\w+$/i.test(filename)` and `/\.icss\.\w+$/i.test(filename)` regexp.
- `true` - enable CSS modules for all files.
- `false` - disables CSS Modules for all files.
- `string` - disables CSS Modules for all files and set the `mode` option, more information you can read [here](https://github.com/webpack-contrib/css-loader#mode)
- `object` - enable CSS modules for all files, if `modules.auto` option is not specified, otherwise the `modules.auto` option will determine whether if it is CSS modules or not, more information you can read [here](https://github.com/webpack-contrib/css-loader#auto)
The `modules` option enables/disables the **[CSS Modules](https://github.com/css-modules/css-modules)** specification and setup basic behaviour.
Using `false` value increase performance because we avoid parsing **CSS Modules** features, it will be useful for developers who use vanilla css or use other technologies.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: true,
},
},
],
},
};
```
#### `Features`
##### `Scope`
Using `local` value requires you to specify `:global` classes.
Using `global` value requires you to specify `:local` classes.
Using `pure` value requires selectors must contain at least one local class or id.
You can find more information [here](https://github.com/css-modules/css-modules).
Styles can be locally scoped to avoid globally scoping styles.
The syntax `:local(.className)` can be used to declare `className` in the local scope. The local identifiers are exported by the module.
With `:local` (without brackets) local mode can be switched on for this selector.
The `:global(.className)` notation can be used to declare an explicit global selector.
With `:global` (without brackets) global mode can be switched on for this selector.
The loader replaces local selectors with unique identifiers. The chosen unique identifiers are exported by the module.
> We strongly recommend that you specify the extension when importing a file, since it is possible to import a file with any extension and it is not known in advance which file to use.
```css
:local(.continueButton) {
composes: button from "library/button.css";
background: red;
}
```
```css
:local(.nameEdit) {
composes: edit highlight from "./edit.css";
background: red;
}
```
To import from multiple modules use multiple `composes:` rules.
```css
:local(.className) {
composes: edit highlight from "./edit.css";
composes: button from "module/button.css";
composes: classFromThisModule;
background: red;
}
```
##### `Values`
You can use `@value` to specific values to be reused throughout a document.
We recommend use prefix `v-` for values, `s-` for selectors and `m-` for media at-rules.
```css
@value v-primary: #BF4040;
@value s-black: black-selector;
@value m-large: (min-width: 960px);
.header {
color: v-primary;
padding: 0 10px;
}
.s-black {
color: black;
}
@media m-large {
.header {
padding: 0 20px;
}
}
```
#### `boolean`
Enable **CSS Modules** features.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: true,
},
},
],
},
};
```
#### `string`
Enable **CSS Modules** features and setup `mode`.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
// Using `local` value has same effect like using `modules: true`
modules: "global",
},
},
],
},
};
```
#### `object`
Enable **CSS Modules** features and setup options for them.
type auto = boolean | regExp | ((resourcePath: string) => boolean);
```
Default: `undefined`
Allows auto enable CSS modules/ICSS based on filename when `modules` option is object.
Possible values:
- `undefined` - enable CSS modules for all files.
- `true` - enable CSS modules for all files matching `/\.module\.\w+$/i.test(filename)` and `/\.icss\.\w+$/i.test(filename)` regexp.
- `false` - disables CSS Modules.
- `RegExp` - enable CSS modules for all files matching `/RegExp/i.test(filename)` regexp.
- `function` - enable CSS Modules for files based on the filename satisfying your filter function check.
###### `boolean`
Possible values:
- `true` - enables CSS modules or interoperable CSS format, sets the [`modules.mode`](#mode) option to `local` value for all files which satisfy `/\.module(s)?\.\w+$/i.test(filename)` condition or sets the [`modules.mode`](#mode) option to `icss` value for all files which satisfy `/\.icss\.\w+$/i.test(filename)` condition
- `false` - disables CSS modules or interoperable CSS format based on filename
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
auto: true,
},
},
},
],
},
};
```
###### `RegExp`
Enable CSS modules for files based on the filename satisfying your regex check.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
auto: /\.custom-module\.\w+$/i,
},
},
},
],
},
};
```
###### `function`
Enable CSS modules for files based on the filename satisfying your filter function check.
Setup `mode` option. You can omit the value when you want `local` mode.
Controls the level of compilation applied to the input styles.
The `local`, `global`, and `pure` handles `class` and `id` scoping and `@value` values.
The `icss` will only compile the low level `Interoperable CSS` format for declaring `:import` and `:export` dependencies between CSS and other languages.
ICSS underpins CSS Module support, and provides a low level syntax for other tools to implement CSS-module variations of their own.
###### `string`
Possible values - `local`, `global`, `pure`, and `icss`.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
mode: "global",
},
},
},
],
},
};
```
###### `function`
Allows set different values for the `mode` option based on a filename
Possible return values - `local`, `global`, `pure` and `icss`.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
// Callback must return "local", "global", or "pure" values
mode: (resourcePath) => {
if (/pure.css$/i.test(resourcePath)) {
return "pure";
}
if (/global.css$/i.test(resourcePath)) {
return "global";
}
return "local";
},
},
},
},
],
},
};
```
##### `localIdentName`
Type:
```ts
type localIdentName = string;
```
Default: `'[hash:base64]'`
Allows to configure the generated local ident name.
- `[folder]` the folder the resource relative to the `compiler.context` option or `modules.localIdentContext` option.
- `[path]` the path of the resource relative to the `compiler.context` option or `modules.localIdentContext` option.
- `[file]` - filename and path.
- `[ext]` - extension with leading `.`.
- `[hash]` - the hash of the string, generated based on `localIdentHashSalt`, `localIdentHashFunction`, `localIdentHashDigest`, `localIdentHashDigestLength`, `localIdentContext`, `resourcePath` and `exportName`
- `[<hashFunction>:hash:<hashDigest>:<hashDigestLength>]` - hash with hash settings.
- `[local]` - original class.
Recommendations:
- use `'[path][name]__[local]'` for development
- use `'[hash:base64]'` for production
The `[local]` placeholder contains original class.
**Note:** all reserved (`<>:"/\|?*`) and control filesystem characters (excluding characters in the `[local]` placeholder) will be converted to `-`.
Should local name be used when computing the hash.
- `'resource-path-and-local-name'` Both resource path and local name are used when hashing. Each identifier in a module gets its own hash digest, always.
- `'minimal-subset'` Auto detect if identifier names can be omitted from hashing. Use this value to optimize the output for better GZIP or Brotli compression.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
hashStrategy: "minimal-subset",
},
},
},
],
},
};
```
##### `localIdentRegExp`
Type:
```ts
type localIdentRegExp = string | RegExp;
```
Default: `undefined`
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentRegExp: /page-(.*)\.css/i,
},
},
},
],
},
};
```
##### `getLocalIdent`
Type:
```ts
type getLocalIdent = (
context: LoaderContext,
localIdentName: string,
localName: string
) => string;
```
Default: `undefined`
Allows to specify a function to generate the classname.
By default we use built-in function to generate a classname.
If the custom function returns `null` or `undefined`, we fallback to the
| **`'asIs'`** | `string` | Class names will be exported as is. |
| **`'camelCase'`** | `string` | Class names will be camelized, the original class name will not to be removed from the locals |
| **`'camelCaseOnly'`** | `string` | Class names will be camelized, the original class name will be removed from the locals |
| **`'dashes'`** | `string` | Only dashes in class names will be camelized |
| **`'dashesOnly'`** | `string` | Dashes in class names will be camelized, the original class name will be removed from the locals |
**file.css**
```css
.class-name {
}
```
**file.js**
```js
import { className } from "file.css";
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: "camelCase",
},
},
},
],
},
};
```
###### `function`
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
};
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: function (name) {
return [
name.replace(/-/g, "_"),
// dashesCamelCase
name.replace(/-+(\w)/g, (match, firstLetter) =>
firstLetter.toUpperCase()
),
];
},
},
},
},
],
},
};
```
##### `exportOnlyLocals`
Type:
```ts
type exportOnlyLocals = boolean;
```
Default: `false`
Export only locals.
**Useful** when you use **css modules** for pre-rendering (for example SSR).
For pre-rendering with `mini-css-extract-plugin` you should use this option instead of `style-loader!css-loader` **in the pre-rendering bundle**.
It doesn't embed CSS but only exports the identifier mappings.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportOnlyLocals: true,
},
},
},
],
},
};
```
### `importLoaders`
Type:
```ts
type importLoaders = number;
```
Default: `0`
Allows to enables/disables or setups number of loaders applied before CSS loader for `@import` at-rules, CSS modules and ICSS imports, i.e. `@import`/`composes`/`@value value from './values.css'`/etc.
The option `importLoaders` allows you to configure how many loaders before `css-loader` should be applied to `@import`ed resources and CSS modules/ICSS imports.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
// 0 => no loaders (default);
// 1 => postcss-loader;
// 2 => postcss-loader, sass-loader
},
},
"postcss-loader",
"sass-loader",
],
},
],
},
};
```
This may change in the future when the module system (i. e. webpack) supports loader matching by origin.
### `sourceMap`
Type:
```ts
type sourceMap = boolean;
```
Default: depends on the `compiler.devtool` value
By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option. All values enable source map generation except `eval` and `false` value.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
sourceMap: true,
},
},
],
},
};
```
### `esModule`
Type:
```ts
type esModule = boolean;
```
Default: `true`
By default, `css-loader` generates JS modules that use the ES modules syntax.
There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).
You can enable a CommonJS modules syntax using:
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
esModule: false,
},
},
],
},
};
```
### `exportType`
Type:
```ts
type exportType = "array" | "string" | "css-style-sheet";
```
Default: `'array'`
Allows exporting styles as array with modules, string or [constructable stylesheet](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) (i.e. [`CSSStyleSheet`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet)).
Default value is `'array'`, i.e. loader exports array of modules with specific API which is used in `style-loader` or other.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
assert: { type: "css" },
loader: "css-loader",
options: {
exportType: "css-style-sheet",
},
},
],
},
};
```
**src/index.js**
```js
import sheet from "./styles.css" assert { type: "css" };
document.adoptedStyleSheets = [sheet];
shadowRoot.adoptedStyleSheets = [sheet];
```
#### `'array'`
The default export is array of modules with specific API which is used in `style-loader` or other.
> You don't need [`style-loader`](https://github.com/webpack-contrib/style-loader) anymore, please remove it.
> **Warning**
>
> The `esModules` option should be enabled if you want to use it with [`CSS modules`](https://github.com/webpack-contrib/css-loader#modules), by default for locals will be used [named export](https://github.com/webpack-contrib/css-loader#namedexport).
> `@import` rules not yet allowed, more [information](https://web.dev/css-module-scripts/#@import-rules-not-yet-allowed)
> **Warning**
>
> You don't need [`style-loader`](https://github.com/webpack-contrib/style-loader) anymore, please remove it.
> **Warning**
>
> The `esModules` option should be enabled if you want to use it with [`CSS modules`](https://github.com/webpack-contrib/css-loader#modules), by default for locals will be used [named export](https://github.com/webpack-contrib/css-loader#namedexport).
> **Warning**
>
> Source maps are not currently supported in `Chrome` due [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1174094&q=CSSStyleSheet%20source%20maps&can=2)
The default export is a [constructable stylesheet](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) (i.e. [`CSSStyleSheet`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet)).
Useful for [custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) and shadow DOM.
More information:
- [Using CSS Module Scripts to import stylesheets](https://web.dev/css-module-scripts/)
import sheet from "./styles.css" assert { type: "css" };
document.adoptedStyleSheets = [sheet];
shadowRoot.adoptedStyleSheets = [sheet];
```
For migration purposes, you can use the following configuration:
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
oneOf: [
{
assert: { type: "css" },
loader: "css-loader",
options: {
exportType: "css-style-sheet",
// Other options
},
},
{
use: [
"style-loader",
{
loader: "css-loader",
options: {
// Other options
},
},
],
},
],
},
],
},
};
```
## Examples
### Recommend
For `production` builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
This can be achieved by using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin), because it creates separate css files.
For `development` mode (including `webpack-dev-server`) you can use [style-loader](https://github.com/webpack-contrib/style-loader), because it injects CSS into the DOM using multiple <style></style> and works faster.
> **Note**
>
> Do not use `style-loader` and `mini-css-extract-plugin` together.
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background: url("./url/img.png"),
/* webpackIgnore: true */ url("./url/img.png");
}
/* prettier-ignore */
.class {
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background: url("./url/img.png"),
/* webpackIgnore: true */
url("./url/img.png");
}
/* prettier-ignore */
.class {
/* Disabled url handling for third and sixth urls in the 'background-image' declaration */
background-image: image-set(
url(./url/img.png) 2x,
url(./url/img.png) 3x,
/* webpackIgnore: true */ url(./url/img.png) 4x,
url(./url/img.png) 5x,
url(./url/img.png) 6x,
/* webpackIgnore: true */
url(./url/img.png) 7x
);
}
```
### Assets
The following `webpack.config.js` can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory.
// More information here https://webpack.js.org/guides/asset-modules/
type: "asset",
},
],
},
};
```
### Extract
For production builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
- This can be achieved by using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract the CSS when running in production mode.
- As an alternative, if seeking better development performance and css outputs that mimic production. [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin) offers a hot module reload friendly, extended version of mini-css-extract-plugin. HMR real CSS files in dev, works like mini-css in non-dev
### Pure CSS, CSS modules and PostCSS
When you have pure CSS (without CSS modules), CSS modules and PostCSS in your project you can use this setup:
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
// For pure CSS - /\.css$/i,
// For Sass/SCSS - /\.((c|sa|sc)ss)$/i,
// For Less - /\.((c|le)ss)$/i,
test: /\.((c|sa|sc)ss)$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
// Run `postcss-loader` on each CSS `@import` and CSS modules/ICSS imports, do not forget that `sass-loader` compile non CSS `@import`'s into a single file
// If you need run `sass-loader` and `postcss-loader` on each CSS `@import` please set it to `2`
// More information here https://webpack.js.org/guides/asset-modules/
type: "asset",
},
],
},
};
```
### Resolve unresolved URLs using an alias
**index.css**
```css
.class {
background: url(/assets/unresolved/img.png);
}
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
resolve: {
alias: {
"/assets/unresolved/img.png": path.resolve(
__dirname,
"assets/real-path-to-img/img.png"
),
},
},
};
```
### Named export with custom export names
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
namedExport: true,
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
};
```
### Separating `Interoperable CSS`-only and `CSS Module` features
The following setup is an example of allowing `Interoperable CSS` features only (such as `:import` and `:export`) without using further `CSS Module` functionality by setting `mode` option for all files that do not match `*.module.scss` naming convention. This is for reference as having `ICSS` features applied to all files was default `css-loader` behavior before v4.
Meanwhile all files matching `*.module.scss` are treated as `CSS Modules` in this example.
An example case is assumed where a project requires canvas drawing variables to be synchronized with CSS - canvas drawing uses the same color (set by color name in JavaScript) as HTML background (set by class name in CSS).
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
// ...
// --------
// SCSS ALL EXCEPT MODULES
{
test: /\.scss$/i,
exclude: /\.module\.scss$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
mode: "icss",
},
},
},
{
loader: "sass-loader",
},
],
},
// --------
// SCSS MODULES
{
test: /\.module\.scss$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
mode: "local",
},
},
},
{
loader: "sass-loader",
},
],
},
// --------
// ...
],
},
};
```
**variables.scss**
File treated as `ICSS`-only.
```scss
$colorBackground: red;
:export {
colorBackgroundCanvas: $colorBackground;
}
```
**Component.module.scss**
File treated as `CSS Module`.
```scss
@import "variables.scss";
.componentClass {
background-color: $colorBackground;
}
```
**Component.jsx**
Using both `CSS Module` functionality as well as SCSS variables directly in JavaScript.
```jsx
import svars from "variables.scss";
import styles from "Component.module.scss";
// Render DOM with CSS modules class name
// <div className={styles.componentClass}>
// <canvas ref={mountsCanvas}/>
// </div>
// Somewhere in JavaScript canvas drawing code use the variable directly