MichealWayne / Moo-CSS

模块化面向对象的css写法规范策略。适用于大中小型C端项目样式开发,旨在提高开发和维护效率。

Home Page:http://blog.michealwayne.cn/Moo-CSS/docs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Moo-CSS

以样式自动化为目标,模块化面向对象的css写法规则策略Moo-CSS, 以及通用Base层样式库moo-css-baseMoo-CSS文档地址>>, English introduce>>Moo-CSS生态(建设中)>>

Moo-CSS

  • 核心:组件模块化+面向对象。
  • 优点:
    • 重用性强
    • 维护性强
    • 拓展性强
  • 缺点:
    • 上手(理解)成本稍高~

主要目录结构:

Moo-CSS
├─moo-css-base
│   ├─less	// less base
│   ├─sass	// sass base
│   └─stylus	// stylus base
├─docs		// documents
└─demo      // demos

milestones

  • 2021.12: moo-css-base、moo-css-transformer优化;
  • 2021.06:webpack/snowpack插件;可视化sketch2code lowcode;
  • 2020.12: sketch2code转换服务;
  • 2020.06: 生态插件(Chrome插件,VSCode插件);
  • 2019.12: Moo-CSS写法策略及moo-css-base。

guide

Moo-CSS structure

moo-css-base

moo-css-transformer

css代码/moo-css选择器的相互转换

moo-css-web

虚拟dom -> 符合moo-css规范的web代码

moo-css-weapp(todo)

虚拟dom -> 符合moo-css规范的小程序代码

moo-css-sketch(todo)

sketch -> web/weapp


基本规范

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

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

1 M(模块化)

Moo-CSS中的M(Module),模块化。Moo-CSS的模块化主要体现在样式属性的模块化以及样式层级的模块化。

1.1 样式属性分类

根据样式属性的特征,Moo-CSS将样式属性分类样式划分为以下模块,并根据模块特征给定命名前缀(命名规则-标志前缀):

  • grid布局样式。布局、位置相关样式。如margin, position, line-height等;
  • function功能样式。文字居中、溢出隐藏等功能性样式。如clear, text-align, overflow, font-style, font-weight, font-family, vertical-align, white-space, text-decoration, text-indent等;
  • unit单元样式。宽高、padding等影响块或元素的常用单元样式。如width, height, padding, display, border, flex等;
  • status状态样式。透明度、是否隐藏、层级等显示状态样式(是唯一可设置!important的部分)。如visibility, opacity, z-index, transform等;
  • skin皮肤样式。主题颜色背景色等。如color, background-color, box-shadow等;
  • animation动画样式。过渡和动画。如animtaion, transition。

另外两种特殊模块:

  • JavaScript DOMDOM操作样式。供js操作DOM节点,建议不带有样式属性
  • React/Vue/Angular sepcial框架独有样式。供专有框架使用,如过渡动画。

更多样式属性归类可参考样式模块词典>>

注意,Moo-CSS推荐其中 grid, module, unit, component, status, animation通常由className实现; skin通常由属性(attribute)实现,*小程序通过className实现; function大部分由className实现,部分低权重样式由属性实现。

使用className以及attribute来确认样式可以较好避免权重问题,且从中我们可以得知skin作为辅助样式而样式权重相比较低。Moo-CSS推荐避免ID以及!important进行样式开发,有且仅有一个!important样式用于元素隐藏(.z-hide { display: none !important })。

1.2 样式分层

样式分层

根据样式属性的特征,将项目样式分层为以下模块层级:

  • Base:基础层。样式最底层,包含样式重置reset、提供样式变量及方法、供给极常出现的样式库。(通常所有页面共用且不做修改操作)。
  • Component:组件层。包含样式组件和方法组件,简单组件样式。如按钮、蒙层;方法组件包括动画方法和mixins方法。可依赖于Base层和Skin层。
  • Skin:皮肤层。设置颜色、背景色、屏幕媒体查询设置等皮肤,且提供项目独有颜色变量。常供应于Component层和Module层;
  • Module:模块层。根据业务划分的模块,常作为Component的容器。依赖于上面几个模块以及Layout层;
  • Layout: 结构层。提供Module层和其中的Component布局样式,构成最终页面。

其中,Base、Component、Skin、Layout中样式作用域为全局,Module层样式保持私有性。各层级保持独立性,满足SRP(单一功能原则)。

详细介绍可见文档-样式分层

1.3 Base层样式权重计算

权重计算参考公式:

1 / (样式资源量 / 样式属性耦合度 * 0.4 + 0.3 / 样式使用率 ^ 2 + 选择器权重 * 0.3)

数值越大权重越高,高权重可归入Base层。

其中,样式资源量可由样式代码量和引入资源大小进行衡量;样式属性耦合度是指在多样式属性的样式中,属性直接的耦合度,如溢出显示'...'这样的耦合度就非常高;样式使用率主要考虑多页面(包括路由页面)的样式使用率;选择器权重计算值越小越好。权重公式仅做参考,简单来说就是提取高频使用且不占用大量资源的原子样式/方法。

2 OO(面向对象)

Moo-CSS中的OO(Object-Oriented),面向对象。Moo-CSS的面向对象主要体现在Component和Module层。

同OOCSS,Moo-CSS中的CSS对象由以下4部分内容组成:

  • HTML,可以是DOM的一个或多个节点;
  • CSS声明,关于这些DOM节点样式的CSS声明,其中部分CSS声明满足私立性;
  • 资源组件,如背景图片,sprites等用于展示资源的;
  • 事件,与对象关联的javascript行为、侦听器或方法。

2.1 两个原则

2.1.1 分离结构和皮肤

分离结构和皮肤意味着要将重复的样式特征(如背景和边框等样式)定义为单独的“皮肤”,通过和其他各种CSS“对象”的混合及匹配,使得在没有太多代码的情况下实现大量的视觉变化。

比如说一个渐变按钮,那么 .btn 的 class 是不会包含渐变相关的属性的,而是需要单独抽取出一个渐变的 class,然后让 .btn 去扩展从而得到一个渐变的按钮。

2.1.2 区分容器和内容

区分容器和内容意味着将很少使用位置相关的样式,一个CSS“对象”应该不管放到哪里看起来都一样。所以不要用.myObject h2{ ... }来设置特定的<h2>样式,而是应该创建并应用一个描述与<h2>相关的class,如<h2 class="category">

总得来说,就是满足SRP(单一职责)、OCP(开放封闭)

2.2 OO特征

2.2.1 封装

Moo-CSS的封装特性一方面体现在Module/Component中对象内容的封装,保持对象之间的独立性; 另一方面,各样式属性/方法的封装以及各样式层级的封装均体现了其封闭性。

2.2.2 继承

页面Module层/Component层可由其他Component层进行样式继承和拓展,各模块符合开闭原则(The Open/Closed Principle)

2.2.3 多态

Moo-CSS所说的多态一方面是指对应平台的多态样式/方法。比如moo-css-base移动端和PC端的Component层分别提供了rem换算方法torem,调用方式相同而移动端进行了1:75的单位换算,而PC端进行了1:54的单位换算。

3 命名

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

className或attribute的写法为:

prefix-className/attribute_字母值

prefix-className/attribute数字值

基本规则

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

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

  • 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]

类名为module时,按照如下命名规则

3.1 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的设置(可见文档) ReactJS需要设置webpack配置文件中cssOptions参数的modules为true。

如:

<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 classnames from 'classnames';

import style from './index.scss';

export default function Footer () {
  return (
  <footer>
    <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;
  }
}

4 命名词典以及moo-css-base查询词典

更多详细内容请见文档>>


5 moo-css-base

moo-css-base为本人从团队多年项目中抽离的公用CSS样式/方法库,遵守Moo-CSS规范,作为页面样式的Base层在全局使用。

  • 功能:浏览器默认样式reset、提供常用原子样式、组件样式基础、颜色变量及常用mixins方法库。
  • 兼容:移动端安卓4.4及以上/ios8.1及以上;PC除flex外兼容IE6。
  • 体积:其css压缩版本大小(gizp)为移动端3.5k、PC端4.2k。
  • 预处理支持情况:less/sass/stylus。
  • moo-css-base可直接在项目中按需引用,或者可以作为Base层的划分参考。

具体使用和介绍请前往Moo-CSS moo-css-base


反馈

About

模块化面向对象的css写法规范策略。适用于大中小型C端项目样式开发,旨在提高开发和维护效率。

http://blog.michealwayne.cn/Moo-CSS/docs/

License:MIT License


Languages

Language:CSS 24.2%Language:SCSS 24.1%Language:Less 23.6%Language:Stylus 21.6%Language:JavaScript 6.5%