命名规则

选择器命名由小写字母,_-符号组成,并通过标志前缀来确定样式命名空间。

className或attribute的写法为:

标志前缀-className/attribute_字母值

标志前缀-className/attribute数字值

基本规则

  • 类名或属性名由小写字母、数字、_-符号组成,不包含大写字母;
  • 连字符分隔单词(-),以代替驼峰式命名。如:head-menu;
  • 单下划线分隔属性和英文值(_)。如:color_red;
  • 双下划线分隔模块和元素(__)。如:nav__item。

其中标志前缀由样式模块确认:

  • g-:grid
  • f-: function
  • u-: unit、Component unit
  • z-: status
  • s-: skin
  • a-: animation
  • m-: Module

特殊样式模块前缀:

  • j-: JavaScript DOM
  • v*-: VueJS专用,如VueJS专用动画.va-fadein
  • r*-: ReactJS专用,如ReactJS专用宽度.ru-w100
  • a*-: Angular专用,如Angular专用皮肤.as-cr_red

属性简写规则,通常由属性单词首字母组成,部分较长的样式属性单词或避免重复可取首字母和中间字母。如margin-top -> mtbackground-color -> bgc;属性值单位值为px时,省略px;为rem/vw时,数值转为px并省略rem/vw;为%时,则%换为per, 如padding-left: 30px -> pl30width: 1rem -> w75margin-top: 2vw -> mt15left: 50% -> l50per。更多属性简写可参考样式属性命名>>

属性值为非模块时,名字为标识,如iconovhidden

结合标志,如下

.u-w30per
.g-mt30
.f-blod
.s-bgc_red
[s-cr_red]

className为module样式时,按照如下命名规则

ID、class、attribute选择器的使用范围

  • ID:不做样式使用,仅作js DOM操作或作为容器
  • class:主要样式
  • attr:作为皮肤控制

Module命名规则

Module结合Base层、Component层、Skin层、Layout层完成整个样式。其命名通常与项目业务耦合,部分缩略命名可参考Module命名词典>>

方式1:BEM的BE

(标志前缀)-类块__类元素

其中标识前缀可省略

Module分为块(Block)及元素(Element),

  • Block,即OO中的容器,是用来标识一个具体块的关键字其实就是这个块的名字,如:->head, 内容->content, 导航->nav, ->foot。一个块必须有一个唯一的名字(类),这样才能保证块的独立性。 块由gird来控制其布局。

  • Element,依赖于块的元素。是用来标识一个元素的关键字,也是这个元素的名字。如导航栏链接或菜单的每一项->item 我们在长名称中使用连字符分隔单词(例如,block-name),使用两个下划线来分隔块名和元素名(block-name__element-name)。 块名称为其元素和专属修饰符定义命名空间。

<nav class="m-nav">
    <a class="m-nav__item">nav 1</a>
    <a class="m-nav__item">nav 2</a>
</nav>

再结合其它层完成整个样式

<section class="g-pr">
    <nav class="m-nav f-tc g-pa g-t50l100" u-size="big" s-bgc_yellow>
        <a class="m-nav__item">nav 1</a>
        <a class="m-nav__item nav_type_selected">nav 2</a>
    </nav>
</section>
/* layout */
.g-pr { position: relative; }
.g-pa { position: absolute; }

/* function */
.f-tc { text-align: center; }

/* unit */
[u-size="big"] { width: 500px; font-size: 30px }
[u-size="small"] { width: 50px; font-size: 10px }

/* skin */
[s-bgc_yellow] { background-color: yellow }

/* module */
.m-nav { /*...*/ }
.m-nav__item { /*...*/ }

方式2:css modules/CSS in JS

如果使用了CSS in JS或者css modules来指定Module的话,则可避免模块元素及修饰符的依赖式写法。(避免BE写法)

VueJS(vue-cli)可直接在style标签中设置module属性完成css module的设置(可见文档 vue css-modules) ReactJS需要设置webpack配置文件中cssOptions参数的modules为true。

Vue使用如:

<template>
    <section :class="$style.foot">
        <p>
            <img :class="$style.img" src="@/images/i-logo_b.png">
        </p>
        <p>@All right reserved | Design by <a href="https://github.com/MichealWayne/">Micheal Wayne</a></p>
    </section>
</template>

<style lang="less" module>
    .foot {
        line-height: 10vw;
        word-break: keep-all;
        white-space: nowrap;
		
		.img {
			width: 10px;
			height: 10px;
		}
    }
</style>

结合其它层完成整个样式

<template>
    <section :class="[$style.foot, 'f-tc']">
        <p class="u-pt80">
            <img :class="[$style.img, 'g-mb20']" src="@/images/i-logo_b.png">
        </p>
        <p class="g-fs22 u-pb100" s-cr_sub>@All right reserved | Design by <a class="f-unl" s-cr_blue href="https://github.com/MichealWayne/">Micheal Wayne</a></p>
    </section>
</template>

<style lang="less" module>
    .foot {
        line-height: 10vw;
        word-break: keep-all;
        white-space: nowrap;
		
		.img {
			width: 10px;
			height: 10px;
		}
    }
</style>

react 例子

import React, {Component} from 'react';
import style from './index.scss'
import classnames from 'classnames'

export default class Footer extends Component {
    render () {
        return (
            <footer className={classnames(style.foot, 'f-tc g-fs12 f-b_1px bt_1px g-mt60')} s-theme__foot="1">
				<p class="u-pt80">
					<img className={classnames(style.img, 'g-mb20')} src={require('@/images/i-logo_b.png')}>
				</p>
                MIT Licensed | Copyright © 2019-present MichealWayne
            </footer>
        )
    }
}
// index.scss
.foot {
    padding: 40px;
	
	.img {
	    width: 10px;
		height: 10px;
	}
}

样式属性及className书写顺序

Moo-CSS推荐分别通过样式属性以及className的书写顺序来提供更为直观且易于管理的代码,同时也表明了样式及层级的选择器权重优先级顺序。

样式属性顺序

grid(Layout) > grid > unit > function > skin > status > animation

.m-item1 {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 8;
    width: 100%;
    height: 50px;
    font-size: 12px;
    background-color: #f00;
}

.m-item2 {
    float: right;
    display: block;
    font: normal 13px "Helvetica Neue", sans-serif;
    line-height: 1.5;
    text-align: center;
    color: #333;
    background-color: #f5f5f5;
    border: 1px solid #e5e5e5;
    border-radius: 3px;
    opacity: 1;
}

className顺序

Module/Component > Base(unit) > Base > Skin(className) > Layout > Skin(attribute) > JavaScript DOM/ Frame special

<div class="m-menu u-h30 f-tc g-mt20 j-topage">classNames</div>

className > attribute

可以很好理解,className权重大于attribute选择器,在HTML中也是以此顺序排列,如

<div class="m-menu u-h30 f-tc g-mt20 j-topage" s-cr_red>classNames</div>