改善CSS的10种最佳做法

    |     2020年5月18日   |   web前端技术, 优化   |     0 条评论   |    1217

英文 | https://medium.com/better-programming/10-best-practices-for-improving-your-css-84c69aac66e。CSS 看起来很难写错:加几条规则就能改外观。小站点几个文件确实如此;大应用里样式会迅速失控。如何让它可管理?

和其他语言一样,CSS 能成全也能毁掉设计。下面 10 条实践,帮你从样式里拿到最大收益。

序号 做法 收益
1 先问要不要框架 少带用不到的选择器
2 BEM / ITCSS / OOCSS 命名和分层一致
3 预处理器 + 后处理器 拆文件、前缀、变量
4–7 语义标签、简写、去冗余、简单选择器 更小更快更好改
8–10 保留 :focus 轮廓、移动优先、压缩 可访问、少覆盖、体积小

一、你真的需要一个框架吗?

先确定要不要 CSS 框架。现在有不少轻量替代。通常你不会用到框架里每个选择器,包里就会有无效代码。

如果只用按钮样式,把那部分拷进自己的 CSS,删掉其余。也可以用 DevTools 的代码覆盖率找未使用规则。

image-20200518081713408

在工具面板搜 Coverage,或 Ctrl+Shift+P 打开工具面板。点重新加载开始录制。红色表示未使用。上例显示 98% CSS 未使用——其实不完全是:有的样式要交互后才用,移动端样式也会标成未使用。删之前务必确认真没用。

二、首选一套 CSS 方法

方法是为了文件里的一致性,方便扩展和维护。

BEM

Block、Element、Modifier,最流行的命名之一,方便做可复用组件:

.block { ... }.block__element { ... }.block--modifier { ... }
  • .block:组件,独立实体。
  • .block__element:块的一部分,必须绑在块上。
  • .block--modifier:外观、行为或状态标志,例如 .block--hidden。

ITCSS

倒三角 CSS:一层层加特性,越往下越具体。

image-20200518081733107

OOCSS

分离结构和皮肤:视觉效果不要和结构写死在一起。

/* Instead of  */
.box {   
    width: 250px;    
    height: 250px;    
    padding: 10px;    
    border: 1px solid #CCC;    
    box-shadow: 1px 2px 5px #CCC;    
    border-radius: 5px;
}
/* Do */
.box {    
    width: 250px;    
    height: 250px;    
    padding: 10px;
}
.elevated {    
    border: 1px solid #CCC;    
    box-shadow: 1px 2px 5px #CCC;    
    border-radius: 5px;
}

分隔容器和内容:元素不要依赖所在位置,同一元素在哪都应长一样。

/* Instead */
.main span.breadcumb { ... }
/* Do */
.breadcrumb { ... }

三、设置预处理器

预处理器提供 CSS 没有的高级能力:循环、变量、函数。常见是 Sass、Less、Stylus。建议 Sass:社区和文档都多。

可以把文件拆成可复用的小文件,互相 import,或分别引进应用:

// Import different modules into one SCSS file
@import 'settings';
@import 'tools';
@import 'generic';
@import 'elements';
@import 'objects';
@import 'components';
@import 'trumps';

嵌套选择器

CSS 本身缺的简单能力,嵌套能看清结构:

.wrapper {    
    .sidebar {        
        &.collapsed {            
            display: none;        
        }
        .list {            
            .list-item {               
                ...
                &.list-item--active {                   
                    ...               
                }            
            }        
        }    
    }
}

自动加浏览器前缀

实验性特性要加前缀:-webkit-(Chrome/Safari/新 Opera)、-moz-(Firefox)、-o-(旧 Opera)、-ms-(IE/Edge)。支持主流浏览器就要写多遍:

.gradient {    
    background: rgb(30,87,153);    
    background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    background: linear-gradient(to bottom, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);}

mixin 可以当函数用,避免硬编码重复:

@mixin gradient() {    
    background: rgb(30,87,153);    
    background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    background: linear-gradient(to bottom, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);    
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);}
.gradient {    
    @include gradient();
}

后处理器

预处理器生成 CSS 后,后处理器再优化。常见是 PostCSS:按 Can I Use 自动加前缀。autoprefixer 甚至不用手写前缀,例如支持最近四个版本:

const autoprefixer = require('autoprefixer')({    
    browsers: [  'last 4 versions',  'not ie < 9'    ]
});

用变量做一致设计

变量和 mixin 一起,能把设计规则固化:

// Font definitions
$font-12: 12px;
$font-21: 21px;// Color definitions
$color-white: #FAFAFA;
$color-black: #212121;

四、能用标记就别堆 CSS

选对 HTML 元素就能减小 CSS。标题如果写成:

span.heading {    
    display: block;    
    font-size: 1.2em;    
    margin-top: 1em;    
    margin-bottom: 1em; 
}

用 span 当标题就要覆盖 display、间距、字体。换成 h1/h2/h3,默认样式已经够用,四条规则可以立刻丢掉。

五、使用速记属性

上面的 margin 可以写成:

.heading {    margin: 1em 0;}

padding、border、background 同样适用。

六、减少冗余

两个类只差一两规则时,抽出公共部分当额外类。不要这样:

<style>    
 .warning {        
    width: 100%;        
     height: 50px;       
     background: yellow;        
     border-radius: 5px;    
    }
    .elevated-warning {        
        width: 100%;        
        height: 50px;        
        font-size: 150%;        
        background: yellow;        
        box-shadow: 1px 2px 5px #CCC;        
        border-radius: 5px;    
    }
</style>
<div class="warning">⚠️</div><div class="elevated-warning"></div>

改成:

<style>    .warning {       
    width: 100%;        
    height: 50px;        
    background: yellow;        
    border-radius: 5px;    
    }
    .warning--elevated {        
        font-size: 150%;        
        box-shadow: 1px 2px 5px #CCC;    
    }
</style>
<div class="warning">⚠️</div><div class="warning warning--elevated"></div>

七、避免复杂选择器

复杂选择器有两害:特异性高,以后更难覆盖;浏览器匹配也更慢。

匹配选择器

浏览器从右到左解释选择器,这比反过来快。例如:

.deeply .nested .selector span {    ...}

先匹配所有 span,再过滤 .selector,依此类推。不建议用标签做选择器,因为它会碰上每个该标签。单次可能只有零点几毫秒,但养成降低复杂度是好习惯。

让人也能读懂

机器难解析,人也难。下面这条何时生效?

[type="checkbox"]:checked + [class$="-confirmation"]::after {    ...}

用自定义类加 JS 切换会简单得多:

.confirmation-icon::after {    ...}

真的别无选择时,至少写清注释:

/** * Creates a confirmation icon after a checkbox is selected. * Select all labels ending with a class name of "-confirmation" * that are preceeded by a checked checkbox. * PS.: There's no other way to get around this, don't try to fix it. **/
.checkbox:checked + label[class$="-confirmation"]::after {    ...}

八、不要删除轮廓

最常见错误之一:觉得去掉 :focus 高亮没事,其实让键盘用户找不到焦点。常被写进 reset:

:focus {    outline: none;}

只用键盘导航的人就不知道自己在哪。默认样式不合品牌就做自定义轮廓,但必须有焦点指示。

九、首先使用移动设备

媒体查询请移动优先:先写小屏,再往上加,也叫渐进增强。这样是给大屏加规则,而不是覆盖已有 CSS,最终规则更少。判断方法:查询用 min-width 就走对了。

/* Mobile-first media query, everything above 600px will get the below styles */
@media (min-width: 600px) {    /* your CSS rules */}
/* Non mobile-first media query, everything below 600px will get the below styles */@media (max-width: 600px) {    /* your CSS rules */}

十、压缩

压缩捆绑文件:去掉注释和空白。服务器端也要开压缩。还可以混淆类名进一步减小 CSS 和标记。

  • Webpack:css-loader
  • Gulp:gulp-minify-cssnames
  • 没有现成包就自己做一套实现

这 10 步能让 CSS 更轻、更好维护、更好扩展。预定义调色板和版式规则也会让设计更一致、样式更可复用。原文

一句话总结:大项目里 CSS 要靠方法(BEM/ITCSS)和工程化(预处理器、覆盖率、压缩)管住体积与特异性,而不是堆选择器。

转载请注明来源:改善CSS的10种最佳做法
本文链接地址:https://ai.zhousir.top/?p=2949
回复 取消