【推荐收藏】10 个最佳实践来让你的CSS代码更加优雅

2021-07-06 14:36:05 浏览数 (1)

前言

❝原文地址: https://medium.com/better-programming/10-best-practices-for-improving-your-css-84c69aac66e 作者:Ferenc Almasi ❞

正文从这里开始~

1. 你真的需要框架吗?

首先,决定是否真的需要使用 CSS 框架。现在,有许多替代轻量级健壮(robust)框架的方法。通常,你不需要使用框架中的所有选择器,所以你的包中会包含死代码(dead code)。

如果你只对按钮使用样式,可以将它们加入到你的 CSS 文件,并去掉其余的样式。另外,你可以通过使用 DevTools 的 coverage 标识未使用的 CSS 规则。

可以在 Chrome 控制面板中搜索 Coverage 来打开它。你可以通过快捷键 Ctrl Shift P 来打开 Chrome 控制面板。打开后,通过点击重新加载(reload)Icon 开始记录。所有表现为红色,则代表未使用。

从上面的例子可以看出,表示有 98% 的 CSS 是未使用的。需要注意的是,事实并非如此,一些 CSS 样式只有在用户在网页上产生交互后才会被应用。移动设备未使用的样式也会标为为使用的字节。所以,在你移除所有这些之前,请你确认在没有任何地方使用它。

2. 推荐使用的 CSS 方法

考虑在你的项目中使用 CSS 方法。CSS 方法用于在 CSS 文件中建立一致性。它们有助于扩展和维护你的项目。下面是一些我推荐的流行的 CSS 方法。

2.1 BEM

BEM ——Block、Element、Modifier ——是最流行的 CSS 方法之一。它是以一个命名约定的集合,你可以用它轻松地构建可复用的组件。命名约定遵循以下模式:

代码语言:javascript复制
.block { ... }
.block__element { ... }
.block--modifier { ... }
  • .block: Block 代表组件。它们是独立的实体,本身就有意义。
  • .block_element: 它们是 .block 的一部分。它们没有独立的意义,必须绑定到块(block)上。
  • .block--modifier: 它们被用作块或元素上的标志。我们使用它们来改变元素的外观、行为或状态。例如,使用 hidden 标志,我们可以称它为 .block-hidden

2.2 ITCSS

倒三角 CSS 通过在不同的层引入不同的特性来帮你更好地组织你的文件。并且,你越深入,它也将变得越具体。

2.3 OOCSS

Object-oriented CSS, 简称 OOCSS,它有两个主要行为准则。这在实践中意味着什么?

代码语言:javascript复制
/* 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;
}
2.3.1 分开结构和皮肤

这意味着你需要将视觉效果和结构代码分开定义。这在实践中意味着什么?

代码语言:javascript复制
/* 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;
}
2.3.2 分开容器和内容

这意味着你不需要任何元素依赖于它的位置。相同的元素应该看起来相同,而不是它们在页面的哪个地方。

代码语言:javascript复制
/* Instead */
.main span.breadcumb { ... }

/* Do */
.breadcrumb { ... }

3. 安装 Pre-Processor

安装预处理器会让你在多个方面受益。预处理器是一个可以让你使用在 CSS 中不存在的先进特性的工具。这些可以是循环的变量或函数。

现今,有很多预处理器。最著名的三种可能还是 Sass、Less 和 Stylus。

所以,预处理器是如何帮助你的?

3.1 更好地组织你的样式

预处理器可以帮你更好地组织样式。它们能把你的文件变成更小的、可复用的片段。文件间可以互相导入,或者稍后单独导入你的应用。

代码语言:javascript复制
// Import different modules into one SCSS file
@import 'settings';
@import 'tools';
@import 'generic';
@import 'elements';
@import 'objects';
@import 'components';
@import 'trumps';

3.2 嵌套你的选择器

另一种增加可读性的好方法如果嵌套你的选择器。这是 CSS 缺少的一个简单、强大的功能。

代码语言:javascript复制

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

层级结构使我们更容易看到不同的元素是如何联系在一起的。

3.3 自动为规则添加厂商前缀

一些非标准的或试验性的特性在 CSS 中需要添加前缀。不同的浏览器会使用不同的前缀,例如:

  • webkit-: 基于 WebKit 的浏览器,例如 Chrome、Safari 或者新版本的 Opera。
  • -moz-: Firefox 火狐。
  • -o-: 旧版本的 Opera。
  • -ms-: IE 和 Edge。

为了支持所有主流浏览器,我们需要多次定义某些属性:

代码语言:javascript复制
.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 来解决这个问题,即可以代替硬编码(hard-code)指的函数。

代码语言:javascript复制
@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();
}

而不是一遍又一遍地写相同的代码,你只需要在需要它们的地方写入这个 minxin

3.4 使用 post-processors

一个更好的选择是 post-processor。一旦 pre-processor 生成 CSS 后,post-processor 可以运行额外的优化步骤。最流行的 post-processors 之一是 PostCss

你可以使用 PostCss 来自动为你的 CSS 打上前缀,所以你不用担心遗漏主流浏览器。它们使用 Can I use 中的值,所以总是最新的。

另外一个很好的 post-processor 是 autoprefixer。有了 autoprefixer,当你想要支持最后四个版本时,你就不用在 CSS 文件中写如何厂商前缀了!

代码语言:javascript复制
const autoprefixer = require('autoprefixer')({
    browsers: [
 'last 4 versions',
 'not ie < 9'
    ]
});

3.5 使用配置文件进行一致的设计

作为 minxin 的一部分,你还可以选择使用变量,与 linter 结合使用,你可以强制执行设计规则。

代码语言:javascript复制
// Font definitions
$font-12: 12px;
$font-21: 21px;

// Color definitions
$color-white: #FAFAFA;
$color-black: #212121;

4. 使用标记而不是 CSS

现在,让我们来看看现实中的 CSS。这经常会被忽视。通常,你可以通过简单地使用正确的 HTML 元素来减少你的 CSS 包的大小。假设你有一个标题,其中包含以下规则:

代码语言:javascript复制
span.heading {
    display: block;
    font-size: 1.2em;
    margin-top: 1em;
    margin-bottom: 1em; 
}

你使用 span 元素作为标题。你可以重写默认的显示,间距或字体样式。这可以通过使用 h1h2 或者 h3 来避免。默认情况下,它们具有你试图使用其他元素实现的样式,你可以直接摆脱这四个不必要的规则。

5. 使用速记(shorthand)属性

为了更进一步地减少 CSS 规则的数量,请始终尝试使用速记属性。对于上面的例子,我们可以这样:

代码语言:javascript复制
.heading {
    margin: 1em 0;
}

其他属性(如 paddingborders 或者 background)也是如此。

6. 减少冗余(Redundancy)

这和前一点(速记属性)是一致的。有时,我们很难发现冗余 CSS 规则,尤其是在两个选择器的重复规则顺序不一致的时候。但是,如果你的类选择器只是一个或两个规则不同,最好将这些规则提取出来,作为一个额外的类选择器来使用,而不是这样:

代码语言:javascript复制
<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>

尝试使用类似的方法:

代码语言:javascript复制
<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>

7. 避免复杂的选择器

使用复杂的选择器有两个主要的问题。首先,你增加的特性不仅使得后期很难去重写存在的规则,而且增加了浏览器去匹配选择器的时间。

7.1 匹配选择器

代码语言:javascript复制
.deeply .nested .selector span {
    ...
}

浏览器将会先从 span 开始。这将会匹配所有 span 标签,然后接着去找下一个。它将会过滤掉 .selector 类里面的 span,以此类推。

7.2 理解选择器

这不仅很难让机器去解析(parse),而且也很难让人去理解。以下面这个为例:

代码语言:javascript复制
[type="checkbox"]:checked   [class$="-confirmation"]::after {
    ...
}

你认为上面这个规则会在什么时候应用?这可以通过创建一个自定义类选择器以及使用 JavaScript 实现切换来简化它。

代码语言:javascript复制
.confirmation-icon::after {
    ...
}

现在它看起来舒服多了。如果你仍然觉得需要一个过于复杂的选择器,并且你认为没有其他选择。请在上面写上注释来解释你的方案。

代码语言:javascript复制
/**
 * 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 {
    ...
}

8. 不要移除轮廓线(outline)

这是开发者在写 CSS 的时候最常见的错误之一。虽然,你可能会认为移除轮廓线造成的 highlight 不会有问题,但是实际上,你将使得网站无法访问。通常的做法是将这个规则作为重置添加到你的 CSS 中。

代码语言:javascript复制
:focus {
    outline: none;
}

然而,通过这种方式,只使用键盘导航的用户将不知道他们正在关注你的网站。

如果默认的样式看起来不适合你的品牌,你可以自定义轮廓线。你只需要确保在聚焦元素时有某些提示。

9. 将移动端作为首选

当你需要处理媒体查询(media queries)时,一定要先考虑移动端。将移动端作为首选意味着你首先从移动设备写 CSS 和小屏幕的方法开始。这也被称为渐进式增强(progressive enhancement)。

这确保你可以添加更多额外的规则来满足大屏幕设备的需求,而不是重写现有的 CSS 规则。这可以减少你最终使用的规则数。

你怎么知道你的媒体是不是先写的移动端?如果你的媒体查询使用了 min-width,则说明你是正确的。

代码语言:javascript复制
/* 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 */
}

10. 压缩

最后,压缩你的包来减少它的大小。压缩会删除注释和空白,这样你的包只需要较少的带宽来获取。

如果你还没启用,请在服务器端启用压缩。

另一种更进一步地减少你的 CSS 的大小的好方法是混淆类选择器名。

要实现这一点,你可以根据项目设置提供两个选项:

  • 「Webpack:」 对于 Webpack,你可以使用 css-loader module。
  • 「Gulp:」 对于 Gulp,你可以使用 gulp-minify-cssnames 插件。
  • 「Create your own:」 如果你的项目设置还没有专门的包(package),我有一个教程向你展示了如何创建自己的实现。

0 人点赞