Skip to content

Commit 1550541

Browse files
committed
A dedicated section to Class Composition.
1 parent db153b4 commit 1550541

File tree

1 file changed

+134
-17
lines changed

1 file changed

+134
-17
lines changed

README.md

Lines changed: 134 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ React CSS Modules implement automatic mapping of CSS modules. Every CSS class is
1515
- [Options](#options)
1616
- [`allowMultiple`](#allowmultiple)
1717
- [`errorWhenNotFound`](#errorwhennotfound)
18+
- [Class Composition](#class-composition)
19+
- [What Problems does Class Composition Solve?](#what-problems-does-class-composition-solve)
20+
- [A Variation of Class Composition Using CSS Preprocessors](#a-variation-of-class-composition-using-css-preprocessors)
1821
- [SASS, SCSS, LESS and other CSS Preprocessors](#sass-scss-less-and-other-css-preprocessors)
1922
- [Global CSS](#global-css)
2023
- [Multiple CSS Classes](#multiple-css-classes)
@@ -228,7 +231,7 @@ Throws an error when `styleName` cannot be mapped to an existing CSS Module.
228231

229232
## SASS, SCSS, LESS and other CSS Preprocessors
230233

231-
[Interoperable CSS](https://github.com/css-modules/icss) is compatible with the CSS Preprocessors. To use a preprocessor, all you need to do is add the preprocessor to the chain of loaders, e.g. in the case of webpack it is as simple as installing `sass-loader` and adding `!sass` to the end of the `style-loader` loader query (loaders are processed from right to left):
234+
[Interoperable CSS](https://github.com/css-modules/icss) is compatible with the CSS preprocessors. To use a preprocessor, all you need to do is add the preprocessor to the chain of loaders, e.g. in the case of webpack it is as simple as installing `sass-loader` and adding `!sass` to the end of the `style-loader` loader query (loaders are processed from right to left):
232235

233236
```js
234237
{
@@ -237,45 +240,159 @@ Throws an error when `styleName` cannot be mapped to an existing CSS Module.
237240
}
238241
```
239242

240-
## Global CSS
243+
## Class Composition
241244

242-
CSS Modules does not restrict you from using global CSS.
245+
CSS Modules promote composition pattern, i.e. every CSS Module that is used in a component should define all properties required to describe an element, e.g.
243246

244247
```css
245-
:global .foo {
248+
.box {
249+
width: 100px;
250+
height: 100px;
251+
}
246252

253+
.empty {
254+
composes: box;
255+
256+
background: #4CAF50;
257+
}
258+
259+
.full {
260+
composes: box;
261+
262+
background: #F44336;
247263
}
248264
```
249265

250-
However, use global CSS with caution. With CSS Modules, there are only a handful of valid use cases for global CSS (e.g. [normalization](https://github.com/necolas/normalize.css/)).
266+
Composition promotes better separation of markup and style using semantics that would be hard to achieve without CSS Modules.
251267

252-
## Multiple CSS Modules
268+
Because CSS Module names are local, it is perfectly fine to use generic style names such as "empty" or "full", without "box-" prefix.
253269

254-
CSS Modules promote composition pattern, i.e. every CSS Module that is used in a component should define all properties required to describe an element, e.g.
270+
To learn more about composing CSS rules, I suggest reading Glen Maddern article about [CSS Modules](http://glenmaddern.com/articles/css-modules) and the official [spec of the CSS Modules](https://github.com/css-modules/css-modules).
271+
272+
### What Problems does Class Composition Solve?
273+
274+
Consider the same example in CSS and HTML:
255275

256276
```css
257-
.button {
277+
.box {
278+
width: 100px;
279+
height: 100px;
280+
}
258281

282+
.box-empty {
283+
background: #4CAF50;
259284
}
260285

261-
.active {
262-
composes: common;
286+
.box-full {
287+
background: #F44336;
288+
}
289+
```
290+
291+
```html
292+
<div class='box box-empty'></div>
293+
```
294+
295+
This pattern emerged with the advent of OOCSS. The biggest disadvantage of this implementation is that you will need to change HTML almost every time you want to change the style.
296+
297+
### A Variation of Class Composition Using CSS Preprocessors
298+
299+
This section of the document is included as a learning exercise to broaden the understanding about the origin of Class Composition. CSS Modules support a native method of composting CSS Modules using [`composes`](https://github.com/css-modules/css-modules#composition) keyword. CSS Preprocessor is not required.
300+
301+
You can write compositions in SCSS using [`@extend`](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#extend) keyword and using [Mixin Directives](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#mixins), e.g.
302+
303+
Using `@extend`:
263304

264-
/* anything that only applies to active state of the button */
305+
```css
306+
%box {
307+
width: 100px;
308+
height: 100px;
265309
}
266310

267-
.disabled {
268-
composes: common;
311+
.box-empty {
312+
@extend %box;
269313

270-
/* anything that only applies to disabled state of the button */
314+
background: #4CAF50;
315+
}
316+
317+
.box-full {
318+
@extend %box;
319+
320+
background: #F44336;
271321
}
272322
```
273323

274-
Composition promotes better separation of markup and style using semantics that would be hard to achieve without CSS Modules.
324+
This translates to:
275325

276-
To learn more about composing CSS rules, I suggest reading Glen Maddern article about [CSS Modules](http://glenmaddern.com/articles/css-modules) and the official [spec of the CSS Modules](https://github.com/css-modules/css-modules).
326+
```css
327+
.box-empty,
328+
.box-full {
329+
width: 100px;
330+
height: 100px;
331+
}
332+
333+
.box-empty {
334+
background: #4CAF50;
335+
}
336+
337+
.box-full {
338+
background: #F44336;
339+
}
340+
```
341+
342+
Using mixins:
343+
344+
```css
345+
@mixin box {
346+
width: 100px;
347+
height: 100px;
348+
}
349+
350+
.box-empty {
351+
@include box;
352+
353+
background: #4CAF50;
354+
}
355+
356+
.box-full {
357+
@include box;
358+
359+
background: #F44336;
360+
}
361+
```
362+
363+
This translates to:
364+
365+
```css
366+
.box-empty {
367+
width: 100px;
368+
height: 100px;
369+
background: #4CAF50;
370+
}
371+
372+
.box-full {
373+
width: 100px;
374+
height: 100px;
375+
background: #F44336;
376+
}
377+
```
378+
379+
## Global CSS
380+
381+
CSS Modules does not restrict you from using global CSS.
382+
383+
```css
384+
:global .foo {
385+
386+
}
387+
```
388+
389+
However, use global CSS with caution. With CSS Modules, there are only a handful of valid use cases for global CSS (e.g. [normalization](https://github.com/necolas/normalize.css/)).
390+
391+
## Multiple CSS Modules
392+
393+
Avoid using multiple CSS Modules to describe a single element. Read about [Class Composition](#class-compositon).
277394

278-
That said, if you enable [`allowMultiple`](#allowmultiple) option, you can map multiple CSS Modules to a single `ReactElement`. `react-css-modules` will append a unique class name for every CSS Module it matches in the `styleName` declaration, e.g.
395+
That said, if you require to use multiple CSS Modules to describe an element, enable the [`allowMultiple`](#allowmultiple) option. When multiple CSS Modules are used to describe an element, `react-css-modules` will append a unique class name for every CSS Module it matches in the `styleName` declaration, e.g.
279396

280397
```css
281398
.button {

0 commit comments

Comments
 (0)