UNPKG

23.4 kBMarkdownView Raw
1<div align="center">
2 <a href="https://github.com/webpack/webpack">
3 <img width="200" height="200"
4 src="https://webpack.js.org/assets/icon-square-big.svg">
5 </a>
6 <h1>Style Loader</h1>
7</div>
8
9[![npm][npm]][npm-url]
10[![node][node]][node-url]
11[![deps][deps]][deps-url]
12[![tests][tests]][tests-url]
13[![coverage][cover]][cover-url]
14[![chat][chat]][chat-url]
15[![size][size]][size-url]
16
17# style-loader
18
19Inject CSS into the DOM.
20
21## Getting Started
22
23To begin, you'll need to install `style-loader`:
24
25```console
26npm install --save-dev style-loader
27```
28
29It's recommended to combine `style-loader` with the [`css-loader`](https://github.com/webpack-contrib/css-loader)
30
31Then add the loader to your `webpack` config. For example:
32
33**style.css**
34
35```css
36body {
37 background: green;
38}
39```
40
41**component.js**
42
43```js
44import "./style.css";
45```
46
47**webpack.config.js**
48
49```js
50module.exports = {
51 module: {
52 rules: [
53 {
54 test: /\.css$/i,
55 use: ["style-loader", "css-loader"],
56 },
57 ],
58 },
59};
60```
61
62## Options
63
64| Name | Type | Default | Description |
65| :-------------------------------------------: | :------------------: | :---------: | :--------------------------------------------------------- |
66| [**`injectType`**](#injecttype) | `{String}` | `styleTag` | Allows to setup how styles will be injected into the DOM |
67| [**`attributes`**](#attributes) | `{Object}` | `{}` | Adds custom attributes to tag |
68| [**`insert`**](#insert) | `{String\|Function}` | `head` | Inserts tag at the given position into the DOM |
69| [**`styleTagTransform`**](#styleTagTransform) | `{String\|Function}` | `undefined` | Transform tag and css when insert 'style' tag into the DOM |
70| [**`base`**](#base) | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
71| [**`esModule`**](#esmodule) | `{Boolean}` | `true` | Use ES modules syntax |
72
73### `injectType`
74
75Type: `String`
76Default: `styleTag`
77
78Allows to setup how styles will be injected into the DOM.
79
80Possible values:
81
82- `styleTag`
83- `singletonStyleTag`
84- `autoStyleTag`
85- `lazyStyleTag`
86- `lazySingletonStyleTag`
87- `lazyAutoStyleTag`
88- `linkTag`
89
90#### `styleTag`
91
92Automatically injects styles into the DOM using multiple `<style></style>`. It is **default** behaviour.
93
94**component.js**
95
96```js
97import "./styles.css";
98```
99
100Example with Locals (CSS Modules):
101
102**component-with-css-modules.js**
103
104```js
105import styles from "./styles.css";
106
107const divElement = document.createElement("div");
108divElement.className = styles["my-class"];
109```
110
111All locals (class names) stored in imported object.
112
113**webpack.config.js**
114
115```js
116module.exports = {
117 module: {
118 rules: [
119 {
120 test: /\.css$/i,
121 use: [
122 // The `injectType` option can be avoided because it is default behaviour
123 { loader: "style-loader", options: { injectType: "styleTag" } },
124 "css-loader",
125 ],
126 },
127 ],
128 },
129};
130```
131
132The loader inject styles like:
133
134```html
135<style>
136 .foo {
137 color: red;
138 }
139</style>
140<style>
141 .bar {
142 color: blue;
143 }
144</style>
145```
146
147#### `singletonStyleTag`
148
149Automatically injects styles into the DOM using one `<style></style>`.
150
151> ⚠ Source maps do not work.
152
153**component.js**
154
155```js
156import "./styles.css";
157```
158
159**component-with-css-modules.js**
160
161```js
162import styles from "./styles.css";
163
164const divElement = document.createElement("div");
165divElement.className = styles["my-class"];
166```
167
168All locals (class names) stored in imported object.
169
170**webpack.config.js**
171
172```js
173module.exports = {
174 module: {
175 rules: [
176 {
177 test: /\.css$/i,
178 use: [
179 {
180 loader: "style-loader",
181 options: { injectType: "singletonStyleTag" },
182 },
183 "css-loader",
184 ],
185 },
186 ],
187 },
188};
189```
190
191The loader inject styles like:
192
193```html
194<style>
195 .foo {
196 color: red;
197 }
198 .bar {
199 color: blue;
200 }
201</style>
202```
203
204#### `autoStyleTag`
205
206Works the same as a [`styleTag`](#styleTag), but if the code is executed in IE6-9, turns on the [`singletonStyleTag`](#singletonStyleTag) mode.
207
208#### `lazyStyleTag`
209
210Injects styles into the DOM using multiple `<style></style>` on demand.
211We 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`).
212When you `lazyStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
213
214> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
215
216**component.js**
217
218```js
219import styles from "./styles.lazy.css";
220
221styles.use();
222// For removing styles you can use
223// styles.unuse();
224```
225
226**component-with-css-modules.js**
227
228```js
229import styles from "./styles.lazy.css";
230
231styles.use();
232
233const divElement = document.createElement("div");
234divElement.className = styles.locals["my-class"];
235```
236
237All locals (class names) stored in `locals` property of imported object.
238
239**webpack.config.js**
240
241```js
242module.exports = {
243 module: {
244 rules: [
245 {
246 test: /\.css$/i,
247 exclude: /\.lazy\.css$/i,
248 use: ["style-loader", "css-loader"],
249 },
250 {
251 test: /\.lazy\.css$/i,
252 use: [
253 { loader: "style-loader", options: { injectType: "lazyStyleTag" } },
254 "css-loader",
255 ],
256 },
257 ],
258 },
259};
260```
261
262The loader inject styles like:
263
264```html
265<style>
266 .foo {
267 color: red;
268 }
269</style>
270<style>
271 .bar {
272 color: blue;
273 }
274</style>
275```
276
277#### `lazySingletonStyleTag`
278
279Injects styles into the DOM using one `<style></style>` on demand.
280We 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`).
281When you `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
282
283> ⚠️ Source maps do not work.
284
285> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
286
287**component.js**
288
289```js
290import styles from "./styles.css";
291
292styles.use();
293// For removing styles you can use
294// styles.unuse();
295```
296
297**component-with-css-modules.js**
298
299```js
300import styles from "./styles.lazy.css";
301
302styles.use();
303
304const divElement = document.createElement("div");
305divElement.className = styles.locals["my-class"];
306```
307
308All locals (class names) stored in `locals` property of imported object.
309
310**webpack.config.js**
311
312```js
313module.exports = {
314 module: {
315 rules: [
316 {
317 test: /\.css$/i,
318 exclude: /\.lazy\.css$/i,
319 use: ["style-loader", "css-loader"],
320 },
321 {
322 test: /\.lazy\.css$/i,
323 use: [
324 {
325 loader: "style-loader",
326 options: { injectType: "lazySingletonStyleTag" },
327 },
328 "css-loader",
329 ],
330 },
331 ],
332 },
333};
334```
335
336The loader generate this:
337
338```html
339<style>
340 .foo {
341 color: red;
342 }
343 .bar {
344 color: blue;
345 }
346</style>
347```
348
349#### `lazyAutoStyleTag`
350
351Works the same as a [`lazyStyleTag`](#lazyStyleTag), but if the code is executed in IE6-9, turns on the [`lazySingletonStyleTag`](#lazySingletonStyleTag) mode.
352
353#### `linkTag`
354
355Injects styles into the DOM using multiple `<link rel="stylesheet" href="path/to/file.css">` .
356
357> ℹ️ The loader will dynamically insert the `<link href="path/to/file.css" rel="stylesheet">` 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 `<link href="path/to/file.css" rel="stylesheet">`.
358
359```js
360import "./styles.css";
361import "./other-styles.css";
362```
363
364**webpack.config.js**
365
366```js
367module.exports = {
368 module: {
369 rules: [
370 {
371 test: /\.link\.css$/i,
372 use: [
373 { loader: "style-loader", options: { injectType: "linkTag" } },
374 { loader: "file-loader" },
375 ],
376 },
377 ],
378 },
379};
380```
381
382The loader generate this:
383
384```html
385<link rel="stylesheet" href="path/to/style.css" />
386<link rel="stylesheet" href="path/to/other-styles.css" />
387```
388
389### `attributes`
390
391Type: `Object`
392Default: `{}`
393
394If defined, the `style-loader` will attach given attributes with their values on `<style>` / `<link>` element.
395
396**component.js**
397
398```js
399import style from "./file.css";
400```
401
402**webpack.config.js**
403
404```js
405module.exports = {
406 module: {
407 rules: [
408 {
409 test: /\.css$/i,
410 use: [
411 { loader: "style-loader", options: { attributes: { id: "id" } } },
412 { loader: "css-loader" },
413 ],
414 },
415 ],
416 },
417};
418```
419
420```html
421<style id="id"></style>
422```
423
424### `insert`
425
426Type: `String|Function`
427Default: `head`
428
429By default, the `style-loader` appends `<style>`/`<link>` elements to the end of the style target, which is the `<head>` tag of the page unless specified by `insert`.
430This will cause CSS created by the loader to take priority over CSS already present in the target.
431You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
432If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure you have sufficient access rights, the styles will be injected into the content document head.
433
434#### `String`
435
436##### `Selector`
437
438Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
439
440**webpack.config.js**
441
442```js
443module.exports = {
444 module: {
445 rules: [
446 {
447 test: /\.css$/i,
448 use: [
449 {
450 loader: "style-loader",
451 options: {
452 insert: "body",
453 },
454 },
455 "css-loader",
456 ],
457 },
458 ],
459 },
460};
461```
462
463##### `Absolute path to function`
464
465Allows to setup absolute path to custom function that allows to override default behavior and insert styles at any position.
466
467> ⚠ 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 using [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) for support latest ECMA features.
468> ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
469
470**webpack.config.js**
471
472```js
473module.exports = {
474 module: {
475 rules: [
476 {
477 test: /\.css$/i,
478 use: [
479 {
480 loader: "style-loader",
481 options: {
482 insert: require.resolve("modulePath"),
483 },
484 },
485 "css-loader",
486 ],
487 },
488 ],
489 },
490};
491```
492
493A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
494
495#### `Function`
496
497Allows to override default behavior and insert styles at any position.
498
499> ⚠ 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
500> ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
501
502**webpack.config.js**
503
504```js
505module.exports = {
506 module: {
507 rules: [
508 {
509 test: /\.css$/i,
510 use: [
511 {
512 loader: "style-loader",
513 options: {
514 insert: function insertAtTop(element) {
515 var parent = document.querySelector("head");
516 // eslint-disable-next-line no-underscore-dangle
517 var lastInsertedElement =
518 window._lastElementInsertedByStyleLoader;
519
520 if (!lastInsertedElement) {
521 parent.insertBefore(element, parent.firstChild);
522 } else if (lastInsertedElement.nextSibling) {
523 parent.insertBefore(element, lastInsertedElement.nextSibling);
524 } else {
525 parent.appendChild(element);
526 }
527
528 // eslint-disable-next-line no-underscore-dangle
529 window._lastElementInsertedByStyleLoader = element;
530 },
531 },
532 },
533 "css-loader",
534 ],
535 },
536 ],
537 },
538};
539```
540
541Insert styles at top of `head` tag.
542
543### `styleTagTransform`
544
545Type: `String | Function`
546Default: `undefined`
547
548#### `String`
549
550Allows to setup absolute path to custom function that allows to override default behavior styleTagTransform.
551
552> ⚠ 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
553
554**webpack.config.js**
555
556```js
557module.exports = {
558 module: {
559 rules: [
560 {
561 test: /\.css$/i,
562 use: [
563 {
564 loader: "style-loader",
565 options: {
566 injectType: "styleTag",
567 styleTagTransform: require.resolve("module-path"),
568 },
569 },
570 "css-loader",
571 ],
572 },
573 ],
574 },
575};
576```
577
578#### `Function`
579
580Transform tag and css when insert 'style' tag into the DOM.
581
582> ⚠ 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
583> ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
584
585**webpack.config.js**
586
587```js
588module.exports = {
589 module: {
590 rules: [
591 {
592 test: /\.css$/i,
593 use: [
594 {
595 loader: "style-loader",
596 options: {
597 injectType: "styleTag",
598 styleTagTransform: function (css, style) {
599 // Do something ...
600 style.innerHTML = `${css}.modify{}\n`;
601
602 document.head.appendChild(style);
603 },
604 },
605 },
606 "css-loader",
607 ],
608 },
609 ],
610 },
611};
612```
613
614### `base`
615
616This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.me.uk/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.:
617
618**webpack.dll1.config.js**
619
620```js
621module.exports = {
622 module: {
623 rules: [
624 {
625 test: /\.css$/i,
626 use: ["style-loader", "css-loader"],
627 },
628 ],
629 },
630};
631```
632
633**webpack.dll2.config.js**
634
635```js
636module.exports = {
637 module: {
638 rules: [
639 {
640 test: /\.css$/i,
641 use: [
642 { loader: "style-loader", options: { base: 1000 } },
643 "css-loader",
644 ],
645 },
646 ],
647 },
648};
649```
650
651**webpack.app.config.js**
652
653```js
654module.exports = {
655 module: {
656 rules: [
657 {
658 test: /\.css$/i,
659 use: [
660 { loader: "style-loader", options: { base: 2000 } },
661 "css-loader",
662 ],
663 },
664 ],
665 },
666};
667```
668
669### `esModule`
670
671Type: `Boolean`
672Default: `true`
673
674By default, `style-loader` generates JS modules that use the ES modules syntax.
675There 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/).
676
677You can enable a CommonJS modules syntax using:
678
679**webpack.config.js**
680
681```js
682module.exports = {
683 module: {
684 rules: [
685 {
686 test: /\.css$/i,
687 loader: "style-loader",
688 options: {
689 esModule: false,
690 },
691 },
692 ],
693 },
694};
695```
696
697## Examples
698
699### Recommend
700
701For `production` builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
702This 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.
703For `development` mode (including `webpack-dev-server`) you can use `style-loader`, because it injects CSS into the DOM using multiple <style></style> and works faster.
704
705> i Do not use together `style-loader` and `mini-css-extract-plugin`.
706
707**webpack.config.js**
708
709```js
710const MiniCssExtractPlugin = require("mini-css-extract-plugin");
711const devMode = process.env.NODE_ENV !== "production";
712
713module.exports = {
714 module: {
715 rules: [
716 {
717 test: /\.(sa|sc|c)ss$/,
718 use: [
719 devMode ? "style-loader" : MiniCssExtractPlugin.loader,
720 "css-loader",
721 "postcss-loader",
722 "sass-loader",
723 ],
724 },
725 ],
726 },
727 plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
728};
729```
730
731### Named export for CSS Modules
732
733> ⚠ Names of locals are converted to `camelCase`.
734
735> ⚠ It is not allowed to use JavaScript reserved words in css class names.
736
737> ⚠ Options `esModule` and `modules.namedExport` in `css-loader` should be enabled.
738
739**styles.css**
740
741```css
742.foo-baz {
743 color: red;
744}
745.bar {
746 color: blue;
747}
748```
749
750**index.js**
751
752```js
753import { fooBaz, bar } from "./styles.css";
754
755console.log(fooBaz, bar);
756```
757
758You can enable a ES module named export using:
759
760**webpack.config.js**
761
762```js
763module.exports = {
764 module: {
765 rules: [
766 {
767 test: /\.css$/,
768 use: [
769 {
770 loader: "style-loader",
771 },
772 {
773 loader: "css-loader",
774 options: {
775 modules: {
776 namedExport: true,
777 },
778 },
779 },
780 ],
781 },
782 ],
783 },
784};
785```
786
787### Source maps
788
789The loader automatically inject source maps when previous loader emit them.
790Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader.
791
792**webpack.config.js**
793
794```js
795module.exports = {
796 module: {
797 rules: [
798 {
799 test: /\.css$/i,
800 use: [
801 "style-loader",
802 { loader: "css-loader", options: { sourceMap: true } },
803 ],
804 },
805 ],
806 },
807};
808```
809
810### Nonce
811
812There are two ways to work with `nonce`:
813
814- using the `attributes` option
815- using the `__webpack_nonce__` variable
816
817> ⚠ the `attributes` option takes precedence over the `__webpack_nonce__` variable
818
819#### `attributes`
820
821**component.js**
822
823```js
824import "./style.css";
825```
826
827**webpack.config.js**
828
829```js
830module.exports = {
831 module: {
832 rules: [
833 {
834 test: /\.css$/i,
835 use: [
836 {
837 loader: "style-loader",
838 options: {
839 attributes: {
840 nonce: "12345678",
841 },
842 },
843 },
844 "css-loader",
845 ],
846 },
847 ],
848 },
849};
850```
851
852The loader generate:
853
854```html
855<style nonce="12345678">
856 .foo {
857 color: red;
858 }
859</style>
860```
861
862#### `__webpack_nonce__`
863
864**create-nonce.js**
865
866```js
867__webpack_nonce__ = "12345678";
868```
869
870**component.js**
871
872```js
873import "./create-nonce.js";
874import "./style.css";
875```
876
877Alternative example for `require`:
878
879**component.js**
880
881```js
882__webpack_nonce__ = "12345678";
883
884require("./style.css");
885```
886
887**webpack.config.js**
888
889```js
890module.exports = {
891 module: {
892 rules: [
893 {
894 test: /\.css$/i,
895 use: ["style-loader", "css-loader"],
896 },
897 ],
898 },
899};
900```
901
902The loader generate:
903
904```html
905<style nonce="12345678">
906 .foo {
907 color: red;
908 }
909</style>
910```
911
912#### Insert styles at top
913
914Inserts styles at top of `head` tag.
915
916**webpack.config.js**
917
918```js
919module.exports = {
920 module: {
921 rules: [
922 {
923 test: /\.css$/i,
924 use: [
925 {
926 loader: "style-loader",
927 options: {
928 insert: function insertAtTop(element) {
929 var parent = document.querySelector("head");
930 var lastInsertedElement =
931 window._lastElementInsertedByStyleLoader;
932
933 if (!lastInsertedElement) {
934 parent.insertBefore(element, parent.firstChild);
935 } else if (lastInsertedElement.nextSibling) {
936 parent.insertBefore(element, lastInsertedElement.nextSibling);
937 } else {
938 parent.appendChild(element);
939 }
940
941 window._lastElementInsertedByStyleLoader = element;
942 },
943 },
944 },
945 "css-loader",
946 ],
947 },
948 ],
949 },
950};
951```
952
953#### Insert styles before target element
954
955Inserts styles before `#id` element.
956
957**webpack.config.js**
958
959```js
960module.exports = {
961 module: {
962 rules: [
963 {
964 test: /\.css$/i,
965 use: [
966 {
967 loader: "style-loader",
968 options: {
969 insert: function insertBeforeAt(element) {
970 const parent = document.querySelector("head");
971 const target = document.querySelector("#id");
972
973 const lastInsertedElement =
974 window._lastElementInsertedByStyleLoader;
975
976 if (!lastInsertedElement) {
977 parent.insertBefore(element, target);
978 } else if (lastInsertedElement.nextSibling) {
979 parent.insertBefore(element, lastInsertedElement.nextSibling);
980 } else {
981 parent.appendChild(element);
982 }
983
984 window._lastElementInsertedByStyleLoader = element;
985 },
986 },
987 },
988 "css-loader",
989 ],
990 },
991 ],
992 },
993};
994```
995
996## Contributing
997
998Please take a moment to read our contributing guidelines if you haven't yet done so.
999
1000[CONTRIBUTING](./.github/CONTRIBUTING.md)
1001
1002## License
1003
1004[MIT](./LICENSE)
1005
1006[npm]: https://img.shields.io/npm/v/style-loader.svg
1007[npm-url]: https://npmjs.com/package/style-loader
1008[node]: https://img.shields.io/node/v/style-loader.svg
1009[node-url]: https://nodejs.org
1010[deps]: https://david-dm.org/webpack-contrib/style-loader.svg
1011[deps-url]: https://david-dm.org/webpack-contrib/style-loader
1012[tests]: https://github.com/webpack-contrib/style-loader/workflows/style-loader/badge.svg
1013[tests-url]: https://github.com/webpack-contrib/style-loader/actions
1014[cover]: https://codecov.io/gh/webpack-contrib/style-loader/branch/master/graph/badge.svg
1015[cover-url]: https://codecov.io/gh/webpack-contrib/style-loader
1016[chat]: https://badges.gitter.im/webpack/webpack.svg
1017[chat-url]: https://gitter.im/webpack/webpack
1018[size]: https://packagephobia.now.sh/badge?p=style-loader
1019[size-url]: https://packagephobia.now.sh/result?p=style-loader