我们每周(大约)都会发布 时事通讯,其中包含关于网页设计和开发的最佳链接、提示和技巧。 最后,我们通常会写一些我们在本周学到的东西。 这可能与 CSS 或前端开发完全无关,但分享起来很有趣。 这是一个来自时事通讯的此类内容段落的示例,其中我漫谈代码质量,并深入探讨我认为在 CSS 语言中应被视为代码异味的内容。
许多开发人员抱怨 CSS。 级联! 奇怪的属性名称! 垂直对齐! 这门语言有很多奇怪的地方,特别是如果您更熟悉 JavaScript 或 Ruby 等编程语言。
但是,我认为 CSS 语言的真正问题在于它 简单但不易。 我的意思是,学习如何编写 CSS 不需要太多时间,但编写“好的”CSS 需要付出非凡的努力。 在一两周内,您可能就能记住所有属性和值,并在浏览器中创建真正漂亮的网页设计,无需任何插件或依赖项,从而让所有朋友都惊叹不已。 但这不是我所说的“好的 CSS”。
为了定义什么是好的 CSS,我最近一直在思考如何首先识别什么是坏的 CSS。 在编程的其他领域,开发人员在描述糟糕代码时倾向于谈论代码异味;程序中的提示表明,嘿,也许您编写的这个东西不是一个好主意。 它可能是一些简单的东西,比如命名约定或一段特别脆弱的代码。
类似地,下面是我自己列出的 代码异味,我认为这些代码异味将有助于我们识别不良设计和 CSS。 请注意,这些要点与我在构建复杂应用程序中的大型设计系统方面的经验有关,因此请谨慎参考。
代码异味 #1:您编写 CSS 的事实
一个大型团队可能已经有一套工具和系统来创建按钮或样式以移动布局中的元素,因此您即将编写 CSS 的简单事实可能是一个坏主意。 如果您只是要为特定的极端情况编写自定义 CSS,那么请停止! 您可能需要执行以下操作之一
- 了解当前系统的运作方式以及它为何具有这些约束条件,并坚持这些约束条件
- 重新思考 CSS 的底层基础架构
我认为这种方法在这里得到了完美的描述
关于“快速修复”的虚假速度。 pic.twitter.com/91jauLyEJ3
— Pete Lacey (@chopeh) 2017年11月2日
代码异味 #2:文件名和命名约定
假设您需要为您的应用程序创建一个支持页面。 您可能首先要做的是创建一个名为 `support.scss` 的 CSS 文件,并开始编写如下代码
.support {
background-color: #efefef;
max-width: 600px;
border: 2px solid #bbb;
}
因此,这里的问题不一定是样式本身,而是“支持页面”的概念本身。 当我们编写 CSS 时,我们需要以更大的抽象思维来思考——我们需要以模板或组件来思考,而不是用户需要在页面上看到的特定内容。 通过这种方式,我们可以一遍又一遍地在每个页面上重复使用诸如“卡片”之类的元素,包括支持页面上我们需要的那一个实例
.card {
background-color: #efefef;
max-width: 600px;
border: 2px solid #bbb;
}
这已经好多了!(我的下一个问题将是什么是卡片,卡片内部可以包含哪些内容,什么时候不能使用卡片等等——这些问题可能会挑战设计并让您保持专注。)
代码异味 #3:设置 HTML 元素的样式
以我的经验,设置 HTML 元素(如 section 或 paragraph 标签)的样式几乎总是意味着我们正在编写一个 hack。 只有在以下一种情况下才适合直接设置 HTML 元素的样式
section { display: block; }
figure { margin-bottom: 20px; }
那就是在应用程序的全局所谓的 “重置样式”中。 否则,我们将使我们的代码库支离破碎,难以调试,因为我们不知道这些样式是出于特定目的的 hack,还是定义了该 HTML 元素的默认值。
代码异味 #4:缩进代码
缩进 Sass 代码,使子组件位于父元素内,几乎总是代码异味,并且是该设计需要重构的明确标志。 以下是一个示例
.card {
display: flex;
.header {
font-size: 21px;
}
}
在这个例子中,我们是在说您只能在 .card
内使用 .header
类吗? 或者我们是否在代码库的其他某个深处覆盖了另一个 CSS 块? 我们甚至不得不提出这样的问题,这表明了这里最大的问题:我们现在在代码库中播下了怀疑的种子。 为了真正理解这段代码是如何工作的,我必须了解其他代码片段。 而且,如果我必须问关于这段代码为何存在或如何工作的问题,那么它可能要么过于复杂,要么对未来来说难以维护。
这导致了第五个代码异味……
代码异味 #5:覆盖 CSS
在理想情况下,我们有一个重置 CSS 文件,它为我们所有的默认元素设置样式,然后我们为应用程序中的每个按钮、表单输入和组件创建单独的 CSS 文件。 我们的代码最多应该被级联覆盖一次。 首先,这使得我们的整体代码更具可预测性,其次,使我们的组件代码(如 button.scss
)超级易读。 我们现在知道,如果我们需要修复某些东西,我们可以打开一个文件,这些更改将在整个应用程序中一举复制。 在 CSS 中,可预测性是一切。
在同一个 CSS 理想国中,我们可能会通过类似 CSS 模块 的东西来阻止覆盖某些类名。 这样我们就不会意外出错。
代码异味 #6:CSS 文件包含超过 50 行代码
您编写的 CSS 越多,代码库就越复杂和脆弱。 因此,每当我的 CSS 代码达到大约 50 行时,我都会重新思考我的设计,并问自己几个问题。 从以下问题开始和结束:“这是否是一个单独的组件,或者我们可以将其分解成独立工作的单独部分?”
这是一个既困难又耗时的过程,需要不断练习,但它会导致一个可靠的代码库,并训练您编写真正优秀的 CSS。
总结
我想我现在还有另一个问题,但这次是问您的:您认为 CSS 中的代码异味是什么? 什么是糟糕的 CSS? 什么是真正好的 CSS? 确保在下面添加评论!
代码异味 #1:您编写 CSS 的事实
真的吗? 这正是我每天工作 9 到 5,一周 5 天所做的事情。 只有 CSS。 在一个其他人做 Typescript、Java、管理工作的团队中……多亏了他们让我专门负责所有 CSS 工作……
其他代码异味:您确定您作为 CSS 开发人员的经验足够做出这些陈述吗? 我不同意任何一点……
超过 50 行 CSS 是代码异味……真的吗? 37000 行 CSS,那是代码异味(顺便说一下,Angular JS 中大约有这么多行 CSS)。
对于 #1,是的,整个观点是拥有一个模式库是一种常见做法,即使这意味着使用其他人的库,如 Material、Bootstrap、Foundation 等。
这条规则并没有说它总是正确的,而且我不确定它是否能很好地解释自身。一个经过深思熟虑的系统不应该需要编写很多 CSS,除非你正在添加新功能,在这种情况下,你应该没问题。
至于这里列出的其余规则,我想大多数规则也都是有效的,尽管它们也存在缺乏更好示例的问题。我认为关于 50 行的规则可能有点多,并且可能根据构建的系统类型而有所不同。超过 200 行后,我可能会开始好奇为什么一个文件中会有如此多的样式。
(只是因为我无法回复 Luke P.,这是写给他的)
所以你基本上是在说我们都应该使用 Materialize、MDL、Bootstrap、Foundation 或其他任何一千个框架来完成工作,如果我们必须编写额外的 CSS,那么我们基本上就是在做错事,除非我们正在添加额外的功能!?真的!?
那么,根据你的说法,所有网站都应该看起来一样,codrops、csstricks 或任何其他网站之间都没有区别,因为我们应该使用任何现成的框架而无需自定义,对吧?
同意。如果你使用框架没有任何额外的样式覆盖或自定义,那么你正在创建一个无聊的网站。我不确定作者想用这个观点表达什么。
至于第 2 点,我已经听说了很多年了。我知道在理想情况下,CSS 将被完全抽象化,并且我将为每个事物都有一个可重用的类。但是,在我的职业生涯中,我从未遇到过因某个页面元素使用
.support
这样的类而产生的问题。如果该样式需要扩展到未来的区域,则可以在实际需要时稍后重构代码。大多数这些技巧都只是在 CSS 上花费太多时间并使整个过程比需要更复杂的方法。
我不同意这里对 Luke 的回复。我认为本文中的大多数观点都是合理的。如果你正在处理一个新项目或新功能,显然你会编写 CSS。如果不是,而你正在更改现有功能或修复错误,那么也许你不需要更改任何 CSS(也许)。如果你使用 UI 套件或设计系统,那么这通常可以作为开发依赖项,并且很少更新。如果你没有使用,并且你的 CSS 与你的应用程序组件紧密耦合,那么你可能会在更改任何其他代码时更改 CSS。由于设计系统如今非常流行,因此本文中提到了这一点。
至于第 2 点,我完全同意。如果你想为支持页面的容器创建一个名为
.support
的类,然后使用此类来设置支持页面上元素的样式,那么我希望你不要在我的项目上工作。我认为你对样式指南的评论有点脱离上下文。我从未说过你应该将 Bootstrap 拖放到项目中。使用这些框架,甚至是我们自己编写的框架,也很容易偏离 DRY 并为本来可以用辅助类更好地服务的事物创建一次性实例。在开始编写解决方案之前,你应该确保不存在已经存在的模式或类可以满足你的需求,或者它遵循模式库的一组标准。
如果你使用已经建立的模式库,是的,你仍然会编写 CSS,但关键是它减少了你需要编写 CSS 的实例数量,这就是第一条规则的全部意义所在,质疑你正在做的事情是否已经存在于你面前的工具中。
我目前正在开发几个 React 应用程序,它们都使用共享组件,在整个生态系统中保持品牌一致性至关重要。我们的组件有很多预定义的属性,例如字体大小、网格系统布局以及许多其他属性,以保持高度一致性。因此,我很少编写 CSS,而当我编写时,则是针对存在一次性情况或可能需要新组件的非常具体的实例。
正是在这些情况下,我不得不停下来思考为什么我正在编写 CSS。设计/UX 是否忘记了我们已经有一种使用模式的既定方法?其他人是否已在其他地方创建了我可以重用的样式?大多数这些问题通过消除细微的不一致性来帮助我们改进设计。其他时候,我发现其他人已经为我可以在组件中重用的样式/大小创建了一个新规则。
无论何时你在处理大型代码库,以及其他几个开发人员,你都必须练习一定程度的克制,否则你的代码库将很快变得难以控制。我经常在内联菜单、按钮和网格内项目对齐等方面看到这种情况。这些元素的大多数样式都可以通过几个基本类和修饰符类轻松解决。一个好的 UI 将具有高度的一致性,几乎不需要任何一次性调整。
至于说应用这些规则需要花费很多时间,当然需要。然而,与重构已失控的代码库所花费的精力相比,这段时间微不足道。它还会对整体性能产生影响,无论额外的尺寸重量有多小,它仍然很重要。
这条规则是否意味着你永远不应该编写任何 CSS?绝对不是,它只是一个保障措施,可以让你更高效并减少重构时间。
说真的,这里谁曾经遇到过
.support
这样的类带来的麻烦?你是否真的遇到过需要将你的.support
样式移植到另一个页面,并且你无法在一小时内或更短时间内重构代码的情况?是否真的值得花费额外的时间来使某些东西 100% 可扩展且非特定化,以防万一以后需要它,或者现在做你需要做的事情,并在需要时考虑扩展它更有意义?请记住,我并不是说像
.support
这样超级特定的类是处理事情的完美方式。它肯定不是。但你们说得好像仅仅以务实有效的方式完成任务是完全不可接受的。人们对“代码异味”变得非常挑剔,忽略了仅仅 10 年前,CSS 框架几乎不存在,并且使用像.support
这样的类进行样式设置将是标准做法的事实。当然,那是过去,现在是现在。但归根结底,我保证客户不会关心你的代码是否可以扩展到可能存在也可能不存在的未来区域。嗨,Robin!好文章,观点也非常好,尽管我不确定你如何编写一个低于你约 50 行限制的 button.scss 文件。你能否提供一个你管理过 css 部分的仓库链接?我很想了解更多关于最佳实践的信息 :)
第 4 点只是一种定义组件的方法。除了标题类命名过于宽泛之外,没有问题。
我听到的是关于重置和预处理器的论点,以及关于 50 行 CSS 的复杂性的警告(根据一些编码标准,大约相当于 12 个声明)。
我想知道,这是否,所有这些观点,都是为了质量和可管理性?我们如何向那些关注性能的人解释,当网站——几乎所有网站——都能在没有重置的情况下正常工作时,为什么需要重置 [1]?或者向那些运营大型网站的人解释,他们的 50,000 个声明 [2] 应该分成至少 1,000 个组件?
我支持并鼓励指出 CSS 编码问题的想法——但我们需要密切注意补救措施不要比最初的问题更糟糕,并且我们不要将功能误认为是错误。例如,设置元素样式本身并不意味着“代码异味”。这几乎就像说一辆汽车坏了因为它会动——如果司机不知道如何驾驶,这似乎非常正确,但我们都知道事实并非如此。
[1] https://meiert.com/en/blog/stop-using-resets/
[2] https://meiert.com/en/blog/70-percent-css-repetition/
感谢你抽出时间分享你对 CSS 中代码异味的理解。我不想花时间分享我对你的异味的想法,除了第 1 点。从文章开头就说我们不应该编写 CSS 是消极的。我们为什么不应该编写 CSS?你是说我们应该依靠框架来做这件事吗?请详细解释为什么你认为我们不应该编写 CSS。
嗨,Rob,我认为作者并非字面意义上说编写 CSS 不是一个好主意。我认为这只是吸引我们注意并帮助我们在开始编码之前进行思考的一种方式。在处理大型应用程序时,很多时候,你需要做的事情之前已经做过,并且可以利用这些经验。这可能是以辅助类或已经编写的组件的形式。我对这一点的理解是,我们应该确保我们了解应用程序的编写方式以及它遵循的约定,以便我们能够以最佳方式做出贡献并帮助保持其可维护性。
感谢你撰写这篇文章,Robin。
尽管许多代码异味似乎都存在争议,但它帮助像我这样的初级开发人员了解了应该注意哪些问题——而且我确实在这里认识到了一些不良行为,我可以在这个早期阶段消除这些不良行为。
很棒的阅读!
那么第 4 点的解决方案是什么?标题应该命名为 .card-header 吗?
是的,我认为是这样。
使用 OOCSS 方法,我会将类链接起来,例如 class=”header card-header”,以便继承默认的标题样式,然后进行自定义覆盖。
这也意味着你不需要嵌套 Sass
我必须同意另一位评论者的说法,即这篇文章及其“代码异味”缺乏清晰度。
#1 – 编写CSS就是设计。如果你已经编写了你的基础(你称之为重置,它不应该包含非重置样式),并且有来自其他项目的组件元素样式适合当前设计,那么除了布局之外,你不需要编写太多新的CSS。但暗示我们必须要么有预先编写的代码来重用,要么使用预先编写的框架是荒谬的。
当你拒绝在没有盒子的时候工作时,你如何跳出框框思考?
#3 – 我再次声明,重置不是基础。你根本不应该在重置中为任何元素设置样式,只删除样式以用于设置基线。也就是说,基础应该仅保留用于那些不更适合放在另一个样式表中、用于特定组件、模式等的样式。
#4 – Sass代码不是CSS。在CSS中,这种“异味”实际上只存在于媒体查询和动画中,在这种情况下,提供的示例非常准确。
#6 – 正如另一位评论者所指出的,在许多情况下,50行CSS基本上是12个声明。如果你将代码分解成非常小的块,比如button.css,那么这可能有效。但是,你不能为单个元素设计模式。一个模式需要不止一个。虽然你*可以*将其分解到这种程度,但你实际上只是创建了一个迷宫般的文件,作为解决方案,它比它试图解决的问题更麻烦。buttons.css(复数)更有意义。而且在大多数情况下,这是设计师理智所能承受的程度。
我感谢这篇文章。尽管我有所保留,但我还是通读了整篇文章。新的方法很有价值,无论它们来自哪里。但是,在阅读之后,我相信这篇文章应该以你的确切观点作为前言。也就是说,你不是CSS设计师,而是一个CSS预处理器设计师,并且你可能在一个成熟的团队中工作,以构建/改进已有的设计,而不是全新的东西。换句话说,这篇文章是针对那些致力于调整设计而不是创建设计的人。 :)
既然我因为你没有这样做而对你有所批评,我还是要说明,我是一个程序员和设计师,自由职业者,也做个人项目(长期、创收的个人项目)。祝你一切顺利!
你一定有一份不错的工作。而我,另一方面,却要为一家财富100强科技公司的网站工作。
#1。当然,有一个库和工具集可以用于处理网站的SCSS。由于我是承包商,所以我无权访问它。(没有承包商被允许访问,但大部分工作都是由承包商完成的。)但我仍然需要修复问题。
#2。同一个网站将所有CSS都放在一个文件中。最初是为了加载时间。现在是因为它太大了,以至于不能失败。如果你尝试使用通用类名,你很可能会覆盖其他一些部分。
#3。过去的开发人员要么使用元素名称,要么没有提供类名。在这两种情况下,我们都只能使用元素名称。(通常作为更长规则的一部分。不,我们通常无法更改预先存在的html来添加类。)
#4。这表明对scss缩进的用途存在误解。
#5。在这一点上,覆盖CSS是完成任何事情的唯一方法。
#6。50行?说真的?也许如果你只有几个页面。如果一个网站有数千个页面呢?每六个月到一年,外观都会更新。但他们不能破坏旧的样式,因为有些页面仍然使用它们。而且他们不能只加载模板所需的CSS,因为CMS在10年前不支持。
总之,当然,如果你正在创建一个新的、小型网站,这些都是合理的指南。但对于一个存在了几十年的网站来说呢?这些都不现实。我们只是在上面涂抹更多的油漆,希望没有人注意到下面隐藏的代码污水坑。
好文章!
看来对第一个代码异味#1:你正在编写CSS可能存在一些误解。我相信这里的关键句子是2. 重新思考CSS的基础架构。并不是说我们不应该将CSS本身作为一种语言来使用。
假设有人需要你在一个你以前从未参与过的项目上提供帮助。他们需要一个输入字段和一个按钮来创建一个新闻稿注册功能。当然,你会说并询问设计文件,然后开始编写html和CSS以匹配设计。这是一个快速修复!
你应该做的是重新思考CSS的基础架构。当前项目是否在其他地方使用了按钮和输入字段?也许有一个现有的联系页面或类似的表单页面,其中这两个元素已经存在。然后,你可以通过重用CSS类名来重用这些部分,并且可能无需编写一行CSS。
ronnidc说得对,我认为你抓住了问题的关键!
这些都是指南,因此显然它们不可能在任何情况下都适用。不过,关于#4,我想说的是,嵌套是封装行为的好方法。如果.header确实因为位于.card内部而表现出不同的行为,那么将其嵌套是合理的。这意味着你将所有card的样式封装在一个文件中。如果你删除了card组件,.card .header类也可以一起删除。
另一种方法是在header组件文件中使用类似.header–in-card的东西,但乍一看很难确切地知道它在做什么以及它在哪里生效。如果你删除了card组件,你是否确信可以删除该类?
之前有人对此发表了评论。我认为这个想法是,你会给元素现有的类,如果需要自定义它,你会添加一个额外的类。像这样
<div class="header header-in-card">
这样,你就可以继承现有的样式,并可以添加或覆盖新类的规则。
#1 只有你不是CSS开发者时才这样?作为CSS开发者,我希望你开发的CSS其他人可以轻松实现而无需编写CSS?仅仅添加和配置bootstrap并不是CSS开发。(前端开发者,做CSS的,为了简单起见,这里就说CSS开发了)
#2 这完全取决于项目。如果你正在为纽约时报编写CSS,是的。如果你正在为一家当地的花店编写,为什么要使用极端的抽象?
#3 也取决于项目,但大多数情况下确实只需要样式类
#4 是代码异味?我认为这是一种最佳实践……
#5 覆盖CSS不好?你是如何做响应式设计的?不过我同意尽量少覆盖
#6 50?你有没有为功能性日期选择器或表单之类的东西设置过样式?或者你是否为每一件小事都创建了500个css文件?
有点困惑为什么这些是代码异味……
这篇文章上有一些乱七八糟的评论。我同意这里的大多数观点。这不是让CSS变得比必要更复杂的方法。这些都是好的、有效的观点。
#1 我是一名CSS开发者,我喜欢在不需要编写CSS的时候。这意味着我之前编写的CSS很好,可以重用。
#2 这非常重要。如果你在我面试过程中进行技术测试,并使用名为support.scss的文件或名为
.support
的类来为支持页面中的组件设置样式,我不会给你这份工作。因为你是在根据内容而不是目的来为UI组件设置样式。#3 对我来说,为元素设置样式只在基础样式(或所谓的“重置”样式)中是可以接受的,正如文章中所说。好的,有效的观点。
#4 这与第5点相关。遵循BEM标准的命名约定要好得多,也更容易维护。
#5 没有必要重复我上面说的话。但这是一个好的、有效的观点。
#6 我认为50行只是一个作者喜欢的数字。但总的来说,这个想法又是一个好的、有效的观点。不要在一个文件中放太多CSS。不难理解,甚至也不难认同。
我之前列了一长串具体的评论,然后删除了评论。我觉得这篇文章最大的缺陷是缺乏背景。如果你正在构建一个小型网站,几乎所有这些都不是代码异味。如果你在一个拥有多个开发人员且代码库广泛的庞大系统中工作,那么这些*可能*是代码异味。
我从中学到的最大问题是,如果你在观点、论点或背景上含糊不清,你可以让任何人同意或不同意你。
此外,我注意到作者偷偷地使用了“应用程序”这个词,这意味着上下文。在应用程序环境中,这些*可能*是代码异味。
但同样,我们大多数开发人员都不得不接受它,尤其是在我们维护一个我们访问权限有限的旧代码库时,或者修复代码异味的成本过高。我认为这在维护模式项目中很常见。
所以,给作者的一点建议,上下文和清晰度,如果作者阐明了自己的观点来源(例如,“大型/中型/小型”网站/应用程序、开发团队规模,甚至是在开源项目中工作还是封闭项目、企业项目还是公益项目等等),这里的大多数批评观点都将变得毫无意义或完全不同。
我认为作者在定义上下文方面做得很好。请参阅文章引言中的这一部分
“同样地,下面是我自己的一份代码异味清单,我认为它将有助于我们识别糟糕的设计和 CSS。请注意,这些要点与我在构建复杂应用程序的大规模设计系统方面的经验相关,因此请谨慎参考。”
要么我疯了,要么这篇文章被重写了。鉴于这里的评论显然缺乏上下文,我倾向于认为它被重写了。
我同意这篇文章现在效果更好。但再次强调,也许是我疯了。
代码异味 #0:你正在使用 normalize 或 reset CSS。
令人难过的是,在过去的十年里,网页技术退化了。
感谢你撰写这篇文章。我已经很久没有读到过我想参与讨论的文章了。我认为这篇文章发人深省,信息和上下文恰到好处。非常喜欢阅读它并与其他读者互动。
我认为值得注意的是,“缩进”与“嵌套”是不同的。我同意包含大量嵌套样式(例如
.content .card .header
)可能会减慢网站速度,而且通常是不必要的。但是,“缩进”可以用于使代码更易读和易于管理。例如,此 scss 可以很好地创建 BEM 样式的 css我实际上建议不要这样做,因为它使得搜索 .card–header 变得更加困难。我更倾向于明确而不是简洁。
是的,James,我想这可能是一个问题。我很少搜索,因为我通常使用提供行号的检查器,所以我没有遇到过这种情况。
同意作者的所有观点。尤其是在阅读了强调规划和真正创建系统重要性的原子设计之后——编写毫无意义的 CSS 非常容易,任何人都可以在一周左右学会,但“能力越大,责任越大”。我现在在一个大型项目中工作,该项目是大型应用程序的一部分,我不得不多次重构我的 CSS,因为“修复修复”变得难以控制。谢谢,Chris!
我绝不是专家,但这是我的看法
#1:你首先编写 CSS 这个事实本身
抱歉,有时我需要进行快速修复才能保住工作。这就是生活。
#2:文件名和命名约定
我选择了目前我能做到的最佳方案。然后我寄希望于最好的结果。它 50% 的时间有效。
#3:设置 HTML 元素的样式
同意。除非我覆盖了别人的 CSS,否则我肯定会这样做。现在阅读 #1 的答案。
#4:缩进代码
什么鬼?. 我真的没有发现有什么问题。
#5:覆盖 CSS
无论我们是否喜欢,它都会继续发生在你身上,发生在我身上,发生在我们所有人身上。这就是生活。
#6:CSS 文件超过 50 行代码
等等,什么?呃……但是…… … 呃…… … 什么什么!
代码异味 #3:设置 HTML 元素的样式
设置按钮元素样式的替代方法是创建一个 .button 类,并在 html 中到处冗余地使用它。
在一个按钮始终是按钮,并且在基本主题上有一些变化的应用程序中,拥有 .button 类毫无意义且很混乱。