How to lint for a harry robert's BEM convention with stylelint?
Asked Answered
S

3

13

PostCSS BEM Linter plugin needs component definition for each block which is a time consuming thing to do in a legacy project.

Is there a way to use stylelint to check for the classes pattern and show error in all stylesheets (.scss in my case) of the project without needing component definition in each file/block?

https://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/

.block {}
.block__element {}
.block--modifier {}
Surfboarding answered 7/4, 2017 at 7:52 Comment(1)
Have you tried github.com/davidtheclark/stylelint-selector-bem-pattern?Siberia
P
3

I have a working example following on from @jeddy3 answer.
This is a copy of my stylelint.config.js

We override the bemSelector() function taken from https://github.com/postcss/postcss-bem-linter/blob/master/lib/preset-patterns.js

We use two dashes style instead of default BEM by changing the const modifier to match https://en.bem.info/methodology/naming-convention/#two-dashes-style

/**
 * @param {String} block
 * @param {Object} [presetOptions]
 * @param {String} [presetOptions.namespace]
 * @returns {RegExp}
 */
const bemSelector = (block, presetOptions) => {
  const ns = (presetOptions && presetOptions.namespace) ? `${presetOptions.namespace}-` : '';
  const WORD = '[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*';
  const element = `(?:__${WORD})?`;
  const modifier = `(?:--${WORD}){0,2}`;
  const attribute = '(?:\\[.+\\])?';
  return new RegExp(`^\\.${ns}${block}${element}${modifier}${attribute}$`);
}

module.exports = {
  extends: 'stylelint-config-recommended-scss',
  plugins: [
    'stylelint-selector-bem-pattern'
  ],
  rules: {
    'plugin/selector-bem-pattern': {
      preset: 'bem',
      componentSelectors: bemSelector
    }
  }
}
Preponderant answered 12/11, 2018 at 15:44 Comment(2)
If anyone is reading this a few years down the line like I am, it looks like the bemSelector() function taken from github.com/postcss/postcss-bem-linter/blob/master/lib/… now allows both "classic" BEM and "two-dashes" style BEM. Here: github.com/postcss/postcss-bem-linter/blob/master/lib/… With (?:_|--)Andi
I'm trying to use a SCSS selector of &.is-open {}as a sort of state-like class. However I'm getting: "Stylelint: Invalid component selector ".c-stylelint.is-open" (plugin/selector-bem-pattern)" Do you get the same? Do you have any work arounds?Andi
C
1

You can use stylelint's selector-class-pattern rule to enforce a pattern for class selectors using a regular expression.

However, if you're writing BEM-like CSS then stylelint-selector-bem-pattern, which wraps PostCSS BEM Linter, is more powerful as it understands the concept of components, elements, modifiers and utility classes.

There is an option to implicitly define components based on their filename, removing the need for component definitions within each file.

Coast answered 12/6, 2017 at 15:28 Comment(0)
H
0

Harry Robert's BEM, the one you show, is actually called Two Dash BEM, one of the official alternative styles and quite popular too. You can install this zero dependency module that has only that rule and nothing else, it's a simple rule to enforce that style for Stylelint:

https://www.npmjs.com/package/stylelint-config-two-dash-bem

Hornpipe answered 22/6, 2024 at 7:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.