使用这 5 个原则改进你的 CSS
编写 CSS 非常简单直接,那么为什么编写 CSS 时需要原则和最佳实践呢?
随着项目范围的扩大和项目人员数量的增加,问题变得越来越明显,并可能导致严重的后续问题。修复问题可能会变得更加困难,例如重复代码、复杂的覆盖链和使用!important
、剩余/未使用的代码(已删除的元素或功能)、难以阅读的代码等等。
专业的 CSS 编写水平将使 CSS 代码更易于维护、扩展、理解和简洁。我们将探讨五个简单有效的原则,助您提升 CSS 水平。
命名原则
“计算机科学中只有两件难事:缓存失效和命名。”——Phil Karlton
正确命名和构建 CSS 选择器是提升 CSS 可读性、结构化和简洁性的第一步。在命名约定中建立规则和约束,可以使您的代码标准化、健壮性更强,也更易于理解。
这就是为什么BEM(块元素修饰符)、SMACSS(CSS 的可扩展和模块化架构)和OOCSS(面向对象的 CSS)等概念在许多前端开发人员中流行的原因。
低特异性原则
覆盖 CSS 属性非常有用,但在更复杂的项目中,事情很快就会失控。覆盖链可能会变得非常长且复杂,你可能不得不使用它来!important
解决优先级问题,并且在调试或添加新功能时很容易迷失方向。
/* Low-specificity selector */
.card {}
/* High-specificity selectors */
.card .title {}
.blog-list .card img {}
.blog-list .card.featured .title {}
#js-blog-list .blog-list .card img {}
浏览器和特异性
遵循低特异性原则的好处之一是性能。浏览器从右到左解析 CSS 。
我们来看下面的例子:
.blog-list .card img {}
浏览器解析选择器如下:
- 查找
img
页面上的所有元素 - 保留属于
.card
该类的后代的选定元素 - 保留属于
.blog-list
该类的后代的选定元素
您可以看到高特异性选择器如何影响性能,特别是当我们需要全局选择通用元素(如、、div
等)时。img
li
使用相同级别的特异性
通过将低特异性 CSS 类选择器与 BEM 或上一节中提到的其他命名原则之一结合使用,我们可以创建高性能、灵活且易于理解的代码。
为什么要使用 CSS 类?我们希望保持相同的优先级,保持灵活性,并能够定位多个元素。元素选择器和 id 选择器无法提供我们所需的灵活性。
让我们使用 BEM 重写前面的示例并保持较低的特异性。
/* Low-specificity selector */
.card {}
/* Fixed high-specificity selectors */
.card__title {}
.blogList__image {}
.blogList__title--featured {}
.blogList__img--special {}
您可以看到这些选择器非常简单易懂,并且可以根据需要轻松覆盖和扩展。通过保持它们的低级(单个类),我们保证了最佳的性能和灵活性。
DRY 原则
DRY(不要重复自己)原则也适用于 CSS。CSS 中的重复代码会导致代码臃肿、不必要的覆盖、降低可维护性等。这个问题可以通过合理构建代码结构并编写高质量的文档来解决。
Storybook是一款出色的免费工具,可让您创建可用前端组件的概述并编写高质量的文档。
/* Without DRY Princple */
.warningStatus {
padding: 0.5rem;
font-weight: bold;
color: #eba834;
}
.errorStatus {
padding: 0.5rem;
font-weight: bold;
color: #eb3d34;
}
.form-errorStatus {
padding: 0.5rem 0 0 0;
font-weight: bold;
color: #eb3d34;
}
让我们重构代码,使其遵循 DRY 原则。
/* With DRY Principle */
.status {
padding: 0.5rem;
font-weight: bold;
}
.status--warning {
color: #eba834;
}
.status--error {
color: #eb3d34;
}
.form__status {
padding: 0.5rem 0 0 0;
}
单一职责原则
通过在 CSS 中使用单一职责原则,我们可以确保 CSS 类易于扩展和覆盖。让我们看下面的例子。
.button {
padding: 1rem 2rem;
font-size: 2rem;
border-radius: 0.2rem;
background-color: #eb4934;
color: #fff;
font-weight: bold;
}
.button--secondary {
border-radius: 0;
font-size: 1rem;
background-color: #888;
}
我们可以看到,如果我们想要扩展.button
类.button--secondary
,我们需要做大量的覆盖来实现我们需要的,而我们只想应用不同的背景颜色并保留默认样式。
问题是我们的.button
班级有多个角色:
- 设置布局(
padding
) - 设置排版(
font-size
,font-weight
) - 设置演示(
color
,,background-color
)border-radius
这使得我们的 CSS 类很难扩展,也很难与其他 CSS 类组合。考虑到这一点,让我们使用 BEM 和 OOCSS 来改进我们的 CSS。
/* Shared styles */
.button {
padding: 1rem 2rem;
font-weight: bold;
color: #fff;
}
/* Style extensions */
.button--radialBorder {
border-radius: 0.2rem;
}
.button--large {
font-size: 2rem;
}
.button--primary{
background-color: #eb4934;
}
.button--secondary {
background-color: #888;
}
我们将样式拆分button
成几个类,用于扩展基button
类。我们可以选择性地应用修饰符,并在设计变更或添加新元素时添加新的修饰符。
开/闭原则
软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭。
我们已经在前面的例子中运用了开放/封闭原则。所有新功能和选项都需要通过扩展来添加。让我们来看看这个例子。
.card {
padding: 1rem;
}
.blog-list .card {
padding: 0.5em 1rem;
}
该.blog-list .card
选择器有几个潜在问题:
.card
某些样式仅当元素是元素的子元素时才可应用.blog-list
。.card
如果将样式放置在元素内部,则会强制应用于元素.blog-list
,这可能会产生意外的结果和不必要的覆盖。
让我们重写前面的例子:
.card {
padding: 1rem;
}
.blogList__card {
padding: 0.5em 1rem;
}
我们通过使用单个类选择器解决了这个问题。使用此选择器,我们可以避免意外效果,并且不会出现条件嵌套样式。
结论
我们已经看到,通过应用这几个简单的原则,我们显著改善了编写 CSS 的方式:
- 通过使用BEM、OCSS等规范化命名和结构,提高可读性。
- 通过使用低特异性选择器来改进性能和结构。
- 使用 DRY 原则减少代码膨胀并提高代码质量
- 通过使用开放/封闭原则实现灵活性和可维护性
- ETC。
这些文章都是咖啡带来的灵感。所以,如果你喜欢我的文章,觉得它有用,不妨请我喝杯咖啡!我会非常感激的。
感谢您花时间阅读这篇文章。如果您觉得它有用,请点赞 ❤️ 或 🦄,分享并评论。
文章来源:https://dev.to/prototyp/improve-your-css-with-these-5-principles-35jd