csz
Runtime CSS modules with SASS like preprocessing
A framework agnostic css-in-js solution that uses stylis 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.
Features
- Efficient caching of styles
- Import styles from regular
.css
files - Available as an ES module (from unpkg.com)
- Styles scoped under unique namespaces
.csz-lur7p80ssnq
- Global style injection
:global(selector)
- Nested selectors
a { &:hover {} }
- Vendor prefixing
-moz-placeholder
- Flat stylesheets
color: red; h1 { color: red; }
- Minification of appended styles
- Keyframe and animation namespacing
Usage
The package is designed to be used as an ES module. You can import it directly from unpkg.com:
; // staticconst inlined = css`background: blue;`; // generate class name for ruleset // dynamic (from stylesheet)const relative = css`/index.css`; // generate class name for file contentsconst absolute = css`https://example.com/index.css`; // generate class name for file contents
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.
NOTE: File paths starting with
/
must be relative to the current hostname, so if you are running your app onexample.com
and require/styles/index.css
then csz will try fetch it fromexample.com/styles/index.css
.
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.
See below for an example of what a raw ruleset might look like and how it looks like after processing.
Example stylesheet (unprocessed)
font-size: 2em; // line comments /* block comments */ :global(body) h1 &:before & &::placeholder
Example stylesheet (processed)
.csz-a4B7ccH9 body h1 h2 h3 .csz-a4B7ccH9:before .csz-a4B7ccH9 .csz-a4B7ccH9::-webkit-input-placeholder .csz-a4B7ccH9::-moz-placeholder .csz-a4B7ccH9:-ms-input-placeholder .csz-a4B7ccH9::placeholder
Example
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.
import css from 'https://unpkg.com/csz'; const toggle setToggle = React; return <div = > <h1>Hello World!</h1> <button =>Toggle</button> </div> ;;
Implementation
I was inspired by emotion and styled-components but unfortunately neither of these packages expose an es module compatible build and come with quite a lot of extraneous functionality that isn't required when the scope of the project is restricted to runtime only class name generation and ruleset isolation.