Giter VIP home page Giter VIP logo

stylelint-rscss's Introduction

stylelint-rscss

Validate CSS (and SCSS, Less, SugarSS) to RSCSS conventions

stylelint-rscss is a plugin for stylelint to validate your code against RSCSS conventions. It supports SCSS (Sass), SugarSS and Less, as supported by stylelint.

As a stylelint plugin, it can be used with stylelint's hundreds of rules or other stylelint configs to validate other good CSS practices as well.

Status


Quickstart guide

Install: Install stylelint and stylelint-rscss to your project.

npm install --save-dev stylelint stylelint-rscss

Configure: Create a .stylelintrc in your project. Use the stylelint-rscss/config configuration, which has defaults for strict RSCSS conventions.

// .stylelintrc
{
  "extends": [
    "stylelint-rscss/config"
  ]
}

Add a script: Add an npm script to your package.json.

// package.json
{
  "scripts": {
    "lint:css": "stylelint path/to/css/**/*"
  }
}

Run it!

npm run lint:css

Recommendations

These steps are not required, but are highly recommended:


Text editor support

You need to install stylelint globally (npm install -g stylelint) for text editor support.

npm install -g stylelint

After that, here are the plugins I'd recommend:

Also see stylelint's complimentary tools documentation.


Examples

Here are some valid examples according to RSCSS rules.

.component-name { }
  // ✓ Components should be two or more words, separated by dashes.
.component-name > .element { }
  // ✓ Elements should be one word. Use `>` to denote markup structure.
.component-name > .element.-foo { }
  // ✓ Variant classes begin with a dash (`-`).
.component-name.-variant { }
  // ✓ Components can have variants.
._helper { }
  // ✓ Helpers start with an underscore (`_`).

Some cases not allowed:

.component-name .element { }
  // ✗ Use `>` to denote markup structure.
.component-name.variant { }
  // ✗ Variants must begin with a dash.
.componentname { }
  // ✗ Components should be two or more words.
.component-name.other-component { }
  // ✗ Only one component name is allowed.
.component-name > .-foo { }
.-foo { }
  // ✗ Variants should be attached to components or elements.

Also OK:

h2 { }
  // ✓ Bare elements can be styled.
.component-name > h2 { }
  // ✓ Bare elements can be styled as elements.
.component-name > a:hover[aria-hidden="false"] { }
  // ✓ Pseudo-classes and attributes are OK.
.component-name:hover > .element { }
  // ✓ They're ok for components too.

See Rules for more examples.


Rules and customization

See Rules for a detailed lint of rules and examples of how to customize stylelint-rscss.


Thanks

stylelint-rscss © 2016+, Rico Sta. Cruz. Released under the MIT License.
Authored and maintained by Rico Sta. Cruz with help from contributors (list).

ricostacruz.com  ·  GitHub @rstacruz  ·  Twitter @rstacruz

stylelint-rscss's People

Contributors

mik01aj avatar rstacruz 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  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  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

stylelint-rscss's Issues

Ideas for new rules

I'll just throw some ideas in like I did in one other plugin - the plugin could:

  • check that the each file contains just one toplevel block
  • check that every toplevel selector (might be just one, see above) matches the file name (e.g. I have .cool-thing { ... } in things/cool-thing/style.scss. I mean, every toplevel selector in that file should contain cool-thing. E.g. .cool-thing-floating-menu would be ok too.
  • check that a component doesn't modify other components' stuff, e.g. .cool-thing > .other-thing > .that should be illegal
  • for selectors containing a component class (possibly with a variant) check that there are no positioning properties (position, floats, margins, maybe dimensions)

Edge cases

Here are some cases in existing code bases that stylelint-rscss reports as errors. Maybe they should be adjusted for consideration.

  1. Tables can easily get a "too deep" error. An example would be .my-table > * > tr > td > a:visited (depth 4).
  2. [Fixed in v0.3.0] Variants attached to tag names (a.-home) are an error, because variants expect themselves to be attached to elements.
  3. [Fixed in v0.3.0] Bootstrap names are failing: btn, jumbotron, container, etc. They don't conform to RSCSS, but you can't really do anything about that in a Bootstrap project. — there's now componentWhitelist to alleviate this.
  4. You can't style components-in-components at the moment, ie, .form-fieldset > .form-control. Not sure what should be done here; it's a bad practice (it can lead to specificity issues and mental overhead), but it's a practice that's quite common.
  5. [Fixed in v0.3.0] Using adjacent combinators like + and ~ aren't treated properly: eg, .form-row + .form-row considers the second form-row as an element.

Reorganizing docs

Hi, I thought that it would be a good idea to spend some time on the docs so they're easier to read and more similar to other stylelint/eslint plugins.

My ideas would be to:

  • put a list of rules in the readme, and have the docs organized rule-wise,
  • add example config for people who prefer not to extend
  • extend docs of the big class-format rule.

@rstacruz, if you like this idea, I'd submit a PR in October as a part of Hacktoberfest :)

stylelint-disable-line doesn't work for multiline declarations

    &:checked ~ .single-steward-header, // stylelint-disable-line rscss/class-format
    &:checked ~ .toggle {
      //
    }

still triggers an error for the first line:
Invalid element name: '.single-steward-header' rscss/class-format

ATM you have to do this instead:

    // stylelint-disable
    &:checked ~ .single-steward-header,
    // stylelint-enable
    &:checked ~ .toggle {
      //
    }

Not sure if this is a styleline issue though.

Nested components trigger the "invalid element name" rule

Hi,

This page advises you to set a component's positioning in the parent component. However, actually doing this triggers the invalid element name rule.

Perhaps it would be a good idea to stop this and instead add a new rule that triggers if the nested component applies the positioning properties not mentioned here (with a different error).

class-format enhancement: an option to add my own regexes

I see that the rule is configurable, but I can't make it fit my needs. My needs are:

  • .PascalCase for components (this works)
  • .camelCase for elements (can't do this)
  • -camelCase for variants (almost the default)

Imho it would be reasonable to just accept regexes in the config, like this:

"rscss/class-format": {
    component: "[A-Z][a-zA-Z0-9]+",
    element - "[a-z][a-zA-Z0-9]+",
    helper - "_[a-z][a-zA-Z0-9]+",
    variant - "_[a-z][a-zA-Z0-9]+",
}

And of course the "RSCSS standard" conventions should be the default.

For now I'll stick to the built-in selector-class-pattern rule.

TypeError: rule(...) is not a function

This is my stylelint config:

{
    "plugins": [
        "stylelint-rscss"
    ],
    "rules": {
        "rscss/no-descendant-combinator": false,
    }
}

Yes, that's right, I removed everything except this one rule.
When running stylelint, I get this:

TypeError: rule(...) is not a function
    at /...../node_modules/stylelint/dist/postcssPlugin.js:124:46
    at Array.forEach (native)
    at /...../node_modules/stylelint/dist/postcssPlugin.js:103:33

Needless to say, with other rules it works fine. Using [email protected] and [email protected].

Doesn't understand selector lists

here's stylelint config:

    "rscss/no-descendant-combinator": false,
    "rscss/class-format": [
      true,
      {
        "component": "pascal-case",
        "variant": "^-[a-z]\\w+",
        "element": "^[a-z]\\w+",
        "helper": "^fr-[a-z]\\w+"
      }
    ]

here's example code that breaks:

.Component {
  .elementA,
  .elementB {
     color: red
  }
}

It gives this error: Invalid component name: '.elementB' (rscss/class-format) (css-stylelint)
workaround is to do this:

.Component {
  & .elementA,
  & .elementB {
     color: red
  }
}

both ways are equivalent and produce same code

Implement whitelists for other classnames

We currently have componentWhitelist, but it'd be nice to also have:

  • elementWhitelist
  • variantWhitelist
  • helperWhitelist

For example, when using bootstrap elements like .form-control:

/* .form-control is used as an element here */
.form-field > .controls > .form-control

Parsing nested SASS causes errors when linting

I might be in the minority here of using SASS over SCSS but the linter just dies when parsing certain nested keywords:

stylelint css/base/_typography.sass
Error: Expected pseudo-class or pseudo-element
    at new error (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/processor.js:29:23)
    at Parser.error (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/parser.js:234:15)
    at Parser.pseudo (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/parser.js:332:25)
    at Parser.parse (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/parser.js:549:22)
    at Parser.loop (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/parser.js:517:18)
    at new Parser (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/parser.js:104:21)
    at Processor.process (/Users/my_project/assets/node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/processor.js:26:21)
    at flattenRule (/Users/my_project/assets/node_modules/stylelint-rscss/lib/helpers/flatten_rule.js:16:6)
    at visitRule (/Users/my_project/assets/node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:40:5)
    at visit (/Users/my_project/assets/node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:23:20)

Upon further investigation, it looks like it breaks on this:

// has a sad D:
.my-component
  font:
    weight: 800

// happy days
.my-component
  font-weight: 800

It also notably fails on:

.fail-component
  padding:
    top: 1rem

// not tested, but theoretically:
.might-die
  margin: auto
    bottom: 0

class-format/component: false triggers "TypeError: Cannot read property 'test' of undefined"

My stylelint config is:

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-rscss/config"
  ],
  "plugins": [
    "stylelint-rscss"
  ],
  "rules": {
    "string-quotes": "single",
    "selector-no-type": true,
    "selector-no-id": true,
    "block-opening-brace-space-before": "never-multi-line",
    "rscss/no-descendant-combinator": true,
    "rscss/class-format": [
      true,
      {
        "component": false
      }
    ]
  }
}

When running using gulp-stylelint, I get this error:

TypeError: Cannot read property 'test' of undefined
    at classes.filter.c (...node_modules/stylelint-rscss/lib/class_format.js:158:30)
    at Array.filter (native)
    at validateComponent (...node_modules/stylelint-rscss/lib/class_format.js:157:30)
    at walkSelectors (...node_modules/stylelint-rscss/lib/class_format.js:81:7)
    at selectors.nodes.forEach.selector (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:41:43)
    at Array.forEach (native)
    at selectors (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:41:23)
    at Processor.selectors [as func] (...node_modules/stylelint-rscss/lib/helpers/flatten_rule.js:15:14)
    at Processor.process (...node_modules/stylelint-rscss/node_modules/postcss-selector-parser/dist/processor.js:34:14)
    at flattenRule (...node_modules/stylelint-rscss/lib/helpers/flatten_rule.js:16:6)
    at visitRule (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:40:5)
    at visit (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:23:20)
    at node.nodes.forEach.subnode (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:29:7)
    at Array.forEach (native)
    at visit (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:28:16)
    at walkSelectors (...node_modules/stylelint-rscss/lib/helpers/walk_selectors.js:14:3)
    at ...node_modules/stylelint-rscss/lib/class_format.js:73:5
    at Promise.resolve.then (...node_modules/stylelint/lib/lintSource.js:122:59)

It seems it happens when rscss/class-format -> component rule is set to false.
Is my config file wrong or something?

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.