Fly CSS-in-JS modules
Features
- You can actually write CSS in your Javascript
- Composeable stylesheets with lazy compilation
- Hack-free psuedo-classes, @keyframes, @media, & @font-face support
- Not tied to any build system or React
- Supports parent > child relationships
- Autoprefixed for all browser vendors
- Simple Server-side CSS support
- Content-addressed class names
- Auto-injected
<style>
tag 8kb
total- Deduped CSS
Installation
npm install afro
Example
let domify = require('domify')
let Afro = require('..')
let container = Afro(`
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2');
}
.red {
font-family: 'Open Sans';
background: red;
}
`)
let span = Afro(`
.blue {
font-family: 'Open Sans';
background: blue;
}
@media (min-width: 33em) {
.blue {
background: turquoise;
}
}
`)
let css = Afro(container, span)
document.body.appendChild(domify(`
<div class="${css.red}">
<span class="${css.blue}">hi there!</span>
<span class="${css.blue}">hi there!</span>
</div>
`)
document.body.appendChild(domify(`
<style type="text/css" afro static>${css}</style>
<div class="${css.red}">
<span class="${css.blue}">hi there!</span>
<span class="${css.blue}">hi there!</span>
</div>
`)
How is this different than X
Aphrodite
Afro is a spiritual successor to Aphrodite. Aphrodite uses JSON as the way to write CSS, where Afro you just write plain CSS.
Aphrodite also uses global singletons on the server-side to generate CSS which prevents you from doing any sort of concurrency.
Aphrodite doesn't yet support parent > child relationships like this one parent:hover child { ... }
. With Afro that relationship just works.
Lastly, Aphrodite writes CSS dynamically as you need it in your components. Afro inserts all the CSS (deduped) at once, making the model quite a bit simpler. There may be some benefits to dynamically inserted CSS, like less work to do on initialization, but there are definitely a few caveats.
CSS Modules
CSS modules introduce new syntax into CSS via composes
and require a build system like postcss or webpack to make it work.
Where you can help
Autoprefixer for CSS properties
Right now the autoprefixing library uses inline style names which are camel-cased. We could skip this step entirely if we had an autoprefixer library that could deal with hyphened properties.
FAQ
Isn't the <style>
injection feature creep?
Good observation! This is something I was planning to exclude from this library. The reason it's important to inject a style tag is that allows your modules to work standalone.
You can require a module and run that code and it will just work without any style-specific initialization on your end. With that being said, it's good practice to export your styles alongside your component so you can compose the styles together.
If you're building an app and you have control over the styles, you'll want to compose all the styles together to get the benefits of de-duped CSS.
You also may want to ignore the injection all together and just render the CSS to a string and stick it in a React <style>
element
Tests
npm install
make test
Credits
Logo is from Oliviu Stoian.
License
MIT