一些编写css的建议
工欲善其事,必先利其器
在编写css的时候,你需要至少掌握一个开发工具,无论是SASS,还是LESS,本质上来说他们一样的,只是语法有点不一样。如果你还是在纯手写css,那么请尽快了解它们,并根据自己的习惯选择其中一个并使用他们。个人而言,我比较喜欢sass,更符合我的书写习惯。也有很多人喜欢Less,他们觉得less语法更加便捷。
什么SASS/LESS
SASS(LESS)是CSS3的一个扩展,增加了规则嵌套、变量、混合、选择器继承等等。通过使用命令行的工具或WEB框架插件把它转换成标准的、格式良好的CSS代码。
为什么需要SASS/LESS
它们作为一个开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护。
它们也是编写模块化、可维护的CSS的基石。
该如何使用
网上关于SASS/LESS的教程一大堆,我这里不浪费篇幅写基本语法了。
可以自己去网上搜索,它们都差不多,学了一个基本都可以使用了:
下面的内容我用SASS举例,内容不限于SASS,LESS同样适用!
神说,无规矩不成方圆
是的,无规矩不成方圆,你需要了解一种css命名规范或者制定自己的规范(不建议自定义,不利于团队合作);
为什么需要有一种命名规范呢?
当你编写过大量css时候,你就发现没有一种有效的命名规范会让你痛不欲生。如果你在一个稍微大一点的项目中,或者在与其他人合作开发的过程,这种感觉特别明显。因为当你为css命名的时候会发现这个命名在别的地方使用了,或者队友已经使用过了,你必须重新命名。久而久之,css的命名就会杂乱无章而且又臭又长,一眼望去根本猜不到这个命名的意义。
BEM命名规范
各种命名规范是仁者见仁,智者见智,在这里我介绍下BEM命名规范,我介绍的不一定就是适合你的,你需要自己思考何种命名规范适合自己。。
BEM是由Yandex团队提出的一种CSS Class 命名方法,旨在更好的创建CSS/Sass模块。
BEM的意思就是块(block)、元素(element)、修饰符(modifier)。
●block: 可以理解为一个区域、一个组件或者一个块级元素,具体如何区分需要根据实际情况具体分析;
●block__element: 就是一个上面的block里面的元素,比如说导航(nav:block)里面有a标签(a: element)就是一个元素, block与element使用两个下划线链接;
●block__element–modifier: 我的理解是状态或属性。比如element里面的a标签,它有active、hover、normal三种状态,这三种状态就是modifier。midifier是使用两个“–”中横线连接
就上面所说的例子我用实际的代码来示范下:
<!-- HTML结构 --><nav class="nav"> <a href="#" class="nav__item nav__item--active">当前页:active</a> <a href="#" class="nav__item nav__item--hover">假设鼠标在这里要加个hover的class</a> <a href="#" class="nav__item nav__item--normal">假设需要加个normar的状态</a></nav>
// SASS写法.nav{ &__item{ &--active{ <!-- active样式 --> } &--hover{ <!-- hover样式 --> } &--normal{ <!-- normal样式 --> } }}
/* 编译后的css */ .nav{ } .nav__item{ } .nav__item--active{ } .nav__item--hover{ } .nav__item--normal{ }
从上面的例子可以一眼看出css的含义,而且编译后的css没有任何的嵌套,但是SASS的结构却很清晰,一目了然。
由此可见,使用SASS配合BEM可以写出一份易读、可维护、模块化的代码;
神说,我不认识你
一份可读性的SASS必须有一份说明,一个文件,一个函数都需要一份说明。
对于一份SASS文件,你至少需要说明两点,这份SASS是公用还是私有、哪个页面哪个部分
@charset "utf-8"/** 预定义函数* author:xxx* time:xxxx-xx-xx*//** 清除浮动* use: @include clearfix();* author: xxx* time: xxxx-xx-xx*/@mixin clearfix(){ *zoom: 1; &:before, &:after { content: ""; display: table; } &:after { clear: both; overflow: hidden; }}
神说,世界要统一
●reset
css reset必不可少,网上有很多css reset的代码,compass也有reset的module,只需要@import “compass/reset”。如果你觉得这些代码太冗余,太多,你至少需要保证你的css有margin和padding的reset,这样才可以保证在各个浏览器中css有相同的样式。
*{ margin: 0; padding: 0;}
●间距/行距/边距
●字号
●颜色
●层级
●高度
……
为什么需要variables
使用一份单独的variables,好处很多,最大的好久就是可维护性,谁用谁知道!
可维护性
●等你开发完了,拿给设计师验收,设计师说这里不好,换个颜色!—— 没事,我改个变量!
●产品说,这里不好,列表间距太大了,小屏幕只显示那么一点点!—— 没事,我改个变量!
●来来来,产品说我们换一套皮肤! —— 没事,我重新定义一份变量!
……
这些例子可以让你明白有一份variables是多么重要了吧。其实这些只是在可维护方面的好处。作为一名前端,我们是最接近用户的工程师,我们不能仅仅停留在代码层面,更需要的是站在用户体验的角度思考问题,而variables可以让我们有一套规范,确保页面一致性
一致性
FE是面向用户的,我们需要对用户负责。设计师在设计页面的时候,不能所有的像素的都很精确,不可能每次的颜色都是毫无差错的。所以在这时候,就需要规范了,如果设计师没有规范,那我们自己制定一套规范。例如:
●同一个项目,一个页面的列表高度是20px,另一个页面的列表是21px,这时我们无需理会,直接使用我们之前定义的列表高度进行开发。
●同一个页面,有两个error的颜色#dc4c4c和#d84a4a,我们也无需理会,使用统一的error颜色变量;
这些是用户体验的细节,通过一份variables可以让我们保持页面的一致性。
这里只是略微提下用户体验,之后我再写一篇《前端工程师必须重视的用户体验》来详细讲解下用户体验。
module(模块化,基于SASS/LESS)
模块化在js中经常听到,对于css来说,模块化对于易读性和可维护性同样重要。那么如何来做模块化呢?
多文件夹
建立多个文件夹,分类存放sass文件。例如:将variables、mixin、公共样式、私有样式分成多个文件夹存放;
多文件
同一个文件夹的sass可以按模块、功能等等分成多个文件,最终用@import 导入
这样说的有点粗糙,我举个例子吧(下划线开头的sass文件不会编译单独css文件)
——sass ——config //基本变量 ——mixin //函数 ——common //公用 ——header ——aside ——_list.scss ——_nav.scss ——_base.scss ——compoment //组件样式 ——dropdown ——lightbox ——page ——index //首页 ——_ad.scss //广告样式 ——_content.scss //内容信息 ——_info.scss //个人信息样式 ——_base.scss //index样式,@import 'ad';@import 'content';@import 'info'; ——write ——preview ——_aside.scss //preview页面独有侧边栏 ——about ——main.scss //导入所需要的样式,最终生成一个main.css
如上面所示的目录结构,能让人一目了然sass的目录的结构,维护的时候可以快速准确的找到文件。
如果是多页面的项目,也可以最大限度复用代码,而且可以导出公用样式,利用缓存提高加载速度,不用每个页面都重复写一样的代码。
注意:common文件夹的公共样式必须是其他页面所共有的样式,如果有些页面有特殊的样式,应该将会覆盖的css抽取出来,在页面中分别导入不同的私有样式。
根据命名规则限定使用样式
比如说preview页面有一个私有aside样式,可以在这样写preview里面的_aside.scss:
@charset "utf-8"/** 预览页面侧边栏* author:xxx* time:xxxx-xx-xx*/@import '../../common/aside/base'.preview{ .aside{ /* css */ &__item{ /* css */ } }}
这里需要注意的是,css覆盖会导致重新渲染,影响性能。