1 | # @erickmerchant/css
|
2 |
|
3 | _CSS from JS_
|
4 |
|
5 | When I write CSS, I like to write it as if each element will have just one class, and no other styles will apply to that element, except via inheritance. It's nice to look at a rule and see all the declarations that will be applied. I feel like this makes authoring easier, at least for me. To avoid copy-pasting, composition can be used.
|
6 |
|
7 | But the most ideal way to ship CSS to the browsers is with little to no duplication. Something as close to atomic or functional as possible. Without this optimization, compression will help, but my CSS is still bigger than it needs to be.
|
8 |
|
9 | This module takes a single ES module entry point, and outputs a single CSS file and a generated ES module that has a map of keys to the generated class names in the css file.
|
10 |
|
11 | # Example
|
12 |
|
13 | ``` javascript
|
14 | // input.js
|
15 | const desktop = '@media (min-width: 100px)'
|
16 |
|
17 | // some styles for reuse. font-weight normal is removed because it's overridden
|
18 | const emphasis = `
|
19 | font-weight: normal;
|
20 | font-weight: bold;
|
21 | `
|
22 |
|
23 | // these styles are tacked onto the beginning of output.css unmodified
|
24 | export const _start = `
|
25 | p {
|
26 | margin-top: var(--spacing)
|
27 | }
|
28 | `
|
29 |
|
30 | // these are the identifiers (class like) that we'll use later in app.mjs
|
31 | export const styles = {
|
32 | loud: `
|
33 | ${emphasis}
|
34 | ${desktop} {
|
35 | font-size: 5em;
|
36 |
|
37 | ::after {
|
38 | content: '!!'
|
39 | }
|
40 | }
|
41 | ::after {
|
42 | content: '!'
|
43 | }
|
44 | `,
|
45 | button: `
|
46 | ${emphasis}
|
47 | background: #ff8000;
|
48 | color: #111;
|
49 | `
|
50 | }
|
51 | ```
|
52 |
|
53 | ``` css
|
54 | /* output.css */
|
55 | p {
|
56 | margin-top: var(--spacing)
|
57 | }
|
58 |
|
59 | .a { font-weight: bold; }
|
60 | .b {
|
61 | background: #ff8000;
|
62 | color: #111;
|
63 | }
|
64 | .c::after {
|
65 | content: '!';
|
66 | }
|
67 | @media (min-width: 100px) {
|
68 | .c {
|
69 | font-size: 5em;
|
70 | }
|
71 | .c::after {
|
72 | content: '!!';
|
73 | }
|
74 | }
|
75 | ```
|
76 |
|
77 | ``` javascript
|
78 | // output.mjs
|
79 | export const classes = {
|
80 | "loud": "a c",
|
81 | "button": "a b"
|
82 | }
|
83 | ```
|
84 |
|
85 | ``` javascript
|
86 | // app.mjs
|
87 | import {classes} from './output.mjs'
|
88 |
|
89 | classes.loud // 'a c'
|
90 |
|
91 | classes.button // 'a b'
|
92 | ```
|
93 |
|
94 | ## usage
|
95 |
|
96 | build once
|
97 |
|
98 | ```
|
99 | css input.js -o output
|
100 | ```
|
101 |
|
102 | watch for changes
|
103 |
|
104 | ```
|
105 | css -w input.js -o output
|
106 | ```
|