{"id":17991368,"url":"https://github.com/jareware/css-ns","last_synced_at":"2025-08-21T08:06:32.222Z","repository":{"id":31339082,"uuid":"34901757","full_name":"jareware/css-ns","owner":"jareware","description":"Dead-simple CSS namespaces","archived":false,"fork":false,"pushed_at":"2018-11-21T10:42:40.000Z","size":485,"stargazers_count":118,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-02T04:40:28.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/css-ns","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jareware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-01T12:24:59.000Z","updated_at":"2024-02-03T04:49:15.000Z","dependencies_parsed_at":"2022-08-24T04:31:11.364Z","dependency_job_id":null,"html_url":"https://github.com/jareware/css-ns","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/jareware/css-ns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2Fcss-ns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2Fcss-ns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2Fcss-ns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2Fcss-ns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jareware","download_url":"https://codeload.github.com/jareware/css-ns/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2Fcss-ns/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264631355,"owners_count":23640949,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T19:21:29.797Z","updated_at":"2025-07-10T18:39:54.449Z","avatar_url":"https://github.com/jareware.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![css-ns](logo.png)\n\n[![Build Status](https://travis-ci.org/jareware/css-ns.svg?branch=master)](https://travis-ci.org/jareware/css-ns) [![Dependency Status](https://david-dm.org/jareware/css-ns.svg)](https://david-dm.org/jareware/css-ns) [![devDependency Status](https://david-dm.org/jareware/css-ns/dev-status.svg)](https://david-dm.org/jareware/css-ns#info=devDependencies)\n\n## tl;dr\n\nThere's no shortage of solutions to the [problem of global CSS](https://medium.com/seek-ui-engineering/the-end-of-global-css-90d2a4a06284). The properties that set this one apart:\n\n * **It's very simple**, on the order of 100 [well](css-ns.spec.js)-[tested](selenium.png) lines of JS, with [0 dependencies](package.json).\n * **Works with all your favorite styling languages**, including [Sass](#use-with-sass), [PostCSS](#use-with-postcss), [Less](#use-with-less) and [Stylus](#use-with-stylus).\n * **Doesn't rely on a specific bundler**, meaning you can use [Browserify](http://browserify.org/), [webpack](https://webpack.github.io/), [RequireJS](http://requirejs.org/), or any bundler-de-jour.\n * **Isn't tied to any UI framework**, but has opt-in convenience for [use with React](#usage-example).\n * **Generates stable and predictable class names** for external parties, such as the consumers of your UI library on [npm](https://www.npmjs.com/), or your test automation system.\n\nThe core API is very straightforward:\n\n```js\nvar ns = require('css-ns')('MyComponent');\n\nns('foo') // \"MyComponent-foo\"\n```\n\nEverything else is just added convenience for working with class names:\n\n```js\n// Multiple class names:\nns('foo bar') // \"MyComponent-foo MyComponent-bar\"\n\n// Dynamic list of class names, filtering falsy ones out:\nns([ 'foo', null, 'bar' ]) // \"MyComponent-foo MyComponent-bar\"\n\n// Providing class names as object properties:\nns({ foo: true, unwanted: false, bar: true }) // \"MyComponent-foo MyComponent-bar\"\n\n// Escaping the namespace where needed:\nns('foo =icon-star') // \"MyComponent-foo icon-star\"\n```\n\nAnd with the optional [React integration](#use-with-react):\n\n```jsx\n// Simplest possible integration:\n\u003cdiv className={ns('foo')} /\u003e // \u003cdiv class=\"MyComponent-foo\"\u003e\n\n// Namespacing existing elements:\nns(\u003cdiv className=\"foo\" /\u003e) // \u003cdiv class=\"MyComponent-foo\"\u003e\n\n// Creating a namespace-bound React instance:\nvar { React } = require('./config/css-ns')('MyComponent');\n\u003cdiv className=\"foo\" /\u003e // \u003cdiv class=\"MyComponent-foo\"\u003e\n\u003cdiv className={{ foo: true }} /\u003e // \u003cdiv class=\"MyComponent-foo\"\u003e\n```\n\nCreating a bound React instance is a powerful way of **enforcing a namespace** within a file.\n\n## Getting started\n\nInstall with:\n\n```\n$ npm install --save css-ns\n```\n\nThen, create a namespace function:\n\n```js\nvar ns = require('css-ns')('MyComponent');\n```\n\n## Usage example\n\nIt's easy to add `css-ns` to most frameworks and workflows. For example, if you happen to use React, this is what `MyComponent.js` might look like:\n\n```jsx\nvar ns = require('css-ns')('MyComponent');\n\nmodule.exports = (props) =\u003e (\n  \u003cdiv className={ns('this')}\u003e\n    \u003cbutton className={ns({ submit: true, isActive: props.isActive })} /\u003e\n  \u003c/div\u003e\n);\n```\n\nThis component produces the following DOM when rendered with truthy `props.isActive`:\n\n```html\n\u003cdiv class=\"MyComponent\"\u003e\n  \u003cbutton class=\"MyComponent-submit MyComponent-isActive\"\u003e\u003c/button\u003e\n\u003c/div\u003e\n```\n\nTo ensure you won't accidentally forget to wrap a `className` with `ns()`, you can use the optional [React integration](#use-with-react). Here we also use [`__filename`](https://nodejs.org/api/globals.html#globals_filename) (supported by node, Browserify, webpack and others) to make sure our namespace always matches the file that contains it:\n\n```jsx\n// Instead of requiring React directly, let's require a\n// wrapped version that's bound to the current namespace:\nvar { React } = require('./config/css-ns')(__filename);\n\n// All className props within this file are automatically fed through css-ns. There's really no\n// magic here; keep in mind \u003cdiv /\u003e is just JSX sugar for React.createElement('div', {});\nmodule.exports = (props) =\u003e (\n  \u003cdiv className=\"this\"\u003e\n    \u003cbutton className={{ submit: true, isActive: props.isActive }} /\u003e\n  \u003c/div\u003e\n);\n```\n\nYou'll note we also `require('./config/css-ns')`; this is explained thoroughly in [Configuration](#configuration).\n\nFinally, if we were to style this component [using Sass](#use-with-sass), those styles could be:\n\n```scss\n.MyComponent {\n  background: white;\n\n  \u0026-isActive {\n    background: cyan;\n  }\n\n  \u0026-submit {\n    font-weight: bold;\n  }\n}\n```\n\nThe `\u0026` reference is a [Sass built-in](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector), no plugins needed.\n\n## Configuration\n\nThe simple `require('css-ns')(__filename)` one-liner might very well be enough for some projects. If you need to set some options, however, it might become tedious to repeat them in every file. Having an `.*rc`-style configuration file would tie `css-ns` to environments with a file system (browsers don't have one), so to create a configuration file, just use whatever module system you're already using. Let's say we're using ES6:\n\n```js\n// e.g. config/css-ns.js\n\nimport { createCssNs } from 'css-ns';\n\nexport default namespace =\u003e createCssNs({\n  namespace,\n  exclude: /^fa-/ // exclude Font Awesome classes, as they have their own \"fa-\" namespace\n});\n```\n\nThen, to create a local namespace with the `exclude` option set:\n\n```js\nimport createCssNs from './config/css-ns'; // instead of the global 'css-ns'\n\nconst ns = createCssNs(__filename);\n```\n\nOr, in the more compact CommonJS form:\n\n```js\nvar ns = require('./config/css-ns')(__filename);\n```\n\nThere's also a [complete demo app](demo/react) configured this way.\n\n## API\n\nThe `createCssNs()` factory takes either a string or an options object as its single argument:\n\n```js\nvar createCssNs = require('css-ns');\n\n// This shorthand syntax...\nvar ns = createCssNs(__filename);\n\n// ...is equivalent to this options object:\nvar ns = createCssNs({\n  namespace: __filename\n});\n```\n\nAll available options are:\n\n| Option         | Type   | Default    | Description\n|----------------|--------|------------|------------\n| `namespace`    | string | (none)     | Mandatory base part for the namespace, e.g. `\"MyComponent\"` or `__filename`. For convenience, a possible file path and suffix are ignored, so that if the provided value is `\"/path/to/MyComponent.js\"`, the resulting namespace will still be `\"MyComponent\"`.\n| `prefix`       | string | `\"\"`       | All namespaces are prefixed with this string. By default, namespaces aren't prefixed. Class names that begin with this `prefix` are automatically excluded .\n| `include`      | regex  | `/^[a-z]/` | Only class names matching this regex are namespaced. By default, only ones starting in lower-case are. This works out nicely with upper-cased `namespace` values: it ensures only one namespace can be applied to a class name, and calling `ns()` multiple times has the same effect as calling it once.\n| `exclude`      | regex  | `/^$/`     | Class names matching this regex are not namespaced. By default, nothing is excluded (since `/^$/` won't ever match a class name). When both `include` and `exclude` match, `exclude` wins.\n| `escape`       | string | `\"=\"`      | Class names beginning with this string are not namespaced. By default, `=` is used for escaping.\n| `self`         | regex  | `/^this$/` | Class names matching this regex are replaced with the name of the namespace itself. This allows you to e.g. mark the root of your UI component without any suffixes, just the component name.\n| `glue`         | string | `\"-\"`      | This string is used to combine the namespace and the class name.\n| `React`        | object | (none)     | Providing this option enables React integration. When provided, must be an instance of React, e.g. `{ react: require('react') }`. See [Use with React](#use-with-react) for details.\n\n## Use with React\n\nBy default, `css-ns` doesn't use or depend on React in any way. This ensures bundlers don't get confused in projects that don't need the React integration. To enable React integration, provide the [`React` option](#api) for `createCssNs()`:\n\n```js\n// e.g. config/css-ns.js\n\nvar createCssNs = require('css-ns');\nvar React = require('react');\n\nmodule.exports = function(namespace) {\n  return createCssNs({\n    namespace,\n    React\n  });\n};\n```\n\n### Wrapped React instance\n\nProviding the `React` option will expose a wrapped React instance on resulting namespace functions:\n\n```js\nvar ns = require('./config/css-ns')('MyComponent');\n\nns.React.createElement('div', { className: 'foo' }) // \u003cdiv class=\"MyComponent-foo\"\u003e\n```\n\nBecause JSX just sugar for `React.createElement()` calls, this allows you to:\n\n```jsx\nvar { React } = require('./config/css-ns')('MyComponent');\n\n\u003cdiv className=\"foo\"\u003e // \u003cdiv class=\"MyComponent-foo\"\u003e\n```\n\nThe wrapping is in fact [extremely thin](https://github.com/jareware/css-ns/blob/b62b5d4aef6d8c43707622da2fa63eeb601bdb66/css-ns.js#L70-L77), and everything except `React.createElement()` is just inherited from React proper.\n\n### Namespacing existing React elements\n\nProviding the `React` option will also enable support for React elements in the `ns()` function, so that:\n\n```jsx\nvar React = require('react'); // vanilla, non-wrapped React instance\n\nns(\u003cdiv className=\"foo\" /\u003e) // \u003cdiv class=\"MyComponent-foo\"\u003e\n```\n\nThis can be useful in the (rare) cases where your namespace has to be dynamically applied to elements created by some other module. Because the only safe way to do this is to invoke `React.cloneElement()` under the hood, it can have performance implications if overused.\n\n## Use with Sass\n\nUse with [Sass](http://sass-lang.com/) requires no special support or plugins. This input:\n\n```scss\n.MyComponent {\n  background: cyan;\n\n  \u0026-row {\n    color: red;\n  }\n}\n```\n\nwill be compiled to this CSS:\n\n```css\n.MyComponent {\n  background: cyan;\n}\n.MyComponent-row {\n  color: red;\n}\n```\n\n## Use with PostCSS\n\nUse with [PostCSS](https://github.com/postcss/postcss) is easiest with the [`postcss-nested`](https://github.com/postcss/postcss-nested) plugin. With it, this input:\n\n```scss\n.MyComponent {\n  background: cyan;\n\n  \u0026-row {\n    color: red;\n  }\n}\n```\n\nwill be compiled to this CSS:\n\n```css\n.MyComponent {\n  background: cyan;\n}\n.MyComponent-row {\n  color: red;\n}\n```\n\n## Use with Less\n\nUse with [Less](http://lesscss.org/) requires no special support or plugins. This input:\n\n```less\n.MyComponent {\n  background: cyan;\n\n  \u0026-row {\n    color: red;\n  }\n}\n```\n\nwill be compiled to this CSS:\n\n```css\n.MyComponent {\n  background: cyan;\n}\n.MyComponent-row {\n  color: red;\n}\n```\n\n## Use with Stylus\n\nUse with [Stylus](http://stylus-lang.com/) requires no special support or plugins. This input:\n\n```\n.MyComponent\n  background: cyan\n\n  \u0026-row\n    color: red\n```\n\nwill be compiled to this CSS:\n\n```css\n.MyComponent {\n  background: cyan;\n}\n.MyComponent-row {\n  color: red;\n}\n```\n\n## Test suite\n\nThe web-based test suite is available at http://jrw.fi/css-ns/.\n\n## Release\n\n1. Bump version number in `package.json`\n1. `$ git commit -m \"Version bump for release.\" \u0026\u0026 git push`\n1. `$ cp css-ns.{js,d.ts} package.json dist/`\n1. `$ cd dist \u0026\u0026 npm publish`\n1. Create release on GitHub, e.g. `v1.1.3`\n\n## Licence\n\n[MIT](https://opensource.org/licenses/MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjareware%2Fcss-ns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjareware%2Fcss-ns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjareware%2Fcss-ns/lists"}