http://github.com/buildbreakdo/style-it
WARNING: This module has been renamed to style-it. Please install it instead. Seescoped-css
Scoped CSS in two easy steps.
Install with npm.
npm install scoped-css --save
Use with node.js or webpack (barebones covered here, see Usage section below):
var Style = ; // Create classes for the root element; optionally pass in a className for the// root element if you would like to style it using your CSS style objectStyle; // => <div class='fooRootClassName _scoped-1'> // Compile your Style object into CSS; use this for the innerHTML of your style elementStyle; // => '_scoped-1 .btn:hover {background-color: red}'
Why Make This
scoped-css
was created to have ↑ cohesion and ↓ coupling of files without sacrificing the power of CSS (classes, pseudo-elements, pseudo-classes, and media queries).
Loved the cohesion of Inline styles, no more flipping between HTML and CSS, with React it is all in one place. However-- ended up needing features of CSS not possible with Inline styles. And worse, found myself in the unenviable position of reimplementing CSS features in JavaScript.
With Inline styling we lose access to pseudo-classes like :hover
and :nth-of-type
or pseudo-elements like :before
and :after
, and media queries. When we start recreating CSS features in JavaScript--especially at scale--we end up with what basically amounts to custom CSS APIs on a per component or developer basis (Spaghetti served daily@work from 9:00AM - 5:00PM).
Reimplementing CSS features in JavaScript:
- creates more code to maintain
- adds style noise to components (
index === 0 ? //do : //something;
vs.foo:first-of-type
) - slows the pace of development
- reduces agility
- and is a productivity barrier as new developers are onboarded (each devs implementation must be learned for each component).
Hence the conclusion: Inline styles do not scale.
There must be a better way.. lets have our cake and eat it too: scoped-css
takes a middle-of-the-road approach bringing together benefits of Inline styling and External stylesheets by way of an Embedded style element and scoped selectors (read more about scoped style elements on MDN).
Inline ---- [Embedded] ---- External
Top Reasons to Use scoped-css
Instead of Inline Styles:
- You already know and understand it, this is just CSS wrapped in JavaScript objects; selectors are keys and declaration blocks are objects of property-value pairs
- Media queries, pseudo-classes, pseudo-elements, selectors are available: full power of CSS at your fingertips
- Linting of CSS rule property-value pairs (internally leverage Reacts CSSPropertyOperations and warning system); Selector linting coming soon
- Reduce noise in components (no more index based conditionals in loops to recreate pseudo-classes like
nth-of-type()
or:first-child
) - Inline style cohesion and scoping benefits without the selector tradeoff
- ...
Problems with CSS at Scale (from FB Christopher Viuexx) and the ones scoped-css
solves:
- Global namespace (via scoped)
- Dependencies (via composition, JavaScript modules, and scoped)
- Dead code elimination
- Minification (Possible relative to Inline styles with a CSS declaration block registry system)
- Sharing Constants (via JavaScript modules and variables)
- Non-deterministic Resolution (Possible; linting to warn against identical selector statements)
- Isolation (via scoped)
Usage
;; { return <section className= Style > // => <section class="root _scoped-1"> <style type="text/css"> Style // => </style> // = </style> // = <button className="btn"></button> // = <button class="btn"></button> </section> // = </section> ; } ;
Using Media Queries
Media queries are conditonal wrapping statements that execute a set of Styles if conditions are true. Just like in CSS, scoped-css
uses nesting to signal that the parent is to wrap the child.
This looks something like:
;; { return <section className= Style > <style type="text/css"> Style </style> <button className="btn"></button> </section> ; } ;
And is output as:
With ES6 there is support for computed property names. So we can prettify long @media strings with +
operators if the key is wrapped in []
. Looks something like this:
... <style type="text/css"> Style </style>...
In the near future short strings like '@media iphone6'
or '@media iphone6plus'
will map to the proper media query.
License
MIT. Copyright (c) 2016-present Joshua Robinson.