UNPKG

27.5 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[![tests][tests]][tests-url]
12[![coverage][cover]][cover-url]
13[![discussion][discussion]][discussion-url]
14[![size][size]][size-url]
15
16# style-loader
17
18Inject CSS into the DOM.
19
20## Getting Started
21
22To begin, you'll need to install `style-loader`:
23
24```console
25npm install --save-dev style-loader
26```
27
28or
29
30```console
31yarn add -D style-loader
32```
33
34or
35
36```console
37pnpm add -D style-loader
38```
39
40It's recommended to combine `style-loader` with the [`css-loader`](https://github.com/webpack-contrib/css-loader)
41
42Then add the loader to your `webpack` config. For example:
43
44**style.css**
45
46```css
47body {
48 background: green;
49}
50```
51
52**component.js**
53
54```js
55import "./style.css";
56```
57
58**webpack.config.js**
59
60```js
61module.exports = {
62 module: {
63 rules: [
64 {
65 test: /\.css$/i,
66 use: ["style-loader", "css-loader"],
67 },
68 ],
69 },
70};
71```
72
73## Security Warning
74
75This loader is primarily meant for development. The default settings are not safe for production environments. See the [recommended example configuration](#recommend) and the section on [nonces](#nonce) for details.
76
77## Options
78
79- [**`injectType`**](#injecttype)
80- [**`attributes`**](#attributes)
81- [**`insert`**](#insert)
82- [**`styleTagTransform`**](#styleTagTransform)
83- [**`base`**](#base)
84- [**`esModule`**](#esmodule)
85
86### `injectType`
87
88Type:
89
90```ts
91type injectType =
92 | "styleTag"
93 | "singletonStyleTag"
94 | "autoStyleTag"
95 | "lazyStyleTag"
96 | "lazySingletonStyleTag"
97 | "lazyAutoStyleTag"
98 | "linkTag";
99```
100
101Default: `styleTag`
102
103Allows to setup how styles will be injected into the DOM.
104
105Possible values:
106
107#### `styleTag`
108
109Automatically injects styles into the DOM using multiple `<style></style>`. It is **default** behaviour.
110
111**component.js**
112
113```js
114import "./styles.css";
115```
116
117Example with Locals (CSS Modules):
118
119**component-with-css-modules.js**
120
121```js
122import * as styles from "./styles.css";
123
124const divElement = document.createElement("div");
125divElement.className = styles["my-class"];
126```
127
128All local variables (class names) are exported as named exports. To achieve this behaviour you also have to setup `modules` option for `css-loader`. For more information consult with `css-loader` [`documentation`](https://github.com/webpack-contrib/css-loader).
129
130**webpack.config.js**
131
132```js
133module.exports = {
134 module: {
135 rules: [
136 {
137 test: /\.css$/i,
138 use: [
139 // The `injectType` option can be avoided because it is default behaviour
140 { loader: "style-loader", options: { injectType: "styleTag" } },
141 {
142 loader: "css-loader",
143 // Uncomment it if you want to use CSS modules
144 // options: { modules: true }
145 },
146 ],
147 },
148 ],
149 },
150};
151```
152
153The loader inject styles like:
154
155```html
156<style>
157 .foo {
158 color: red;
159 }
160</style>
161<style>
162 .bar {
163 color: blue;
164 }
165</style>
166```
167
168#### `singletonStyleTag`
169
170Automatically injects styles into the DOM using one `<style></style>`.
171
172> **Warning**
173>
174> Source maps do not work.
175
176**component.js**
177
178```js
179import "./styles.css";
180```
181
182**component-with-css-modules.js**
183
184```js
185import * as styles from "./styles.css";
186
187const divElement = document.createElement("div");
188divElement.className = styles["my-class"];
189```
190
191All local variables (class names) are exported as named exports. To achieve this behaviour you also have to setup `modules` option for `css-loader`. For more information consult with `css-loader` [`documentation`](https://github.com/webpack-contrib/css-loader).
192
193**webpack.config.js**
194
195```js
196module.exports = {
197 module: {
198 rules: [
199 {
200 test: /\.css$/i,
201 use: [
202 {
203 loader: "style-loader",
204 options: { injectType: "singletonStyleTag" },
205 },
206 {
207 loader: "css-loader",
208 // Uncomment it if you want to use CSS modules
209 // options: { modules: true }
210 },
211 ],
212 },
213 ],
214 },
215};
216```
217
218The loader inject styles like:
219
220```html
221<style>
222 .foo {
223 color: red;
224 }
225 .bar {
226 color: blue;
227 }
228</style>
229```
230
231#### `autoStyleTag`
232
233Works the same as a [`styleTag`](#styleTag), but if the code is executed in IE6-9, turns on the [`singletonStyleTag`](#singletonStyleTag) mode.
234
235#### `lazyStyleTag`
236
237Injects styles into the DOM using multiple `<style></style>` on demand.
238We 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`).
239When you `lazyStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
240
241> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
242
243**component.js**
244
245```js
246import styles from "./styles.lazy.css";
247
248styles.use();
249// For removing styles you can use
250// styles.unuse();
251```
252
253**component-with-css-modules.js**
254
255```js
256import styles, { "my-class" as myClass } from "./styles.lazy.css";
257
258styles.use();
259
260const divElement = document.createElement("div");
261divElement.className = myClass;
262```
263
264All local variables (class names) are exported as named exports. To achieve this behaviour you also have to setup `modules` option for `css-loader`. For more information consult with `css-loader` [`documentation`](https://github.com/webpack-contrib/css-loader).
265
266**webpack.config.js**
267
268```js
269module.exports = {
270 module: {
271 rules: [
272 {
273 test: /\.css$/i,
274 exclude: /\.lazy\.css$/i,
275 use: ["style-loader", "css-loader"],
276 },
277 {
278 test: /\.lazy\.css$/i,
279 use: [
280 { loader: "style-loader", options: { injectType: "lazyStyleTag" } },
281 {
282 loader: "css-loader",
283 // Uncomment it if you want to use CSS modules
284 // options: { modules: true }
285 },
286 ],
287 },
288 ],
289 },
290};
291```
292
293The loader inject styles like:
294
295```html
296<style>
297 .foo {
298 color: red;
299 }
300</style>
301<style>
302 .bar {
303 color: blue;
304 }
305</style>
306```
307
308#### `lazySingletonStyleTag`
309
310Injects styles into the DOM using one `<style></style>` on demand.
311We 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`).
312When you `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
313
314> ⚠️ Source maps do not work.
315
316> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
317
318**component.js**
319
320```js
321import styles from "./styles.css";
322
323styles.use();
324// For removing styles you can use
325// styles.unuse();
326```
327
328**component-with-css-modules.js**
329
330```js
331import styles, { "my-class" as myClass } from "./styles.lazy.css";
332
333styles.use();
334
335const divElement = document.createElement("div");
336divElement.className = myClass;
337```
338
339All local variables (class names) are exported as named exports. To achieve this behaviour you also have to setup `modules` option for `css-loader`. For more information consult with `css-loader` [`documentation`](https://github.com/webpack-contrib/css-loader).
340
341**webpack.config.js**
342
343```js
344module.exports = {
345 module: {
346 rules: [
347 {
348 test: /\.css$/i,
349 exclude: /\.lazy\.css$/i,
350 use: ["style-loader", "css-loader"],
351 },
352 {
353 test: /\.lazy\.css$/i,
354 use: [
355 {
356 loader: "style-loader",
357 options: { injectType: "lazySingletonStyleTag" },
358 },
359 {
360 loader: "css-loader",
361 // Uncomment it if you want to use CSS modules
362 // options: { modules: true }
363 },
364 ],
365 },
366 ],
367 },
368};
369```
370
371The loader generate this:
372
373```html
374<style>
375 .foo {
376 color: red;
377 }
378 .bar {
379 color: blue;
380 }
381</style>
382```
383
384#### `lazyAutoStyleTag`
385
386Works the same as a [`lazyStyleTag`](#lazyStyleTag), but if the code is executed in IE6-9, turns on the [`lazySingletonStyleTag`](#lazySingletonStyleTag) mode.
387
388#### `linkTag`
389
390Injects styles into the DOM using multiple `<link rel="stylesheet" href="path/to/file.css">` .
391
392> ℹ️ 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">`.
393
394```js
395import "./styles.css";
396import "./other-styles.css";
397```
398
399**webpack.config.js**
400
401```js
402module.exports = {
403 module: {
404 rules: [
405 {
406 test: /\.link\.css$/i,
407 use: [
408 { loader: "style-loader", options: { injectType: "linkTag" } },
409 { loader: "file-loader" },
410 ],
411 },
412 ],
413 },
414};
415```
416
417The loader generate this:
418
419```html
420<link rel="stylesheet" href="path/to/style.css" />
421<link rel="stylesheet" href="path/to/other-styles.css" />
422```
423
424### `attributes`
425
426Type:
427
428```ts
429type attributes = HTMLAttributes;
430```
431
432Default: `{}`
433
434If defined, the `style-loader` will attach given attributes with their values on `<style>` / `<link>` element.
435
436**component.js**
437
438```js
439import "./file.css";
440```
441
442**webpack.config.js**
443
444```js
445module.exports = {
446 module: {
447 rules: [
448 {
449 test: /\.css$/i,
450 use: [
451 { loader: "style-loader", options: { attributes: { id: "id" } } },
452 { loader: "css-loader" },
453 ],
454 },
455 ],
456 },
457};
458```
459
460```html
461<style id="id"></style>
462```
463
464### `insert`
465
466Type:
467
468```ts
469type insert = string;
470```
471
472Default: `head`
473
474By 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`.
475This will cause CSS created by the loader to take priority over CSS already present in the target.
476You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
477If 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.
478
479#### `Selector`
480
481Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
482
483**webpack.config.js**
484
485```js
486module.exports = {
487 module: {
488 rules: [
489 {
490 test: /\.css$/i,
491 use: [
492 {
493 loader: "style-loader",
494 options: {
495 insert: "body",
496 },
497 },
498 "css-loader",
499 ],
500 },
501 ],
502 },
503};
504```
505
506#### `Absolute path to function`
507
508Allows to setup absolute path to custom function that allows to override default behavior and insert styles at any position.
509
510> **Warning**
511>
512> 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.
513
514> **Warning**
515>
516> 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
517
518**webpack.config.js**
519
520```js
521module.exports = {
522 module: {
523 rules: [
524 {
525 test: /\.css$/i,
526 use: [
527 {
528 loader: "style-loader",
529 options: {
530 insert: require.resolve("./path-to-insert-module"),
531 },
532 },
533 "css-loader",
534 ],
535 },
536 ],
537 },
538};
539```
540
541A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
542
543Examples:
544
545Insert styles at top of `head` tag:
546
547**insert-function.js**
548
549```js
550function insertAtTop(element) {
551 var parent = document.querySelector("head");
552 // eslint-disable-next-line no-underscore-dangle
553 var lastInsertedElement = window._lastElementInsertedByStyleLoader;
554
555 if (!lastInsertedElement) {
556 parent.insertBefore(element, parent.firstChild);
557 } else if (lastInsertedElement.nextSibling) {
558 parent.insertBefore(element, lastInsertedElement.nextSibling);
559 } else {
560 parent.appendChild(element);
561 }
562
563 // eslint-disable-next-line no-underscore-dangle
564 window._lastElementInsertedByStyleLoader = element;
565}
566
567module.exports = insertAtTop;
568```
569
570**webpack.config.js**
571
572```js
573module.exports = {
574 module: {
575 rules: [
576 {
577 test: /\.css$/i,
578 use: [
579 {
580 loader: "style-loader",
581 options: {
582 insert: require.resolve("./insert-function"),
583 },
584 },
585 "css-loader",
586 ],
587 },
588 ],
589 },
590};
591```
592
593You can pass any parameters to `style.use(options)` and this value will be passed to `insert` and `styleTagTransform` functions.
594
595**insert-function.js**
596
597```js
598function insertIntoTarget(element, options) {
599 var parent = options.target || document.head;
600
601 parent.appendChild(element);
602}
603
604module.exports = insertIntoTarget;
605```
606
607**webpack.config.js**
608
609```js
610module.exports = {
611 module: {
612 rules: [
613 {
614 test: /\.css$/i,
615 use: [
616 {
617 loader: "style-loader",
618 options: {
619 injectType: "lazyStyleTag",
620 // Do not forget that this code will be used in the browser and
621 // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
622 // we recommend use only ECMA 5 features,
623 // but it depends what browsers you want to support
624 insert: require.resolve("./insert-function.js"),
625 },
626 },
627 "css-loader",
628 ],
629 },
630 ],
631 },
632};
633```
634
635Insert styles to the provided element or to the `head` tag if target isn't provided. Now you can inject styles into Shadow DOM (or any other element).
636
637**custom-square.css**
638
639```css
640div {
641 width: 50px;
642 height: 50px;
643 background-color: red;
644}
645```
646
647**custom-square.js**
648
649```js
650import customSquareStyles from "./custom-square.css";
651
652class CustomSquare extends HTMLElement {
653 constructor() {
654 super();
655
656 this.attachShadow({ mode: "open" });
657
658 const divElement = document.createElement("div");
659
660 divElement.textContent = "Text content.";
661
662 this.shadowRoot.appendChild(divElement);
663
664 customSquareStyles.use({ target: this.shadowRoot });
665
666 // You can override injected styles
667 const bgPurple = new CSSStyleSheet();
668 const width = this.getAttribute("w");
669 const height = this.getAttribute("h");
670
671 bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);
672
673 this.shadowRoot.adoptedStyleSheets = [bgPurple];
674
675 // `divElement` will have `100px` width, `100px` height and `red` background color
676 }
677}
678
679customElements.define("custom-square", CustomSquare);
680
681export default CustomSquare;
682```
683
684### `styleTagTransform`
685
686Type:
687
688```ts
689type styleTagTransform = string;
690```
691
692Default: `undefined`
693
694#### `string`
695
696Allows to setup absolute path to custom function that allows to override default behavior styleTagTransform.
697
698> **Warning**
699>
700> 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
701
702> **Warning**
703>
704> 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 depends what browsers you want to support
705
706**webpack.config.js**
707
708```js
709module.exports = {
710 module: {
711 rules: [
712 {
713 test: /\.css$/i,
714 use: [
715 {
716 loader: "style-loader",
717 options: {
718 injectType: "styleTag",
719 styleTagTransform: require.resolve("style-tag-transform-code"),
720 },
721 },
722 "css-loader",
723 ],
724 },
725 ],
726 },
727};
728```
729
730### `base`
731
732```ts
733type base = number;
734```
735
736This 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.:
737
738**webpack.dll1.config.js**
739
740```js
741module.exports = {
742 module: {
743 rules: [
744 {
745 test: /\.css$/i,
746 use: ["style-loader", "css-loader"],
747 },
748 ],
749 },
750};
751```
752
753**webpack.dll2.config.js**
754
755```js
756module.exports = {
757 module: {
758 rules: [
759 {
760 test: /\.css$/i,
761 use: [
762 { loader: "style-loader", options: { base: 1000 } },
763 "css-loader",
764 ],
765 },
766 ],
767 },
768};
769```
770
771**webpack.app.config.js**
772
773```js
774module.exports = {
775 module: {
776 rules: [
777 {
778 test: /\.css$/i,
779 use: [
780 { loader: "style-loader", options: { base: 2000 } },
781 "css-loader",
782 ],
783 },
784 ],
785 },
786};
787```
788
789### `esModule`
790
791Type:
792
793```ts
794type esModule = boolean;
795```
796
797Default: `true`
798
799By default, `style-loader` generates JS modules that use the ES modules syntax.
800There 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/).
801
802You can enable a CommonJS modules syntax using:
803
804**webpack.config.js**
805
806```js
807module.exports = {
808 module: {
809 rules: [
810 {
811 test: /\.css$/i,
812 loader: "style-loader",
813 options: {
814 esModule: false,
815 },
816 },
817 ],
818 },
819};
820```
821
822## Examples
823
824### Recommend
825
826For `production` builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
827This 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.
828For `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.
829
830> **Warning**
831>
832> Do not use together `style-loader` and `mini-css-extract-plugin`.
833
834**webpack.config.js**
835
836```js
837const MiniCssExtractPlugin = require("mini-css-extract-plugin");
838const devMode = process.env.NODE_ENV !== "production";
839
840module.exports = {
841 module: {
842 rules: [
843 {
844 test: /\.(sa|sc|c)ss$/,
845 use: [
846 devMode ? "style-loader" : MiniCssExtractPlugin.loader,
847 "css-loader",
848 "postcss-loader",
849 "sass-loader",
850 ],
851 },
852 ],
853 },
854 plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
855};
856```
857
858### Named export for CSS Modules
859
860> **Warning**
861>
862> It is not allowed to use JavaScript reserved words in css class names.
863
864> **Warning**
865>
866> Options `esModule` and `modules.namedExport` in `css-loader` should be enabled (by default for `css-loader@7` it is true).
867
868**styles.css**
869
870```css
871.fooBaz {
872 color: red;
873}
874.bar {
875 color: blue;
876}
877.my-class {
878 color: green;
879}
880```
881
882**index.js**
883
884```js
885import { fooBaz, bar, "my-class" as myClass } from "./styles.css";
886
887console.log(fooBaz, bar, myClass);
888```
889
890Or:
891
892**index.js**
893
894```js
895import * as styles from "./styles.css";
896
897console.log(styles.fooBaz, styles.bar, styles["my-class"]);
898```
899
900You can enable a ES module named export using:
901
902**webpack.config.js**
903
904```js
905module.exports = {
906 module: {
907 rules: [
908 {
909 test: /\.css$/,
910 use: [
911 {
912 loader: "style-loader",
913 },
914 {
915 loader: "css-loader",
916 options: {
917 modules: {
918 namedExport: true,
919 },
920 },
921 },
922 ],
923 },
924 ],
925 },
926};
927```
928
929### Source maps
930
931The loader automatically inject source maps when previous loader emit them.
932Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader.
933
934**webpack.config.js**
935
936```js
937module.exports = {
938 module: {
939 rules: [
940 {
941 test: /\.css$/i,
942 use: [
943 "style-loader",
944 { loader: "css-loader", options: { sourceMap: true } },
945 ],
946 },
947 ],
948 },
949};
950```
951
952### Nonce
953
954If 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.
955
956There are two ways to work with `nonce`:
957
958- using the `attributes` option
959- using the `__webpack_nonce__` variable
960
961> **Warning**
962>
963> the `attributes` option takes precedence over the `__webpack_nonce__` variable
964
965#### `attributes`
966
967**component.js**
968
969```js
970import "./style.css";
971```
972
973**webpack.config.js**
974
975```js
976module.exports = {
977 module: {
978 rules: [
979 {
980 test: /\.css$/i,
981 use: [
982 {
983 loader: "style-loader",
984 options: {
985 attributes: {
986 nonce: "12345678",
987 },
988 },
989 },
990 "css-loader",
991 ],
992 },
993 ],
994 },
995};
996```
997
998The loader generate:
999
1000```html
1001<style nonce="12345678">
1002 .foo {
1003 color: red;
1004 }
1005</style>
1006```
1007
1008#### `__webpack_nonce__`
1009
1010**create-nonce.js**
1011
1012```js
1013__webpack_nonce__ = "12345678";
1014```
1015
1016**component.js**
1017
1018```js
1019import "./create-nonce.js";
1020import "./style.css";
1021```
1022
1023Alternative example for `require`:
1024
1025**component.js**
1026
1027```js
1028__webpack_nonce__ = "12345678";
1029
1030require("./style.css");
1031```
1032
1033**webpack.config.js**
1034
1035```js
1036module.exports = {
1037 module: {
1038 rules: [
1039 {
1040 test: /\.css$/i,
1041 use: ["style-loader", "css-loader"],
1042 },
1043 ],
1044 },
1045};
1046```
1047
1048The loader generate:
1049
1050```html
1051<style nonce="12345678">
1052 .foo {
1053 color: red;
1054 }
1055</style>
1056```
1057
1058#### Insert styles at top
1059
1060Insert styles at top of `head` tag.
1061
1062**insert-function.js**
1063
1064```js
1065function insertAtTop(element) {
1066 var parent = document.querySelector("head");
1067 var lastInsertedElement = window._lastElementInsertedByStyleLoader;
1068
1069 if (!lastInsertedElement) {
1070 parent.insertBefore(element, parent.firstChild);
1071 } else if (lastInsertedElement.nextSibling) {
1072 parent.insertBefore(element, lastInsertedElement.nextSibling);
1073 } else {
1074 parent.appendChild(element);
1075 }
1076
1077 window._lastElementInsertedByStyleLoader = element;
1078}
1079
1080module.exports = insertAtTop;
1081```
1082
1083**webpack.config.js**
1084
1085```js
1086module.exports = {
1087 module: {
1088 rules: [
1089 {
1090 test: /\.css$/i,
1091 use: [
1092 {
1093 loader: "style-loader",
1094 options: {
1095 insert: require.resolve("./insert-function.js"),
1096 },
1097 },
1098 "css-loader",
1099 ],
1100 },
1101 ],
1102 },
1103};
1104```
1105
1106#### Insert styles before target element
1107
1108Inserts styles before `#id` element.
1109
1110**insert-function.js**
1111
1112```js
1113function insertBeforeAt(element) {
1114 const parent = document.querySelector("head");
1115 const target = document.querySelector("#id");
1116
1117 const lastInsertedElement = window._lastElementInsertedByStyleLoader;
1118
1119 if (!lastInsertedElement) {
1120 parent.insertBefore(element, target);
1121 } else if (lastInsertedElement.nextSibling) {
1122 parent.insertBefore(element, lastInsertedElement.nextSibling);
1123 } else {
1124 parent.appendChild(element);
1125 }
1126
1127 window._lastElementInsertedByStyleLoader = element;
1128}
1129
1130module.exports = insertBeforeAt;
1131```
1132
1133**webpack.config.js**
1134
1135```js
1136module.exports = {
1137 module: {
1138 rules: [
1139 {
1140 test: /\.css$/i,
1141 use: [
1142 {
1143 loader: "style-loader",
1144 options: {
1145 insert: require.resolve("./insert-function.js"),
1146 },
1147 },
1148 "css-loader",
1149 ],
1150 },
1151 ],
1152 },
1153};
1154```
1155
1156#### Custom Elements (Shadow DOM)
1157
1158You can define custom target for your styles for the `lazyStyleTag` type.
1159
1160**insert-function.js**
1161
1162```js
1163function insertIntoTarget(element, options) {
1164 var parent = options.target || document.head;
1165
1166 parent.appendChild(element);
1167}
1168
1169module.exports = insertIntoTarget;
1170```
1171
1172**webpack.config.js**
1173
1174```js
1175module.exports = {
1176 module: {
1177 rules: [
1178 {
1179 test: /\.css$/i,
1180 use: [
1181 {
1182 loader: "style-loader",
1183 options: {
1184 injectType: "lazyStyleTag",
1185 // Do not forget that this code will be used in the browser and
1186 // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
1187 // we recommend use only ECMA 5 features,
1188 // but it is depends what browsers you want to support
1189 insert: require.resolve("./insert-function.js"),
1190 },
1191 },
1192 "css-loader",
1193 ],
1194 },
1195 ],
1196 },
1197};
1198```
1199
1200Insert styles to the provided element or to the `head` tag if target isn't provided.
1201
1202**custom-square.css**
1203
1204```css
1205div {
1206 width: 50px;
1207 height: 50px;
1208 background-color: red;
1209}
1210```
1211
1212**custom-square.js**
1213
1214```js
1215import customSquareStyles from "./custom-square.css";
1216
1217class CustomSquare extends HTMLElement {
1218 constructor() {
1219 super();
1220
1221 this.attachShadow({ mode: "open" });
1222
1223 const divElement = document.createElement("div");
1224
1225 divElement.textContent = "Text content.";
1226
1227 this.shadowRoot.appendChild(divElement);
1228
1229 customSquareStyles.use({ target: this.shadowRoot });
1230
1231 // You can override injected styles
1232 const bgPurple = new CSSStyleSheet();
1233 const width = this.getAttribute("w");
1234 const height = this.getAttribute("h");
1235
1236 bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);
1237
1238 this.shadowRoot.adoptedStyleSheets = [bgPurple];
1239
1240 // `divElement` will have `100px` width, `100px` height and `red` background color
1241 }
1242}
1243
1244customElements.define("custom-square", CustomSquare);
1245
1246export default CustomSquare;
1247```
1248
1249## Contributing
1250
1251Please take a moment to read our contributing guidelines if you haven't yet done so.
1252
1253[CONTRIBUTING](./.github/CONTRIBUTING.md)
1254
1255## License
1256
1257[MIT](./LICENSE)
1258
1259[npm]: https://img.shields.io/npm/v/style-loader.svg
1260[npm-url]: https://npmjs.com/package/style-loader
1261[node]: https://img.shields.io/node/v/style-loader.svg
1262[node-url]: https://nodejs.org
1263[tests]: https://github.com/webpack-contrib/style-loader/workflows/style-loader/badge.svg
1264[tests-url]: https://github.com/webpack-contrib/style-loader/actions
1265[cover]: https://codecov.io/gh/webpack-contrib/style-loader/branch/master/graph/badge.svg
1266[cover-url]: https://codecov.io/gh/webpack-contrib/style-loader
1267[discussion]: https://img.shields.io/github/discussions/webpack/webpack
1268[discussion-url]: https://github.com/webpack/webpack/discussions
1269[size]: https://packagephobia.now.sh/badge?p=style-loader
1270[size-url]: https://packagephobia.now.sh/result?p=style-loader