# scoped-css

> Scoped CSS in two easy steps.

Latest version **2.2.13** (published 2016-09-06) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install scoped-css
pnpm add scoped-css
yarn add scoped-css
bun add scoped-css
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 2.2.13 |
| Published | 2016-09-06 |
| First published | 2016-06-13 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 160 |
| Author | Joshua Robinson |
| Maintainers | joshuarobinson |
| Keywords | react, reactive-root, scope, scoped, inline, style, styles, styling, css, CSS, classes, classname, classnames, util, utility |

## Links

- npm: https://www.npmjs.com/package/scoped-css
- Repository: https://github.com/buildbreakdo/scoped-css
- Issues: https://github.com/buildbreakdo/scoped-css/issues
- npm.io page: https://npm.io/package/scoped-css

## Alternatives

- [style-dictionary](https://npm.io/package/style-dictionary.md) — 2.0M weekly downloads
- [postcss-merge-idents](https://npm.io/package/postcss-merge-idents.md) — 1.7M weekly downloads
- [@fontsource/noto-sans](https://npm.io/package/@fontsource/noto-sans.md) — 93.0K weekly downloads
- [uglifycss](https://npm.io/package/uglifycss.md) — 71.6K weekly downloads
- [mat4-interpolate](https://npm.io/package/mat4-interpolate.md) — 23.3K weekly downloads

## Recent versions

- 2.2.13 (latest) — 2016-09-06
- 2.2.12 — 2016-06-19
- 2.2.11 — 2016-06-19
- 2.2.10 — 2016-06-19
- 2.2.9 — 2016-06-19
- 2.1.9 — 2016-06-18
- 2.1.8 — 2016-06-18
- 2.1.7 — 2016-06-18
- 2.1.6 — 2016-06-18
- 2.0.6 — 2016-06-17
- 2.0.5 — 2016-06-17
- 1.0.5 — 2016-06-16
- 1.0.4 — 2016-06-14
- 1.0.3 — 2016-06-13

## README

WARNING: This module has been renamed to style-it. Please install it instead. See http://github.com/buildbreakdo/style-it
===========

scoped-css [![Version](http://img.shields.io/npm/v/scoped-css.svg)](https://www.npmjs.org/package/scoped-css) [![Maintenance Status](https://img.shields.io/badge/status-maintained-brightgreen.svg)](https://github.com/buildbreakdo/scoped-css/pulse)
===========
Scoped CSS in two easy steps.

Install with npm.

```sh
npm install scoped-css --save
```

Use with node.js or webpack (barebones covered here, see **Usage** section below):
```js
var Style = require('scoped-css');

// 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 object
Style.scoped('fooRootClassName'); // => <div class='fooRootClassName _scoped-1'>

// Compile your Style object into CSS; use this for the innerHTML of your style element
Style.CSS({ '.btn:hover' : { color: 'red' } }); // => '_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](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes) like `:hover` and `:nth-of-type` or [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) like `:before` and `:after`, and [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_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](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)).

Inline ---- [Embedded] ---- External

**Top Reasons to Use `scoped-css` Instead of Inline Styles:**

1. 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
2. Media queries, pseudo-classes, pseudo-elements, selectors are available: full power of CSS at your fingertips
3. Linting of CSS rule property-value pairs (internally leverage Reacts CSSPropertyOperations and warning system); Selector linting coming soon
4. Reduce noise in components (no more index based conditionals in loops to recreate pseudo-classes like `nth-of-type()` or `:first-child`)
5. Inline style cohesion and scoping benefits without the selector tradeoff
6. ...

**Problems with CSS at Scale (from FB [Christopher Viuexx](http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html)) and the ones `scoped-css` solves:**
- [x]  Global namespace (via scoped)
- [x]  Dependencies (via composition, JavaScript modules, and scoped)
- [ ]  Dead code elimination
- [ ]  Minification (Possible _relative to Inline styles_ with a CSS declaration block registry system)
- [x]  Sharing Constants (via JavaScript modules and variables)
- [ ]  Non-deterministic Resolution (Possible; linting to warn against identical selector statements)
- [x]  Isolation (via scoped)

Usage
==========
```js
import React, { Component } from 'react');
import Style from 'scoped-css';

class myComponent extends Component {

  render() {
    return (
      <section className={ Style.scoped('root') }>  // => <section class="root _scoped-1">
        <style type="text/css">{ Style.css({  // =>   <style type="text/css">
          '.root' : {                         // =>     ._scoped-1.root {
            width: '50%',                     // =>       width: 50%;
            height: '100%'                    // =>       height: 100%;
          },                                  // =>     }
          '.btn': {                           // =>     ._scoped-1 .btn {
            backgroundColor: 'blue',          // =>       background-color: blue;
            color: 'white'                    // =>       color: white;
          },                                  // =>     }
          '.btn:hover': {                     // =>     ._scoped-1 .btn:hover {
            fontWeight: 'bold'                // =>       font-weight: bold;
          }                                   // =>     }
          })}                                 // =>
        </style>                              // =    </style>
                                              // =
        <button className="btn"></button>     // =    <button class="btn"></button>
      </section>                              // =  </section>
    );
  }
}

export default myComponent;
```

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:

```js
import React, { Component } from 'react');
import Style from 'scoped-css';

class myComponent extends Component {

  render() {
    return (
      <section className={ Style.scoped() }>
        <style type="text/css">{ Style.css({
          '.root' : {
            width: '50%',
            height: '100%'
          },
          '@media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)'() {
              '.btn': {
                backgroundColor: 'red'
              }
          }
          })}
        </style>

        <button className="btn"></button>
      </section>
    );
  }
}

export default myComponent;
```

And is output as:

```html
  <section class="root _scoped-1">
    <style type="text/css">
     ._scoped-1.root {
        width: 50%;
        height: 100%;
      }
      @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) {
        ._scoped-1 .btn {
          background-color: 'red';
        }
      }
    </style>

    <button class="btn"></button>
  </section>
```

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:

```js
...
	<style type="text/css">{ Style.css({
	  '.root' : {
	    width: '50%',
	    height: '100%'
	  },
	  ['@media only screen and' +
			'(min-device-width: 320px) and' +
  		'(max-device-width: 480px) and' +
  		'(-webkit-min-device-pixel-ratio: 2)']() {
	      '.btn': {
	        backgroundColor: 'red'
	      }
	  }
	  })}
	</style>
...
```

In the near future short strings like `'@media iphone6'` or `'@media iphone6plus'` will map to the proper media query.

## License
[MIT](LICENSE). Copyright (c) 2016-present Joshua Robinson.

---
_Source: https://npm.io/package/scoped-css · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
