# style-loader **Repository Path**: mirrors_webpack-contrib/style-loader ## Basic Information - **Project Name**: style-loader - **Description**: Style Loader - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-19 - **Last Updated**: 2026-03-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
[![npm][npm]][npm-url] [![node][node]][node-url] [![tests][tests]][tests-url] [![coverage][cover]][cover-url] [![discussion][discussion]][discussion-url] [![size][size]][size-url] # style-loader Inject CSS into the DOM. ## Getting Started To begin, you'll need to install `style-loader`: ```console npm install --save-dev style-loader ``` or ```console yarn add -D style-loader ``` or ```console pnpm add -D style-loader ``` It's recommended to combine `style-loader` with the [`css-loader`](https://github.com/webpack/css-loader) Then add the loader to your `webpack` configuration. For example: **style.css** ```css body { background: green; } ``` **component.js** ```js import "./style.css"; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, ], }, }; ``` ## Security Warning This loader is primarily meant for development. The default settings are not safe for production environments. See the [recommended example configuration](#examples) and the section on [nonces](#nonce) for details. ## Options - [**`injectType`**](#injecttype) - [**`attributes`**](#attributes) - [**`insert`**](#insert) - [**`styleTagTransform`**](#styleTagTransform) - [**`base`**](#base) - [**`esModule`**](#esmodule) ### `injectType` Type: ```ts type injectType = | "styleTag" | "singletonStyleTag" | "autoStyleTag" | "lazyStyleTag" | "lazySingletonStyleTag" | "lazyAutoStyleTag" | "linkTag"; ``` Default: `styleTag` Allows you to setup how styles will be injected into the DOM. Possible values: #### `styleTag` Automatically injects styles into the DOM using multiple ``. It is the **default** behaviour. **component.js** ```js import "./styles.css"; ``` Example with Locals (CSS Modules): **component-with-css-modules.js** ```js import * as styles from "./styles.css"; const divElement = document.createElement("div"); divElement.className = styles["my-class"]; ``` All local variables (class names) are exported as named exports. To achieve this behaviour you also have to set up the `modules` option for `css-loader`. For more information, consult the `css-loader` [`documentation`](https://github.com/webpack/css-loader). **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ // The `injectType` option can be avoided because it is default behaviour { loader: "style-loader", options: { injectType: "styleTag" } }, { loader: "css-loader", // Uncomment it if you want to use CSS modules // options: { modules: true } }, ], }, ], }, }; ``` The loader inject styles like: ```html ``` #### `singletonStyleTag` Automatically injects styles into the DOM using a single `` tag. > [!WARNING] > > Source maps do not work. **component.js** ```js import "./styles.css"; ``` **component-with-css-modules.js** ```js import * as styles from "./styles.css"; const divElement = document.createElement("div"); divElement.className = styles["my-class"]; ``` All local variables (class names) are exported as named exports. To achieve this behaviour, you also have to set up the `modules` option for `css-loader`. For more information, consult the `css-loader` [`documentation`](https://github.com/webpack/css-loader). **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ { loader: "style-loader", options: { injectType: "singletonStyleTag" }, }, { loader: "css-loader", // Uncomment it if you want to use CSS modules // options: { modules: true } }, ], }, ], }, }; ``` The loader inject styles like: ```html ``` #### `autoStyleTag` Works the same as a [`styleTag`](#styleTag), but if the code is executed in IE6-9, turns on the [`singletonStyleTag`](#singletonStyleTag) mode. #### `lazyStyleTag` Injects styles into the DOM using multiple `` tags on demand. We recommend following the `.lazy.css` naming convention for lazy styles and `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`). When you use the `lazyStyleTag` value, `style-loader` injects the styles lazily, making them useable on-demand via `style.use()` / `style.unuse()`. > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that. **component.js** ```js import styles from "./styles.lazy.css"; styles.use(); // For removing styles you can use // styles.unuse(); ``` **component-with-css-modules.js** ```js import styles, { "my-class" as myClass } from "./styles.lazy.css"; styles.use(); const divElement = document.createElement("div"); divElement.className = myClass; ``` All local variables (class names) are exported as named exports. To achieve this behaviour, you also have to set up the `modules` option for `css-loader`. For more information, consult the `css-loader` [`documentation`](https://github.com/webpack/css-loader). **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, exclude: /\.lazy\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.lazy\.css$/i, use: [ { loader: "style-loader", options: { injectType: "lazyStyleTag" } }, { loader: "css-loader", // Uncomment it if you want to use CSS modules // options: { modules: true } }, ], }, ], }, }; ``` The loader inject styles like: ```html ``` #### `lazySingletonStyleTag` Injects styles into the DOM using a single `` tag on demand. We recommend following `.lazy.css` naming convention for lazy styles and the `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`). When you use the `lazySingletonStyleTag` value, `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`. > ⚠️ Source maps do not work. > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that. **component.js** ```js import styles from "./styles.css"; styles.use(); // For removing styles you can use // styles.unuse(); ``` **component-with-css-modules.js** ```js import styles, { "my-class" as myClass } from "./styles.lazy.css"; styles.use(); const divElement = document.createElement("div"); divElement.className = myClass; ``` All local variables (class names) are exported as named exports. To achieve this behaviour, you also have to set up the `modules` option for `css-loader`. For more information, consult the `css-loader` [`documentation`](https://github.com/webpack/css-loader). **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, exclude: /\.lazy\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.lazy\.css$/i, use: [ { loader: "style-loader", options: { injectType: "lazySingletonStyleTag" }, }, { loader: "css-loader", // Uncomment it if you want to use CSS modules // options: { modules: true } }, ], }, ], }, }; ``` The loader generate this: ```html ``` #### `lazyAutoStyleTag` Works the same as a [`lazyStyleTag`](#lazyStyleTag), but if the code is executed in IE6-9, turns on the [`lazySingletonStyleTag`](#lazySingletonStyleTag) mode. #### `linkTag` Injects styles into the DOM using multiple `` . > ℹ️ The loader will dynamically insert the `` tag at runtime via JavaScript. You should use [MiniCssExtractPlugin](https://webpack.js.org/plugins/mini-css-extract-plugin/) if you want to include a static ``. ```js import "./styles.css"; import "./other-styles.css"; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.link\.css$/i, use: [ { loader: "style-loader", options: { injectType: "linkTag" } }, { loader: "file-loader" }, ], }, ], }, }; ``` The loader generate this: ```html ``` ### `attributes` Type: ```ts type attributes = HTMLAttributes; ``` Default: `{}` If defined, the `style-loader` will attach the given attributes with their values on ` ``` ### `insert` Type: ```ts type insert = string; ``` Default: `head` By default, the `style-loader` appends `` tags and works faster. > [!WARNING] > > Do not use `style-loader` and `mini-css-extract-plugin` together. **webpack.config.js** ```js const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const devMode = process.env.NODE_ENV !== "production"; module.exports = { module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ devMode ? "style-loader" : MiniCssExtractPlugin.loader, "css-loader", "postcss-loader", "sass-loader", ], }, ], }, plugins: [devMode ? [] : [new MiniCssExtractPlugin()]].flat(), }; ``` ### Named export for CSS Modules > [!WARNING] > > It is not allowed to use JavaScript reserved words in CSS class names. > [!WARNING] > > Options `esModule` and `modules.namedExport` in `css-loader` should be enabled (by default for `css-loader@7` it is true). **styles.css** ```css .fooBaz { color: red; } .bar { color: blue; } .my-class { color: green; } ``` **index.js** ```js import { bar, fooBaz, "my-class" as myClass } from "./styles.css"; console.log(fooBaz, bar, myClass); ``` Or: **index.js** ```js import * as styles from "./styles.css"; console.log(styles.fooBaz, styles.bar, styles["my-class"]); ``` You can enable an ES module named export using: **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/, use: [ { loader: "style-loader", }, { loader: "css-loader", options: { modules: { namedExport: true, }, }, }, ], }, ], }, }; ``` ### Source maps The loader automatically injects source maps when the previous loader emits them. Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader. **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ "style-loader", { loader: "css-loader", options: { sourceMap: true } }, ], }, ], }, }; ``` ### Nonce If you are using a [Content Security Policy](https://www.w3.org/TR/CSP3/) (CSP), the injected code will usually be blocked. A workaround is to use a nonce. Note, however, that using a nonce significantly reduces the protection provided by the CSP. You can read more about the security impact in [the specification](https://www.w3.org/TR/CSP3/#security-considerations). The better solution is not to use this loader in production. There are two ways to work with `nonce`: - Using the `attributes` option - Using the `__webpack_nonce__` variable > [!WARNING] > > the `attributes` option takes precedence over the `__webpack_nonce__` variable #### `attributes` **component.js** ```js import "./style.css"; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ { loader: "style-loader", options: { attributes: { nonce: "12345678", }, }, }, "css-loader", ], }, ], }, }; ``` The loader generate: ```html ``` #### `__webpack_nonce__` **create-nonce.js** ```js __webpack_nonce__ = "12345678"; ``` **component.js** ```js import "./create-nonce.js"; import "./style.css"; ``` Alternative example for `require`: **component.js** ```js __webpack_nonce__ = "12345678"; require("./style.css"); ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, ], }, }; ``` The loader generate: ```html ``` #### Insert styles at top Insert styles at top of `head` tag. **insert-function.js** ```js function insertAtTop(element) { const parent = document.querySelector("head"); const lastInsertedElement = window._lastElementInsertedByStyleLoader; if (!lastInsertedElement) { parent.insertBefore(element, parent.firstChild); } else if (lastInsertedElement.nextSibling) { parent.insertBefore(element, lastInsertedElement.nextSibling); } else { parent.appendChild(element); } window._lastElementInsertedByStyleLoader = element; } module.exports = insertAtTop; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ { loader: "style-loader", options: { insert: require.resolve("./insert-function.js"), }, }, "css-loader", ], }, ], }, }; ``` #### Insert styles before target element Inserts styles before `#id` element. **insert-function.js** ```js function insertBeforeAt(element) { const parent = document.querySelector("head"); const target = document.querySelector("#id"); const lastInsertedElement = window._lastElementInsertedByStyleLoader; if (!lastInsertedElement) { parent.insertBefore(element, target); } else if (lastInsertedElement.nextSibling) { parent.insertBefore(element, lastInsertedElement.nextSibling); } else { parent.appendChild(element); } window._lastElementInsertedByStyleLoader = element; } module.exports = insertBeforeAt; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ { loader: "style-loader", options: { insert: require.resolve("./insert-function.js"), }, }, "css-loader", ], }, ], }, }; ``` #### Custom Elements (Shadow DOM) You can define custom target for your styles when using the `lazyStyleTag` type. **insert-function.js** ```js function insertIntoTarget(element, options) { const parent = options.target || document.head; parent.appendChild(element); } module.exports = insertIntoTarget; ``` **webpack.config.js** ```js module.exports = { module: { rules: [ { test: /\.css$/i, use: [ { loader: "style-loader", options: { injectType: "lazyStyleTag", // Do not forget that this code will be used in the browser and // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, // we recommend use only ECMA 5 features, // but it is depends what browsers you want to support insert: require.resolve("./insert-function.js"), }, }, "css-loader", ], }, ], }, }; ``` Insert styles to the provided element, or into the `head` tag if the target isn't provided. **custom-square.css** ```css div { width: 50px; height: 50px; background-color: red; } ``` **custom-square.js** ```js import customSquareStyles from "./custom-square.css"; class CustomSquare extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); const divElement = document.createElement("div"); divElement.textContent = "Text content."; this.shadowRoot.appendChild(divElement); customSquareStyles.use({ target: this.shadowRoot }); // You can override injected styles const bgPurple = new CSSStyleSheet(); const width = this.getAttribute("w"); const height = this.getAttribute("h"); bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`); this.shadowRoot.adoptedStyleSheets = [bgPurple]; // `divElement` will have `100px` width, `100px` height and `red` background color } } customElements.define("custom-square", CustomSquare); export default CustomSquare; ``` ## Contributing We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests. [CONTRIBUTING](https://github.com/webpack/style-loader?tab=contributing-ov-file#contributing) ## License [MIT](./LICENSE) [npm]: https://img.shields.io/npm/v/style-loader.svg [npm-url]: https://npmjs.com/package/style-loader [node]: https://img.shields.io/node/v/style-loader.svg [node-url]: https://nodejs.org [tests]: https://github.com/webpack/style-loader/workflows/style-loader/badge.svg [tests-url]: https://github.com/webpack/style-loader/actions [cover]: https://codecov.io/gh/webpack/style-loader/branch/main/graph/badge.svg [cover-url]: https://codecov.io/gh/webpack/style-loader [discussion]: https://img.shields.io/github/discussions/webpack/webpack [discussion-url]: https://github.com/webpack/webpack/discussions [size]: https://packagephobia.now.sh/badge?p=style-loader [size-url]: https://packagephobia.now.sh/result?p=style-loader