Code Monkey home page Code Monkey logo

postcss-selector-namespace's Introduction

postcss-selector-namespace Build Status Test Coverage Code Climate

Installation

$ npm install postcss-selector-namespace

Usage

var postcss = require('postcss')
var selectorNamespace = require('postcss-selector-namespace')

var output = postcss()
  .use(selectorNamespace({ selfSelector: ':--component', namespace: 'my-component' }))
  .process(require('fs').readFileSync('input.css', 'utf8'))
  .css

input.css

:--component {
  color: black;
}

:--component.danger {
  color: red;
}

h1, .h1 {
  font-weight: bold;
}

will output the following css:

.my-component {
  color: black;
}

.my-component.danger {
  color: red;
}

.my-component h1, .my-component .h1 {
  font-weight: bold;
}

Prepending :root to a selector prevents the selector from being namespaced:

:root h1 {
  font-weight: bold;
}

will output the selector without any namespace:

h1 {
  font-weight: bold;
}

SCSS support

This plugin can also process scss files and output scss again using the postcss-scss module.

var postcss = require('postcss')
var postscss = require('postcss-scss')
var selectorNamespace = require('postcss-selector-namespace')

var output = postcss()
  .use(selectorNamespace({ selfSelector: '&', namespace: 'my-component' }))
  .process(require('fs').readFileSync('input.css', 'utf8'), { syntax: postscss })
  .css
$break = 320px;

& {
  float: left;
  width: 250px;
  h1 {
    font-weight: bold;
    font-size: 32px;
  }
  @media screen and (max-width: $break-small) {
    width: 100px;
    float: none;
    h1 {
      font-size: 24px;
    }
  }
}

outputs:

$break = 320px;

.my-component {
  float: left;
  width: 250px;
  h1 {
    font-weight: bold;
    font-size: 32px;
  }
  @media screen and (max-width: $break-small) {
    width: 100px;
    float: none;
    h1 {
      font-size: 24px;
    }
  }
}

Example setup with postcss-import

Using the excellent plugin postcss-import, we can easily namespace each component with its filename.

components/my-button.css

:--namespace {
  border: 1px solid #666;
  border-radius: 3px;
}

components/my-tabs.css

:--namespace {
  display: flex;
}

.tab {
  border: 1px solid #666;
  border-bottom: none;
  border-top-radius: 3px;
  margin: 0 5px;
}

main.css

@import 'components/my-button.css';
@import 'components/my-tabs.css';

body {
  margin: 0;
  color: #333;
}

build.js

const fs = require('fs')
const path = require('path')
const postcss = require('postcss')
const postcssImport = require('postcss-import')
const postcssSelectorNamespace = require('postcss-selector-namespace')

let css = fs.readFileSync('main.css', 'utf8')

function getComponentName(filename) {
  if (/components\//.test(filename)) {
    return path.basename(filename).replace(/\.css$/, '')
  }

  return null
}

postcss()
  .use(postcssImport({
    transform(css, filename, options) {
      let componentName = getComponentName(filename)

      if (!componentName) {
        return css
      }

      return postcss()
        .use(postcssSelectorNamespace({ namespace: '.' + componentName }))
        .process(css)
        .then(result => result.css)
    }
  }))
  .process(css, { from: 'main.css' })
  .then(result => {
    console.log(result.css)
  })

node build.js outputs:

.my-button {
  border: 1px solid #666;
  border-radius: 3px;
}
.my-tabs {
  display: flex;
}
.my-tabs .tab {
  border: 1px solid #666;
  border-bottom: none;
  border-top-radius: 3px;
  margin: 0 5px;
}
body {
  margin: 0;
  color: #333;
}

Options

namespace

(default: '.self')

The selector to prepend to each selector.

selfSelector

(default: :--namespace)

The selector to use to apply rules directly to your namespace selector.

ignoreRoot

(default: true)

Selector won't be namespaced if they start with the :root pseudo-class.

rootSelector

(default: :root)

If prefixed with this selector, selectors won't be namespaced.

dropRoot

(default: true)

If true, the rootSelector will be stripped from the output.


postcss-selector-namespace's People

Contributors

dependabot[bot] avatar renovate-bot avatar topaxi avatar zenflow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

postcss-selector-namespace's Issues

Drop :root selector

I'm not sure if we should drop :root selectors or not.

:root .foo {}

Does not have the same specificity as

.foo {}

which might cause some trouble in some cases.
We could make this configurable though.

Feature request: Support passing a function for `namespace` option

I want to namespace my components based on their file names, but I can't use the example method using postcss-import since each of our components gets bundled into it's own css file. We don't @import the styles.

Would be excellent if we could pass a function for the namespace option that takes the input file name as an argument and returns the namespace string. Are there any other arguments that would be useful to pass?

Preparing a PR now.

(Excellent little package here btw. Thanks!)

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update dependency chai to v5
  • Update dependency eslint to v9
  • Update dependency eslint-plugin-prettier to v5
  • Update dependency mocha to v10
  • Update dependency postcss-scss to v4
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

npm
package.json
  • postcss ^7.0.0
  • @babel/cli 7.7.0
  • @babel/core 7.7.2
  • @babel/preset-env 7.7.1
  • @babel/register 7.7.0
  • babel-eslint 10.0.3
  • chai 4.2.0
  • chai-jest-snapshot 2.0.0
  • eslint 6.5.1
  • eslint-plugin-prettier 3.1.1
  • mocha 6.2.2
  • nyc 14.1.1
  • postcss-scss 2.0.0
  • node >= 8.0.0
travis
.travis.yml
  • node 12
  • node 10
  • node 8

  • Check this box to trigger a request for Renovate to run again on this repository

Adds namespace to animation keyframes

If I define keyframes within the CSS as follows:

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

and run it through postcss-selector-namespace with .foo as the namespace, the output will be:

@keyframes fadeIn {
  .foo 0% {
    opacity: 0;
  }
  .foo 100% {
    opacity: 1;
  }
}

breaking the animation.

I had a quick look through the code to see if there might be a nice way to handle this, not sure if PostCSS handles keyframe declarations differently to other rules though, if it's as simple as adding a regex check for @(-webkit-|-moz-|-o-)?keyframes somewhere and then preventing further rule walking for descendants? Sorry not very familiar with PostCSS plugins. Great plugin though!

Add ability to control walker function

Hi, thanks for the great plugin!
I'd like to control which selectors mustn't be namespaced (for example html tag). Therefore I suggest to add to options callback which would be called for testing if this selector should be namespaced.

P.S. All in all I believe that html tag shouldn't be namespaced at all.

Multiple namespaces?

h1, h2 {
    font-size: 30px
}

into

.namespace1 h1, .namespace1 h2, .namespace2 h1, .namespace2 h2 {
    font-size: 30px
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.