background

In our company project, we always followed the BEM specification for class names, but we found some inconveniences in use

  • The class name is long and cumbersome to write, and the style of a dialog text position needs to be writtenns-dialog__title--center
  • When using multiple classes, you need to spell strings, especially if there is a conditional style judgment, and also need to determine if the following is a section of ant Design framework style processing, although the packaging processing, but still slightly troublesome

The solution

In order to simplify the complexity of using THE BEM specification, I borrowed the methods of several frameworks to create a relatively simple and easy to use plug-in library CSS-BEM (github.com/snowzijun/c…). .

In this plug-in library, in order to be more consistent with the common component library style of naming, ON the basis of BEM specification, I added a namespace concept, become NBEM, At-input__overlay –hidden,at for namespace,input for block,overlay for element,hidden for modifier

The installation
    npm install css-bem
    import cssBem from 'css-bem'
Copy the code
Basic usage (using the React Button component as an example)
Import cssBem from 'css-bem' // Declare namespace and block const nbem = cssBem('zj','button') // component export default class Button extends React.Component{ static propTypes={ type:PropTypes.string, plain:PropTypes.bool, disabled: PropTypes.bool } render(){ const {type,plain,disabled} = this.props return ( <button ClassName ={nbem([type,{disabled,plain}])}> <span className={nbem('text')}> Button text </span> </button>)}} // page export Default class Page extends React.Component{render(){// Set type to primary,plain to false disabled to true return <Button Type ='primary' plain={false} disabled></Button>}} // render result < Button class='zj-button zj-button--primary Zj-button --disabled'> <span class='zj-button__text'>Copy the code
API specification
// cssBem('button') const nbem = cssBem('zj','button') nbem() // zj-button nbem('text') // zj-button__text nbem(['primary']) // zj-button zj-button--primary nbem({disabled:true,plain:false}) // zj-button zj-button--disabled nbem(['primary',{disabled:true}]) // zj-button zj-button--primary zj-button--disabled nbem('text',['large',{show:true}]) // zj-button__text zj-button__text--large zj-button__text--showCopy the code
React Advanced components
// Use decorators
import {injectBem} from 'css-bem'

@injectBem('zj'.'button')
export default class Button extends React.Component{
    render(){
        const {type,plain,disabled} = this.props
        const { classnames } = this
        return <button className={classnames([type,{disabled,plain}])}>
                <span className={classnames('text')} >Button text</span>
            </button>}}// Use higher-order components
class Button extends React.Component{
    // Content and decorator always
}
export default injectBem('zj'.'button')(Button)
Copy the code
Vue mixins
import {vueMixin} from 'css-bem' export default{ mixins:[vueMixin('zj','button')] } <template> <button <span :class="classnames([type,{disabled,plain}])"> <span :class="classnames('text')"> </span> </button> </template>Copy the code
Other instructions
 // Do not use namespace and block
 import {flatten} from 'css-bem'
 flatten('header'['header__text', {'header__icon--show':false.'header--dark':true
 }])
 /** outputs 'header header__text header--dark' */
 
Copy the code