单步设计更好的 CSS

单步设计更好的 CSS

原文:https://medium.com/hackernoon/designing-better-css-with-a-single-step-e28eaeb367dc

SASS 和 Less 这样的 CSS 预处理程序给了我们一整套新语法,旨在减少我们的样式表中计算机可复制的膨胀。

我们有颜色和尺寸的变量,我们有网格系统的循环和复杂的印刷模板,我们有组件语法封装的选择器嵌套。

其中之一可能是鼓励你设计糟糕的系统。

CSS 是一种有趣的语言,因为开发者在微观层面上的选择通常是 1。只有一种方法可以让 div 向左浮动,也只有一种方法可以让文本颜色变成令人惊叹的洋红色(背景为酸橙绿色)。

因此,你应该在宏观层面上引导你的脑力,也就是设计坚实的设计系统。我上面提到的有问题的新语法潜移默化地阻碍了选择器嵌套,你应该抛弃它。我说是因为它看起来太干净了。这看起来是正确的做法。

首先,让我们看看我所说的选择器嵌套是什么意思:

.comment { .comment__header { // Semantic nesting
    color: black;
  } &__body { // Syntactic nesting }}

上面有两种嵌套。一个比另一个差,但他们都有问题。

语义嵌套

语义嵌套改变了生成的 CSS 的含义。在上面的示例中,第二个选择器声明:

“Select all elements with class comment_header that are children of an element with class comment”

乍一看,这似乎相当合理,但它也有一些负面影响:

它不必要地提高了选择器的特异性

在 CSS 中嵌套选择器增加了所谓的特异性。这意味着它将覆盖任何具有较低特异性值的选择器。(如果两个选择器具有相同的特异性,则最后声明的优先于最后声明的。)

选择器特异性需要一直被哈里·罗伯茨称之为“管理良好”。这大体上意味着我们的特异性应该尽可能保持一致,只有在需要覆盖之前的选择器时才上升。这使我们的 CSS 可预测,并避免!重要的是-见鬼。在这里,我们增加了选择器的特异性,但并没有真正的好处。的确,我们获得了封装,但是一个好的命名约定(例如 BEM)将提供这种封装。

例如,假设我想使用下面的实用程序类使一个特定的注释有一个突出显示的标题:

.highlight {
   color: red;
   font-weight: 600;
}

如果我将高亮类应用于 commentheader 元素,颜色将保持为黑色,因为 commentheader 类具有更高的特异性。

或者,我可以创建一个新的类,具有与头相同的特性,如下所示:

.comment .comment__header--is-highlighted {
   color: red;
   font-weight: 600;
}

这肯定会解决手头的问题,但它很好地把我带到了我的下一点。

它阻止你从可组合系统的角度去思考

嵌套选择器通过将 CSS 绑定到标记上给你一种虚幻的封装感。它让你把你开始的任何组件都看作是“顶层”组件,在那里其他所有的组件都和它的父组件有上下文联系,而实际上通常不是这样。

回到上面的 CSS 例子,你真的认为注释头足够独特以至于需要它们自己的类吗,或者你认为我们可以从我们工具包中的其他设计元素中构建它们吗?

实际上,注释头可能看起来和应用程序中的其他类型的头非常相似,但是因为你嵌套了选择器,几乎不加思考地,你就把上下文的包袱附加到了组件上,而组件并不存在。

如果你将单一责任原则应用到你的 CSS 选择器中,你会发现它们变得更加可组合,并且从无用的上下文中移除这些选择器使得概念化变得更加容易。

最后,相关的一点,我会让你回到你的吞咽和咕哝:

它隐藏了选择器中规则的意图

通常,通过将 CSS 与标记紧密地联系在一起,我们会对所选择的元素做出一些我们并不真正想要表达的声明。请允许我举一个无聊的例子:

.whitehouse {
   .president {
      color: orange;
   }
}

这个 CSS 明确声明,当且仅当总统在白宫时,他才是橙色的。事实上,总统在很多不同的场合都是橙色的,所以我们的 CSS 是在撒谎。

好的,那么什么时候可以语义嵌套选择器呢?从来没有?

只有当选择器是一个组合系统的一部分时,它们才应该是嵌套的,覆盖先前声明的功能,并且具有清晰和有限的意图。

.button {
   background-color: green;
   color: magenta;
   padding: 8px 12px;
   border-radius: 5px;
}.button-bar {
    .button {
        padding: 4px 8px;
    }
}

这里我们有两种不同成分的组合。按钮组件和按钮栏组件。这个按钮是完全独立的,可以在许多不同的环境中使用,但是当它在按钮栏中时,需要减少填充以使其非常合适。

在这里,我们有一个清晰的上下文变化,一个覆盖以前样式的需求和一个清晰定义的嵌套规则的意图。

句法嵌套

上面,我演示了语义和语法嵌套。语义嵌套改变了 css 的含义,对于非嵌套的 CSS 选择器来说,语法嵌套只是纯粹的语法糖。

.class {
   &--active { }
}// Compiles to:.class {}.class--active {}

正如你所看到的,这产生了两个具有相同特性的类,但是我上面提到的所有“软”问题仍然适用于你概念化组件的方式。

此外,它还会使您的代码不可搜索,如果您对这类事情感兴趣的话,这可能会成为一种阻力。

我见过最差的选择者?请看:

.home #content main .entry-content ol li p span, .page-template-page-home #content main .entry-content ol li p span, .contact-page #content main .form ul li p a span 

恐怖。

如果你喜欢这篇文章,请记得点击💚下面的符号,以确保更多的人阅读它!

Steven Poulton 是一名居住在英国曼彻斯特的 web 开发人员和技术架构师。在业余时间,他喜欢制作独立音乐,制作独立游戏,和他的独立猫玩耍。


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除