背景介绍:当我们在从事大项目或团队开发工作时,我们经常会发现我们写的代码,凌乱、难以阅读并且难以扩展。尤其是当一段时候后我们回头再看自己的代码,必须回想起当初自己写的时候的思路才能看懂。

因此,人们尝试在代码风格上保持统一,然而,最大的困难是:修改一个较小的问题,都可能创建更多丑陋的 hack,也可能 CSS 的小改变会影响 JavaScript 的功能。但是这些问题能在我们的项目开始的时候精心规划,就能很大程度上避免这些问题。今天就来讨论一下如何写一份不错的CSS代码

一个好的css代码是什么样的呢

  • 保持样式表可维护

  • 保持代码可读性

  • 保持样式表的可扩展性

要保持良好的CSS代码,首先需要订立一致的CSS团队规范,这就必须从CSS架构讲起。

CSS架构

目前CSS主要有以下五种设计架构

1. OOCSS

面向对象的CSS,

  • 结构和主题分离 - 减少对 HTML 结构的依赖

  • 主题和主题分离 - 增加样式的复用性

在OOCSS的基础上,出现了另一种设计模式

2. BEM

也可以被当成一种命名规范,本质上使页面结构清晰

块(Block)、元素(Element__)、修饰符(Modifier--)

有以下几个规则

  • Block元素应该以元素本身的属性为主

  • Element则以元素位置和形状为主

  • Modifier则修饰当前的状态和主题

  • Element一定是在Block之中,而不能独立于Block之外

  • Modifier则更多的表示当前组件的形状和状态

可以明显发现

  • 结构清晰

  • 定位迅速

  • 功能明确

在面对组件化的场景时,Block 代表逻辑上和功能上独立的页面组件。Element封装了行为(JavaScript)、模板、样式(CSS)和其他实现技术。

举个例子

<header class="header"><img class="logo"><form class="search-form"><input class="input"><button class="button"></button></form><ul class="lang-switcher"><li class="lang-switcher__item"><a class="lang-switcher__link" href="url">en</a></li><li class="lang-switcher__item"><a class="lang-switcher__link--active" href="url">ru</a></li></ul>
</header>
  • block-name__element-name--modifier-name--modifier-value

在React当中,也采用了这样的命名方式

BEMnaming工具[1],提供BEM命名的检测

然而在面对大型的项目时CSS的凌乱也很难让开发者愿意在茫茫多的代码中寻找可复用的代码

3. SMACSS

(What’s Smacss)[https://smacss.com/]

设计的主要规范有三点:

  • Categorizing CSS Rules(为css分类)

  • Naming Rules(命名规范)

  • Minimizing the Depth of Applicability(最小化适配深度)

为了实现清晰的CSS结构,将CSS分为

  • Base - 全局样式,如global-reset、normalize.css

  • Layout - 页面布局,如grid

  • Module - 组件布局

  • State - 元素状态,如visible、hidden

  • Theme or Skin - 更多是具体主题的配置样式

  • JavaScript 勾子 (JavaScript hooks)

其中尤其建议JavaScript解除和样式的耦合

<button class="btn btn--buy js-buy-now"></button>

命名规范上出现了一些差异

.layout-header
.is-hidden
.theme-nav

最小化适配深度,减少html和css的耦合度,避免html的变动增加对css的影响

.sidebar ul h3 {}.side {}

4. ITCSS

对CSS进行了更加详细的分层

如果从功能的角度上看呢,是将Base分成了Settings、Tools、Generic和Base,而Objects、Components和Trumps则分别对应Layout、Module、(State、Theme),而这样设计的好处在于可以将代码的复用性进一步提升

5. ACSS

一个样式属性一个类,其中的典型代表就是TailwindCSS[2],缺点则是破坏了语义化

.block{ display: block; }
.hidden { display: none; }
.p-2 { padding: 0.75rem; }
.flex { display: flex; }
.text-base { font-size: 1rem; }
.bg-green-200 { background-color: #123456 }<div className="m-2 p-2 text-2xl text-gray-500">I am Ok</div>

而上述的架构思想,更多则是需要团队成员的一致性认同,才能实现在代码风格上的统一。

除了这些开发自律性上的代码规范外,还有什么其他的方式来提升CSS质量呢?

CSS预处理器

在预处理器中,同样提供了众多的方法来简化与控制CSS代码,以stylus为例

1. 变量

font-size = 14pxbodyfont font-size Arial, sans-serifpad(types = padding, n = 5px)if padding in typespadding nif margin in typesmargin nbodypad()
bodypad(margin)
bodypad(padding margin, 10px)// Yields:
body {padding: 5px;
}
body {margin: 5px;
}
body {padding: 10px;margin: 10px;
}

2. 函数

add(a, b = a)a + badd(10, 5)// => 15get(hash, key)return pair[1] if pair[0] == key for pair in hashhash = (one 1) (two 2) (three 3)get(hash, two)// => 2get(hash, three)// => 3get(hash, something)// => null

3. 内建函数

// 提取颜色分量
red(#c00)
// => 204red(#000, 255)
// => #f00

4. 插值

// 属性插值
vendor(prop, args)-webkit-{prop} args-moz-{prop} args{prop} argsborder-radius()vendor('border-radius', arguments)box-shadow()vendor('box-shadow', arguments)buttonborder-radius 1px 2px / 3px 4px// Yields:    button {-webkit-border-radius: 1px 2px / 3px 4px;-moz-border-radius: 1px 2px / 3px 4px;border-radius: 1px 2px / 3px 4px;}// 选择器插值
tablefor row in 1 2 3 4 5tr:nth-child({row})height: 10px * row// Yields:  table tr:nth-child(1) {height: 10px;
}
table tr:nth-child(2) {height: 20px;
}
table tr:nth-child(3) {height: 30px;
}
table tr:nth-child(4) {height: 40px;
}
table tr:nth-child(5) {height: 50px;
}    mySelectors = '#foo,#bar,.baz'{mySelectors}background: #000Yields:#foo,
#bar,
.baz {background: #000;
}  // 对象插值
foo = {width: 10px,height: 20px,'&:hover': {padding: 0}
}.bar{foo}Yields:// => .bar {
//      width: 10px;
//      height: 20px;
//    }
//    .bar:hover {
//      padding: 0;
//    }

5. @EXTEND

forminput[type=text]padding: 5pxborder: 1px solid #eeecolor: #dddtextarea@extends form input[type=text]padding: 10px//Yielding:form input[type=text],textarea {padding: 5px;border: 1px solid #eee;color: #ddd;}textarea {padding: 10px;}

对于维护一份高质量的CSS代码,注释和间隔必不可少

以下是一种比较建议的注释和间隔方式,可以自行取用。

/*------------------------------------*\#A-SECTION
*------------------------------------*/.selector { }/*------------------------------------*\#ANOTHER-SECTION
*------------------------------------*//*** Comment*/.another-selector { }

除了缩进,我们还可以通过在规则集之间自由而明智地使用空格来提供大量信息。我们用:

  • 密切相关的规则集之间的一 (1) 条空行。

  • 松散相关的规则集之间的两 (2) 条空行。

  • 全新部分之间的五 (5) 行空行。

// good case
/*------------------------------------*\#FOO
*------------------------------------*/.foo { }.foo__bar { }.foo--baz { }// bad case
.foo { }.foo__bar { }
.foo--baz { }

同理,在html结构中,也可以使用同样的规则。

除了以上这些,还有众多的规范和优化可以继续探索,如选择器性能,CSS嵌套,有兴趣的读者可以继续探索

你会认为 CSS规范是一个有点宏大和不必要的概念:为什么这么简单、这么直接的东西需要像架构一样被设计成非常复杂的东西?!

正是因为CSS 的简单性、松散性和不守规矩的性质意味着在任何合理规模上管理(阅读、驯服)它的最佳方式是通过严格和特定的架构。坚实的架构可以帮助我们控制我们的特殊性,强制执行命名约定,管理我们的源代码顺序,创建一个健全的开发环境,并且通常使我们的 CSS 项目管理更加一致和舒适。

总的来说,可以依照一下几个规则订立团队/个人代码规范,保证代码的一致性

建议的几个原则

单一职责原则: 每个 CSS 实现都必须有一个单一的责任。

Correct:.button {font-family: Arial, sans-serif;border: 1px solid black;background: #fff;}.header__button {margin: 30px;position: relative;}Incorrect:.header__button {font-family: Arial, sans-serif;position: relative;border: 1px solid black;margin: 30px;}

开闭原则: 元素应该通过修饰符扩展,而不是直接在原有基础上修改。

Original:<button class="button">...</button>.button {font-family: Arial, sans-serif;text-align: center;font-size: 11px;line-height: 20px;}Extend<button class="button button_size_s">...</button>.button {font-family: Arial, sans-serif;text-align: center;font-size: 11px;line-height: 20px;}.button_size_s {font-size: 13px;line-height: 24px;}

DRY原则:将有意义的重复规范化和抽象化

巧用mixin和extend
@mixin my-web-font() {font-family: "My Web Font", sans-serif;font-weight: bold;
}.btn {display: inline-block;padding: 1em 2em;@include my-web-font();
}.foo {color: red;
}
.bar {@extend .foo;
}

组合优于继承和关注点分离

// 将写js的方式同样适用在css上
<div class="layout"><div class="layout__item  two-thirds"><section class="content">...</section></div><div class="layout__item  one-third"><section class="sub-content">...</section></div></div>

参考资料

[1]

BEMnaming工具: https://github.com/bem/bem-sdk#naming

[2]

TailwindCSS: https://www.tailwindcss.cn/

[3]

BEM简介: https://en.bem.info/methodology/quick-start/

[4]

OOCSS介绍: http://oocss.org/

[5]

探索 SMACSS:可扩展的模块化 CSS 框架: https://zhuanlan.zhihu.com/p/44851489

[6]

编写高效的 CSS 选择器: https://csswizardry.com/2011/09/writing-efficient-css-selectors/

[7]

CSS的单一原则: https://csswizardry.com/2012/04/the-single-responsibility-principle-applied-to-css/

[8]

思考CSS架构: https://zhuanlan.zhihu.com/p/32952130

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

如何写一份不错的CSS代码?相关推荐

  1. Objective-c:写一份可测试的代码

    程序员大咖点击右侧关注,免费进阶高级! 作者:杜玮 https://dywane.github.io/ 前言 单元测试由程序员编写,最终又服务于程序员,但是在面对编写时复杂而繁琐的依赖注入.IoC,不 ...

  2. html页面css代码写在哪里,HTML、CSS代码书写规范

    HTML语义化语义化标签优先 基于功能.内容命名,尽量不使用表现命名 简略.明了.无后患1.所有命名都使用英文小写 推荐:` 不推荐: ` 2.命名用引号包裹 推荐:` 不推荐: ` 3.用中横线连接 ...

  3. 大佬教你如何写出更好的CSS,分享web前端资料

    让我们开门见山:编写优秀的 CSS 代码是件十分痛苦的事情.很多开发人员都不想做 CSS 开发.你让我干什么都行,但是 CSS 还是算了吧. 在我创建应用的时候,从来都无法从 CSS 中享受到乐趣.但 ...

  4. 写好CSS代码的70个专业建议

    写好CSS代码的70个专业建议-前端开发博客 CSS 并不总是容易处理. 在你的能力和经验不够的时候,CSS编程会成为一个噩梦,特别是你不确定为页面元素中选择哪种选择器的时候.使用一个不常见的CSS属 ...

  5. 写好CSS代码的70个专业建议-前端开发博客

    写好CSS代码的70个专业建议-前端开发博客 CSS 并不总是容易处理. 在你的能力和经验不够的时候,CSS编程会成为一个噩梦,特别是你不确定为页面元素中选择哪种选择器的时候.使用一个不常见的CSS属 ...

  6. 在react项目中编写css,更好的在react项目中写css代码--emotion

    简介: emotion是一个JavaScript库,使用emotion可以用写js的方式写css代码.在react中安装emotion后,可以很方便进行css的封装,复用.使用emotion后,浏览器 ...

  7. 如何写出兼容大部分浏览器的CSS 代码

    前阵子一直在从事b/s 项目的开发,在css 方面有一些心得体会,特写来与大家分享,欢迎大家评论,不过请勿人身攻击啊,因为在前几年我也写过一篇文章:[原]兼容浏览器的布局CSS心得体会 楼下有很多人的 ...

  8. CSS代码写一个网页,有留言板

    可以这样写 CSS 代码来创建一个留言板: /* 定义留言板的外观 */ .message-board {width: 500px;height: 400px;background-color: #f ...

  9. html中怎么写css代码,html style样式标签元素教程

    html标签元素之 时时在构造html时,使用到style标签. 认识与用法教程 一.基本语法 style英文翻译:格式.气概含意 从字面上也不难晓得与CSS款式干系的标签. 完结.标签内放CSS代码 ...

最新文章

  1. Windows文件系统过滤驱动开发教程(4,5)
  2. Gamma校正及其OpenCV实现
  3. Java Stub 研究学习(2)
  4. java 获取spring对象数组_解析Java中如何获取Spring中配置的bean
  5. Androd开发之通过ComponentName和setComponent以及scheme打开外部应用 | 打开任意页面 | 打开指定页面
  6. linux批量部署war工具,Linux 批量一键部署工具 Expect
  7. 前端之旅,做一点有回报的事情
  8. java int数组任何数之间间隔不能对于指定数,内付极速排序
  9. LeetCode 长度最小的子数组
  10. php存库,php – 使用Laravel实现存储库模式
  11. 云优CMS采集不需要云优CMS授权
  12. 802.11 Tx Rate Control
  13. 网页设计语言html做思维导图,纯css3实现思维导图样式示例
  14. 使用for循环编写倒立反方向直角三角形
  15. Android Edittext 手机号码格式输入设置
  16. epics安装css,EPICS-synApps/areaDetector安装
  17. 一念起,万水千山;一念灭,沧海桑田。
  18. 01背包问题java_01背包问题 动态规划 java实现
  19. 云计算、雾计算和边缘计算
  20. 云服务器可以换系统不,云服务器可以换系统吗

热门文章

  1. C语言qsort函数详解
  2. [HIHO] 1048 铺地板
  3. 计算机网络题库--第五单元传输层
  4. 勇攀监控高峰 | EMonitor 之根因分析
  5. python中的get()和item()函数
  6. 新手没有灵感也可以写好短文案的六个方法,第六个最实用
  7. DW1820a 黑苹果开机一段时间 卡死机问题或者屏蔽针脚问题
  8. Deepin深度操作系统小问题合集
  9. Cstyle的UEFI导读:第20.0篇 IGD OpRegion interface IGD OpRegion PROTOCOL
  10. Jquery ajax 获取数据以及jQuery.parseJSON