├── LICENSE
├── README.md
├── index.js
├── package.json
├── stylis.js
└── test
├── index.css
├── index.html
└── test.js
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Luke Jackson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # csz
2 |
3 | > Runtime CSS modules with SASS like preprocessing
4 |
5 | A framework agnostic css-in-js solution that uses [stylis](https://github.com/thysultan/stylis.js) to parse styles from tagged template literals and append them to the head of the document at runtime. Loading in stylesheets dynamically – from .css files – is supported out of the box, so you can write your styles in `.css` files and import them via url without having to worry about flashes of unstyled content.
6 |
7 | ## Features
8 |
9 | - Efficient caching of styles
10 | - Import styles from regular `.css` files
11 | - Available as an ES module (from [unpkg.com](https://unpkg.com/csz))
12 | - Styles scoped under unique namespaces `.csz-lur7p80ssnq`
13 | - Global style injection `:global(selector)`
14 | - Nested selectors `a { &:hover {} }`
15 | - Vendor prefixing `-moz-placeholder`
16 | - Flat stylesheets `color: red; h1 { color: red; }`
17 | - Minification of appended styles
18 | - Keyframe and animation namespacing
19 |
20 | ## Usage
21 |
22 | The package is designed to be used as an ES module. You can import it directly from [unpkg.com](https://unpkg.com/csz/):
23 |
24 | ```js
25 | import css from 'https://unpkg.com/csz';
26 |
27 | // static
28 | const inlined = css`background: blue;`; // generate class name for ruleset
29 |
30 | // dynamic (from stylesheet)
31 | const relative = css`/index.css`; // generate class name for file contents
32 | const absolute = css`https://example.com/index.css`; // generate class name for file contents
33 | ```
34 |
35 | Both variations (static and dynamic) are sync and return a string in a format similar to `csz-b60d61b8`. If a ruleset is provided as a string then it is processed immediately but if a filepath is provided then processing is deferred until the contents of the file has been fetched and parsed.
36 |
37 | > **NOTE:** File paths starting with `/` must be relative to the current hostname, so if you are running your app on `example.com` and require `/styles/index.css` then csz will try fetch it from `example.com/styles/index.css`.
38 |
39 | Styles imported from a file are inevitably going to take some amount of time to download. Whilst the stylesheet is being downloaded a temporary ruleset is applied to the element which hides it (using `display: none`) until the fetched files have been processed. This was implemented to prevent flashes of unstyled content.
40 |
41 | See below for an example of what a raw ruleset might look like and how it looks like after processing.
42 |
43 |
44 | Example stylesheet (unprocessed)
45 |
46 | ```scss
47 | font-size: 2em;
48 |
49 | // line comments
50 | /* block comments */
51 |
52 | :global(body) {background:red}
53 |
54 | h1 {
55 | h2 {
56 | h3 {
57 | content:'nesting'
58 | }
59 | }
60 | }
61 |
62 | @media (max-width: 600px) {
63 | & {display:none}
64 | }
65 |
66 | &:before {
67 | animation: slide 3s ease infinite
68 | }
69 |
70 | @keyframes slide {
71 | from { opacity: 0}
72 | to { opacity: 1}
73 | }
74 |
75 | & {
76 | display: flex
77 | }
78 |
79 | &::placeholder {
80 | color:red
81 | }
82 | ```
83 |
84 |
85 |
86 |
87 | Example stylesheet (processed)
88 |
89 | ```scss
90 | .csz-a4B7ccH9 {font-size: 2em;}
91 |
92 | body {background:red}
93 | h1 h2 h3 {content: 'nesting'}
94 |
95 | @media (max-width: 600px) {
96 | .csz-a4B7ccH9 {display:none}
97 | }
98 |
99 | .csz-a4B7ccH9:before {
100 | -webkit-animation: slide-id 3s ease infinite;
101 | animation: slide-id 3s ease infinite;
102 | }
103 |
104 |
105 | @-webkit-keyframes slide-id {
106 | from { opacity: 0}
107 | to { opacity: 1}
108 | }
109 | @keyframes slide-id {
110 | from { opacity: 0}
111 | to { opacity: 1}
112 | }
113 |
114 | .csz-a4B7ccH9 {
115 | display:-webkit-box;
116 | display:-webkit-flex;
117 | display:-ms-flexbox;
118 | display:flex;
119 | }
120 |
121 | .csz-a4B7ccH9::-webkit-input-placeholder {color:red;}
122 | .csz-a4B7ccH9::-moz-placeholder {color:red;}
123 | .csz-a4B7ccH9:-ms-input-placeholder {color:red;}
124 | .csz-a4B7ccH9::placeholder {color:red;}
125 | ```
126 |
127 |
128 | ## Example
129 |
130 | This library is framework agnostic but here is a contrived example of how you can style a React component conditionally based upon some state; demonstrating switching between static and dynamic styles on the fly.
131 |
132 | ```jsx
133 | import css from 'https://unpkg.com/csz';
134 |
135 | export default () => {
136 | const [toggle, setToggle] = React.useState(false);
137 | return (
138 |