Skip to content

Instantly share code, notes, and snippets.

@zserge
Last active April 2, 2021 21:49
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save zserge/b8d4fdfb544617ddf4df74c092063501 to your computer and use it in GitHub Desktop.
Save zserge/b8d4fdfb544617ddf4df74c092063501 to your computer and use it in GitHub Desktop.
This is the smallest possible CSS-in-JS that supports all CSS rules, media queries, keyframes and generates unique class names for each CSS block. Can be used with React or with any other framework.
<body>
<script type="module">
import { css } from './zercss.js';
// Global styles
css`
&{} /* This would be a global CSS */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { max-width: 40rem; padding: 2rem; margin: auto; }
`;
// Simple CSS rules for one implicit selector
const red = css`color: ${'red'}; font-weight: ${'bold'}`;
// Multiple selectors
const parent = css`& strong, & b { background: red; color: white; }`
// Pseudo-selectors
const pseudo = css`&::after { content: "should be visible."; }`;
// Media queries
const media = css`
&::after { content: "large"; }
@media screen and (max-width:480px) {
&::after { content: "small"; }
}
`;
// Raw ampersands
const escaped = css`&::after { content: "${'A&B'}"; }`;
// Keyframes (they remain global)
const pulse = css`
@keyframes pulse {
0% { color: red; }
50% { color: yellow; }
100% { color: red; }
}
& { animation-name: pulse; animation-duration: 1s; animation-iteration-count: infinite; }
`;
// Finally, render some HTML using the generated class names
document.body.innerHTML = `
<h1>Minimal CSS-in-JS with zercss</h1>
<ol>
<li>Content should be centered.</li>
<li>Text should be <span class=${red}>red</span>.</li>
<li>Text should be <span class=${parent}>normal and <strong>inverted</strong></span>.</li>
<li><span class=${pseudo}>Text </span></li>
<li><span class=${media}>Your screen is </span></li>
<li><span class=${escaped}>You should see an ampersand:</span></li>
<li><span class=${pulse}>Text should be pulsating.</span></li>
</ol>
`;
</script>
</body>
let c,d=document,n=1,style=d.head.appendChild(d.createElement("style"));export let css=(e,...t)=>(c="z"+n++,d=0,e=e.map(((e,l)=>(l?t[l-1]:"")+e.replace(/&/g,(()=>d="."+c)))).join(""),style.textContent+=d?e:`.${c}{${e}}`,c);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment