UNPKG

19.2 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| [**`base`**](#base) | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
70| [**`esModule`**](#esmodule) | `{Boolean}` | `false` | Use ES modules syntax |
71| [**`modules`**](#modules) | `{Object}` | `undefined` | Configuration CSS Modules |
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- `lazyStyleTag`
85- `lazySingletonStyleTag`
86- `linkTag`
87
88#### `styleTag`
89
90Automatically injects styles into the DOM using multiple `<style></style>`. It is **default** behaviour.
91
92**component.js**
93
94```js
95import './styles.css';
96```
97
98Example with Locals (CSS Modules):
99
100**component-with-css-modules.js**
101
102```js
103import styles from './styles.css';
104
105const divElement = document.createElement('div');
106divElement.className = styles['my-class'];
107```
108
109All locals (class names) stored in imported object.
110
111**webpack.config.js**
112
113```js
114module.exports = {
115 module: {
116 rules: [
117 {
118 test: /\.css$/i,
119 use: [
120 // The `injectType` option can be avoided because it is default behaviour
121 { loader: 'style-loader', options: { injectType: 'styleTag' } },
122 'css-loader',
123 ],
124 },
125 ],
126 },
127};
128```
129
130The loader inject styles like:
131
132```html
133<style>
134 .foo {
135 color: red;
136 }
137</style>
138<style>
139 .bar {
140 color: blue;
141 }
142</style>
143```
144
145#### `singletonStyleTag`
146
147Automatically injects styles into the DOM using one `<style></style>`.
148
149> ⚠ Source maps do not work.
150
151**component.js**
152
153```js
154import './styles.css';
155```
156
157**component-with-css-modules.js**
158
159```js
160import styles from './styles.css';
161
162const divElement = document.createElement('div');
163divElement.className = styles['my-class'];
164```
165
166All locals (class names) stored in imported object.
167
168**webpack.config.js**
169
170```js
171module.exports = {
172 module: {
173 rules: [
174 {
175 test: /\.css$/i,
176 use: [
177 {
178 loader: 'style-loader',
179 options: { injectType: 'singletonStyleTag' },
180 },
181 'css-loader',
182 ],
183 },
184 ],
185 },
186};
187```
188
189The loader inject styles like:
190
191```html
192<style>
193 .foo {
194 color: red;
195 }
196 .bar {
197 color: blue;
198 }
199</style>
200```
201
202#### `lazyStyleTag`
203
204Injects styles into the DOM using multiple `<style></style>` on demand.
205We 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`).
206When you `lazyStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
207
208> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
209
210**component.js**
211
212```js
213import styles from './styles.lazy.css';
214
215styles.use();
216// For removing styles you can use
217// styles.unuse();
218```
219
220**component-with-css-modules.js**
221
222```js
223import styles from './styles.lazy.css';
224
225styles.use();
226
227const divElement = document.createElement('div');
228divElement.className = styles.locals['my-class'];
229```
230
231All locals (class names) stored in `locals` property of imported object.
232
233**webpack.config.js**
234
235```js
236module.exports = {
237 module: {
238 rules: [
239 {
240 test: /\.css$/i,
241 exclude: /\.lazy\.css$/i,
242 use: ['style-loader', 'css-loader'],
243 },
244 {
245 test: /\.lazy\.css$/i,
246 use: [
247 { loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
248 'css-loader',
249 ],
250 },
251 ],
252 },
253};
254```
255
256The loader inject styles like:
257
258```html
259<style>
260 .foo {
261 color: red;
262 }
263</style>
264<style>
265 .bar {
266 color: blue;
267 }
268</style>
269```
270
271#### `lazySingletonStyleTag`
272
273Injects styles into the DOM using one `<style></style>` on demand.
274We 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`).
275When you `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
276
277> ⚠️ Source maps do not work.
278
279> ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
280
281**component.js**
282
283```js
284import styles from './styles.css';
285
286styles.use();
287// For removing styles you can use
288// styles.unuse();
289```
290
291**component-with-css-modules.js**
292
293```js
294import styles from './styles.lazy.css';
295
296styles.use();
297
298const divElement = document.createElement('div');
299divElement.className = styles.locals['my-class'];
300```
301
302All locals (class names) stored in `locals` property of imported object.
303
304**webpack.config.js**
305
306```js
307module.exports = {
308 module: {
309 rules: [
310 {
311 test: /\.css$/i,
312 exclude: /\.lazy\.css$/i,
313 use: ['style-loader', 'css-loader'],
314 },
315 {
316 test: /\.lazy\.css$/i,
317 use: [
318 {
319 loader: 'style-loader',
320 options: { injectType: 'lazySingletonStyleTag' },
321 },
322 'css-loader',
323 ],
324 },
325 ],
326 },
327};
328```
329
330The loader generate this:
331
332```html
333<style>
334 .foo {
335 color: red;
336 }
337 .bar {
338 color: blue;
339 }
340</style>
341```
342
343#### `linkTag`
344
345Injects styles into the DOM using multiple `<link rel="stylesheet" href="path/to/file.css">` .
346
347> ℹ️ 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">`.
348
349```js
350import './styles.css';
351import './other-styles.css';
352```
353
354**webpack.config.js**
355
356```js
357module.exports = {
358 module: {
359 rules: [
360 {
361 test: /\.link\.css$/i,
362 use: [
363 { loader: 'style-loader', options: { injectType: 'linkTag' } },
364 { loader: 'file-loader' },
365 ],
366 },
367 ],
368 },
369};
370```
371
372The loader generate this:
373
374```html
375<link rel="stylesheet" href="path/to/style.css" />
376<link rel="stylesheet" href="path/to/other-styles.css" />
377```
378
379### `attributes`
380
381Type: `Object`
382Default: `{}`
383
384If defined, the `style-loader` will attach given attributes with their values on `<style>` / `<link>` element.
385
386**component.js**
387
388```js
389import style from './file.css';
390```
391
392**webpack.config.js**
393
394```js
395module.exports = {
396 module: {
397 rules: [
398 {
399 test: /\.css$/i,
400 use: [
401 { loader: 'style-loader', options: { attributes: { id: 'id' } } },
402 { loader: 'css-loader' },
403 ],
404 },
405 ],
406 },
407};
408```
409
410```html
411<style id="id"></style>
412```
413
414### `insert`
415
416Type: `String|Function`
417Default: `head`
418
419By 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`.
420This will cause CSS created by the loader to take priority over CSS already present in the target.
421You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
422If 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.
423
424#### `String`
425
426Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
427
428**webpack.config.js**
429
430```js
431module.exports = {
432 module: {
433 rules: [
434 {
435 test: /\.css$/i,
436 use: [
437 {
438 loader: 'style-loader',
439 options: {
440 insert: 'body',
441 },
442 },
443 'css-loader',
444 ],
445 },
446 ],
447 },
448};
449```
450
451A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
452
453#### `Function`
454
455Allows to override default behavior and insert styles at any position.
456
457> ⚠ 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
458> ⚠ 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
459
460**webpack.config.js**
461
462```js
463module.exports = {
464 module: {
465 rules: [
466 {
467 test: /\.css$/i,
468 use: [
469 {
470 loader: 'style-loader',
471 options: {
472 insert: function insertAtTop(element) {
473 var parent = document.querySelector('head');
474 // eslint-disable-next-line no-underscore-dangle
475 var lastInsertedElement =
476 window._lastElementInsertedByStyleLoader;
477
478 if (!lastInsertedElement) {
479 parent.insertBefore(element, parent.firstChild);
480 } else if (lastInsertedElement.nextSibling) {
481 parent.insertBefore(element, lastInsertedElement.nextSibling);
482 } else {
483 parent.appendChild(element);
484 }
485
486 // eslint-disable-next-line no-underscore-dangle
487 window._lastElementInsertedByStyleLoader = element;
488 },
489 },
490 },
491 'css-loader',
492 ],
493 },
494 ],
495 },
496};
497```
498
499Insert styles at top of `head` tag.
500
501### `base`
502
503This 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.github.io/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.:
504
505**webpack.dll1.config.js**
506
507```js
508module.exports = {
509 module: {
510 rules: [
511 {
512 test: /\.css$/i,
513 use: ['style-loader', 'css-loader'],
514 },
515 ],
516 },
517};
518```
519
520**webpack.dll2.config.js**
521
522```js
523module.exports = {
524 module: {
525 rules: [
526 {
527 test: /\.css$/i,
528 use: [
529 { loader: 'style-loader', options: { base: 1000 } },
530 'css-loader',
531 ],
532 },
533 ],
534 },
535};
536```
537
538**webpack.app.config.js**
539
540```js
541module.exports = {
542 module: {
543 rules: [
544 {
545 test: /\.css$/i,
546 use: [
547 { loader: 'style-loader', options: { base: 2000 } },
548 'css-loader',
549 ],
550 },
551 ],
552 },
553};
554```
555
556### `esModule`
557
558Type: `Boolean`
559Default: `false`
560
561By default, `style-loader` generates JS modules that use the CommonJS modules syntax.
562There 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/).
563
564You can enable a ES module syntax using:
565
566**webpack.config.js**
567
568```js
569module.exports = {
570 module: {
571 rules: [
572 {
573 test: /\.css$/i,
574 loader: 'style-loader',
575 options: {
576 esModule: true,
577 },
578 },
579 ],
580 },
581};
582```
583
584### `modules`
585
586Type: `Object`
587Default: `undefined`
588
589Configuration CSS Modules.
590
591#### `namedExport`
592
593Type: `Boolean`
594Default: `false`
595
596Enables/disables ES modules named export for locals.
597
598> ⚠ Names of locals are converted to `camelCase`.
599
600> ⚠ It is not allowed to use JavaScript reserved words in css class names.
601
602> ⚠ Options `esModule` and `modules.namedExport` in `css-loader` and `style-loader` should be enabled.
603
604**styles.css**
605
606```css
607.foo-baz {
608 color: red;
609}
610.bar {
611 color: blue;
612}
613```
614
615**index.js**
616
617```js
618import { fooBaz, bar } from './styles.css';
619
620console.log(fooBaz, bar);
621```
622
623You can enable a ES module named export using:
624
625**webpack.config.js**
626
627```js
628module.exports = {
629 module: {
630 rules: [
631 {
632 test: /\.css$/,
633 use: [
634 {
635 loader: 'style-loader',
636 options: {
637 esModule: true,
638 modules: {
639 namedExport: true,
640 },
641 },
642 },
643 {
644 loader: 'css-loader',
645 options: {
646 esModule: true,
647 modules: {
648 namedExport: true,
649 },
650 },
651 },
652 ],
653 },
654 ],
655 },
656};
657```
658
659## Examples
660
661### Source maps
662
663The loader automatically inject source maps when previous loader emit them.
664Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader.
665
666**webpack.config.js**
667
668```js
669module.exports = {
670 module: {
671 rules: [
672 {
673 test: /\.css$/i,
674 use: [
675 'style-loader',
676 { loader: 'css-loader', options: { sourceMap: true } },
677 ],
678 },
679 ],
680 },
681};
682```
683
684### Nonce
685
686There are two ways to work with `nonce`:
687
688- using the `attributes` option
689- using the `__webpack_nonce__` variable
690
691> ⚠ the `attributes` option takes precedence over the `__webpack_nonce__` variable
692
693#### `attributes`
694
695**component.js**
696
697```js
698import './style.css';
699```
700
701**webpack.config.js**
702
703```js
704module.exports = {
705 module: {
706 rules: [
707 {
708 test: /\.css$/i,
709 use: [
710 {
711 loader: 'style-loader',
712 options: {
713 attributes: {
714 nonce: '12345678',
715 },
716 },
717 },
718 'css-loader',
719 ],
720 },
721 ],
722 },
723};
724```
725
726The loader generate:
727
728```html
729<style nonce="12345678">
730 .foo {
731 color: red;
732 }
733</style>
734```
735
736#### `__webpack_nonce__`
737
738**create-nonce.js**
739
740```js
741__webpack_nonce__ = '12345678';
742```
743
744**component.js**
745
746```js
747import './create-nonce.js';
748import './style.css';
749```
750
751Alternative example for `require`:
752
753**component.js**
754
755```js
756__webpack_nonce__ = '12345678';
757
758require('./style.css');
759```
760
761**webpack.config.js**
762
763```js
764module.exports = {
765 module: {
766 rules: [
767 {
768 test: /\.css$/i,
769 use: ['style-loader', 'css-loader'],
770 },
771 ],
772 },
773};
774```
775
776The loader generate:
777
778```html
779<style nonce="12345678">
780 .foo {
781 color: red;
782 }
783</style>
784```
785
786#### Insert styles at top
787
788Inserts styles at top of `head` tag.
789
790**webpack.config.js**
791
792```js
793module.exports = {
794 module: {
795 rules: [
796 {
797 test: /\.css$/i,
798 use: [
799 {
800 loader: 'style-loader',
801 options: {
802 insert: function insertAtTop(element) {
803 var parent = document.querySelector('head');
804 var lastInsertedElement =
805 window._lastElementInsertedByStyleLoader;
806
807 if (!lastInsertedElement) {
808 parent.insertBefore(element, parent.firstChild);
809 } else if (lastInsertedElement.nextSibling) {
810 parent.insertBefore(element, lastInsertedElement.nextSibling);
811 } else {
812 parent.appendChild(element);
813 }
814
815 window._lastElementInsertedByStyleLoader = element;
816 },
817 },
818 },
819 'css-loader',
820 ],
821 },
822 ],
823 },
824};
825```
826
827#### Insert styles before target element
828
829Inserts styles before `#id` element.
830
831**webpack.config.js**
832
833```js
834module.exports = {
835 module: {
836 rules: [
837 {
838 test: /\.css$/i,
839 use: [
840 {
841 loader: 'style-loader',
842 options: {
843 insert: function insertBeforeAt(element) {
844 const parent = document.querySelector('head');
845 const target = document.querySelector('#id');
846
847 const lastInsertedElement =
848 window._lastElementInsertedByStyleLoader;
849
850 if (!lastInsertedElement) {
851 parent.insertBefore(element, target);
852 } else if (lastInsertedElement.nextSibling) {
853 parent.insertBefore(element, lastInsertedElement.nextSibling);
854 } else {
855 parent.appendChild(element);
856 }
857
858 window._lastElementInsertedByStyleLoader = element;
859 },
860 },
861 },
862 'css-loader',
863 ],
864 },
865 ],
866 },
867};
868```
869
870## Contributing
871
872Please take a moment to read our contributing guidelines if you haven't yet done so.
873
874[CONTRIBUTING](./.github/CONTRIBUTING.md)
875
876## License
877
878[MIT](./LICENSE)
879
880[npm]: https://img.shields.io/npm/v/style-loader.svg
881[npm-url]: https://npmjs.com/package/style-loader
882[node]: https://img.shields.io/node/v/style-loader.svg
883[node-url]: https://nodejs.org
884[deps]: https://david-dm.org/webpack-contrib/style-loader.svg
885[deps-url]: https://david-dm.org/webpack-contrib/style-loader
886[tests]: https://github.com/webpack-contrib/style-loader/workflows/style-loader/badge.svg
887[tests-url]: https://github.com/webpack-contrib/style-loader/actions
888[cover]: https://codecov.io/gh/webpack-contrib/style-loader/branch/master/graph/badge.svg
889[cover-url]: https://codecov.io/gh/webpack-contrib/style-loader
890[chat]: https://badges.gitter.im/webpack/webpack.svg
891[chat-url]: https://gitter.im/webpack/webpack
892[size]: https://packagephobia.now.sh/badge?p=style-loader
893[size-url]: https://packagephobia.now.sh/result?p=style-loader