新手和经验丰富的开发者最常犯的十大致命 CSS 错误
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
多年来,我看到很多客户公司的工程师在使用层叠样式表 (CSS) 时犯同样的常见错误。即使是那些才华横溢、经验丰富的工程师,尽管他们在广泛的技术领域拥有专业知识,也会犯这些错误,因为他们没有像在大学学习算法那样,投入时间学习 CSS。
我认为CSS之所以被认为难以理解和使用,是因为一些常见的错误阻碍了大多数开发者编写CSS代码。如果你能避免这些错误,就会发现CSS实际上是一门简单易懂的语言,它不应该背负这样的恶名。
以下是我在咨询工作中见过的工程师最常犯的十大致命错误,按严重程度递增排列。错误越严重,如果不彻底重写代码库,就越难挽回。
错误 10:编写选择器时跟随DOM结构
我们以这个HTML页面为例:
<body>
<div class="container">
<div class="main-content">
<div class="blog-row">
<div class="blog-col">
<section>
<article>
<a href="#">This link is not bold</a>
<p><a href="#" class="bold">This link is bold</a></p>
</article>
</section>
<section>
<a href="#">This link is not bold</a>
</section>
</div>
</div>
</div>
</div>
</body>
有些开发者喜欢秉持极简主义理念,尽量避免在 HTML 中使用过多的类,而是利用 DOM 结构来编写 CSS 选择器,使选择器遵循 DOM 树的结构,如下所示:
🚫 错误
body > .container > .main-content > .blog-row > .blog-col > section > article > p > a.bold {
font-weight: bold;
}
像SASS这样的预处理器使得嵌套选择器变得特别容易和自然,因此这种做法尤其诱人:
🚫 错误
body
.container
.main-content
.blog-row
.blog-col
section
article
p
a
font-weight: bold
然而,这种“极简主义”是误入歧途的,因为保持 HTML 的“简洁”最终会导致 CSS 代码臃肿,难以理解、调试和修改。冗长的组合链迫使 CSS 承担复制 HTML 结构的任务,从而导致 CSS 变得僵化,但这并非 CSS 的职责所在。
CSS 的作用是提供样式,HTML 的作用是提供结构。DOM树的结构并不意味着 CSS 也应该与之匹配——CSS 的编写方式应该完全独立于 HTML。如果你决定更改 HTML 的结构,那么你必须回头更新所有在 CSS 中创建的组合链,这既繁琐又容易出错,而且会增加不必要的工作量。
相反,我建议尽可能使用针对特定元素的类。如果您需要从页面中选取特定元素,类选择器就能很好地完成这项工作:
✅ 正确
.bold {
font-weight: bold;
}
这些代码示例来自Painless CSS,这是一套从零开始教授 CSS 的书籍和视频课程。您可以下载包含课程中全部 60 个代码示例和解决方案的完整代码库。
现在,如果您以后想更改页面上链接的顺序,无需重写整个 CSS 规则。您只需将类.bold名移动到您想要的元素上即可。
幸运的是,如果你使用 CSS-in-JS 实现,这种错误的影响会小很多。然而,截至 2019 年,CSS-in-JS 尚未被广泛采用,我仍然会在未使用任何预处理器的代码库中看到不必要的链式选择器。
更普遍地说,你应该避免使用过于针对性或过于具体的选择器,也应该避免使用!important`.`。CSS优先级竞赛让我们直观地理解了为什么过于强大的选择器不好。如果一个选择器在竞赛中非常强大,它就能更快地赢得比赛,而且往往在更早的轮次就获胜,这意味着击败一个强大的选择器的唯一方法就是编写另一个更强大的选择器。
这种特异性不断升级的趋势被称为“特异性战争”。就像囤积核武器一样,这场战争没有赢家——随着特异性的增强,降级只会变得更加困难。避免全面爆发特异性战争的唯一方法,就是从一开始就不要囤积高威力选择器。
错误九:编写 HTML 时忽略 SEO
搜索引擎优化 (SEO) 并非代码编写完成后就可以简单地交给海外营销团队的任务。在编写代码的过程中,您应该考虑 SEO,尤其是一些影响 SEO 的因素一旦上线就很难更改,例如网站的 URL 方案或服务架构。
影响HTML代码SEO的一个重要因素是确保使用语义标签,因为标签的选择会影响搜索引擎如何理解和排名你的内容。如果你想在搜索结果中排名靠前,选择正确的标签是首要步骤之一。
例如,假设您正在撰写一篇关于多伦多房地产价格的博客文章。您可以将所有内容都放在 `<body>`<div>标签中;然而,`<body>`<div>是一个通用的、无语义的标签,它本身并不包含任何含义。相反,您应该选择一个更具体、语义化的标签,例如 ` <article><article>` 来包含文章,<nav>`<link>` 来包含指向其他博客文章的链接,以及<table>`<table>` 来包含有关房地产价格的表格数据。
选择更具体、语义更明确的标签而不是通用、非语义的标签的优势在于,您可以向搜索引擎提供更多关于您网站的信息,从而使搜索引擎爬虫能够更好地理解并提供与读者搜索查询相关的内容。
我们以标题为例。有六种可能的标题标签,按重要性从高到低排列:
<h1><h2><h3><h4><h5><h6>
<h1><head> 标签是最重要的标题,因为它向搜索引擎发出一个特殊信号,表明这是您内容的标题(虽然也有 <head><title>标签,但大多数搜索引擎会同时考虑两者)。此外,如果您的用户有视力障碍并使用屏幕阅读器,大多数屏幕阅读器会<h1>立即朗读 <head> 标签,因为它们默认这是您内容的标题。
这意味着,如果您将 <a> 标签用于<h1>标题以外的任何内容,或者如果您在一个页面上有多个 <a> 标签 <h1>,搜索引擎就会感到困惑,您的“真正”标题可能不会出现在搜索结果中。
但如果您在不同的部分嵌套多个 s,则情况会有所不同<h1>。例如:
<article>
<h1>My cool blog post</h1>
<p>This blog is so cool!</p>
</article>
<footer>
<h1>Contact Us</h1>
<p>Tel: 867-5309</p>
</footer>
尽管<h1>此页面上有两个 `<div>` 标签,但第一个标签的父标签是 `<div>` <article>,另一个标签的父标签是 `<div>` <footer>。由于搜索引擎认为 `<div>` 标签<article>本身比 `<div>` 标签更有趣、更重要<footer>,因此它可以恰当地使用<article>`<div> `<h1>标签而不是<footer>`<div>`<h1>标签来确定标题。所以从某种意义上说,你的父母是谁会影响你的重要性。就像现实生活中一样。😉
除了文中提到的因素外,还有许多其他因素会影响你的搜索引擎排名。为了不偏离本文主题,如果你对SEO感兴趣并想更深入地了解这个话题,我建议你阅读一本相关的书籍。(如何判断哪本书才是最好的SEO书籍呢?我怀疑随便在谷歌搜索结果中排名第一的书是不是个好主意。xkcd.com/125)
错误#8:px单位使用不当
实际上,在某些情况下使用px单位是没问题的。真正的错误在于使用绝对单位而不是相对单位。
我们尽可能使用相对计量单位,例如(一个Emem的长度)、(百分比)、(根 Em)等。这样可以确保网站根据您选择的字体和用户选择的缩放级别按比例缩放。%rem
🚫 错误
p {
font-size: 16px;
line-height: 20px;
margin-bottom: 8px;
}
✅ 正确
body {
font-size: 16px;
}
p {
font-size: 1rem;
line-height: 1.25;
margin-bottom: 0.5em;
}
这些代码示例来自Painless CSS,这是一套从零开始教授 CSS 的书籍和视频课程。您可以下载包含课程中全部 60 个代码示例和解决方案的完整代码库。
使用绝对单位的问题px在于,每个用户的显示器尺寸都不同,浏览器窗口(视口)的大小也各不相同。这似乎有悖常理,因为在生活中几乎所有其他领域,例如室内装饰、城市规划或烘焙,我们总是使用绝对单位。但在网络上,我们绘制的画布,每次换人查看时,其比例都会发生变化。
这样一来,您的网站就无法在所有地方保持相同的比例,因此您必须尝试使用相对单位(例如,砖块 B 应该和砖块 A 一样大)而不是绝对单位(例如,砖块 B 是一个 200px x 400px 的矩形)来放置元素;否则,屏幕上的可用空间将无法根据不同的窗口尺寸进行适当缩放。相对单位很容易导致这个问题——px它会将您的设计锁定在特定的缩放级别,并且使您的设计难以缩放以适应不同的设备。
错误七:试图实现“像素级完美”的设计
更普遍地说,在编写 CSS 时,“像素完美”设计并不是一个好的目标。
现代网站必须在各种设备(手机、台式机、平板电脑和手表)上运行,而这些设备屏幕尺寸、屏幕分辨率、操作系统、用户设置和 JavaScript 引擎种类繁多,都会影响您渲染“像素完美”设计的能力。
在我看来,盲目追求“像素完美”设计,会因为处理这些不一致的渲染方案而导致代码复杂度大幅增加(同时,复杂的代码还会增加出现错误的风险),而带来的好处却很小,而且一旦下一代设备、操作系统版本和浏览器版本发布,这些好处很可能就会被抵消。
实际上,只有像苹果或谷歌这样的大公司才有理由追求这种设计上的完美,因为它们有足够的资源(资金)雇佣庞大的设计团队,哪怕只是0.01%的设计改进。但除非你的公司每分钟也能赚到40万美元,否则0.01%的改进并不会让你每年多赚数百万美元——相反,它只会增加不必要的工程复杂性。
不要把“像素完美”的设计误认为是优秀的设计。真正优秀的设计在于给用户留下持久的情感印象。它体现在用户打开产品包装时的喜悦,以及他们与网站互动时的愉悦感。它并非仅仅因为你选择了16号字体而不是15号字体而受到赞赏。
错误六:打断文档流程
CSS 的难点在于,你可以编写不同的 CSS 代码来实现相同的视觉效果。例如,要使页面上的某个元素水平居中,你可以使用以下任何一种方法,它们对用户来说看起来都一样:
- 用边框包围元素,
直到它看起来居中为止。 - 明确地将元素的宽度
width和左侧边距设置margin为固定值,使其看起来居中。 - 使用
text-align: center - 使用
margin: 0 auto float使用ed siblings 和 clearfix的组合。- 结合使用
position,,left和transform。
哪种方法最好?根据你的目标,以上任何一种方法都可能完全适用。
一般来说,我们会遵循一些经验法则来选择最佳的布局方法。
首先,我们排除所有使用绝对度量而非相对度量的技术。这意味着方法#1 和#2需要明确地设定取值范围width。
其次,我们更倾向于使用不会改变文档流程的技术,而不是会破坏文档流程的技术。这是因为元素默认遵循文档流程,所以如果你打破了这个默认假设,就会让你的同事(或者你自己,六个月后)更难理解发生了什么。这意味着第 5 点float和第 6 点position都不适用。
更普遍地说,我们倾向于选择对其他系统影响最小的技术。保持代码体积小巧有助于避免编写庞大而复杂的代码,从而降低维护难度。
技术 #3text-align: center仅适用于行内元素,因此当我们的 HTML 已经是行内元素时,我们将选择 #3,这样就避免了添加display: inlineCSS 声明的额外需要。
技术 4margin: 0 auto仅适用于块级元素,因此只要我们的 HTML 已经是块级元素,我们就选择技术 4,这样就避免了额外添加display: blockCSS 声明的需要。
频繁地中断文档流程(例如过度使用 `<div>` 标签float)会增加代码体积,并使布局更难理解。当有多种编写 CSS 代码的方法可以实现相同的视觉效果时,我们倾向于使用代码体积更小的技术。
错误五:设计与布局未分开
CSS 的作用是提供样式,HTML 的作用是提供结构。通常,你应该首先编写 HTML 代码,使其能够体现页面的信息层级,暂时忽略任何设计方面的考虑。之后,你可以添加 CSS 来美化页面。
虽然 HTML 提供了结构,但它并非总能将元素精确地放置在页面上你想要的位置。因此,你可以使用 CSS 来搭建页面的正确布局,使元素出现在正确的位置。一旦元素被放置在页面上的正确位置,之后就可以轻松地对其进行美化,使其看起来更美观,而无需担心其位置问题。因此,你应该将“布局 CSS”与“美化 CSS”视为不同的工作。
🚫 错误
.article {
display: inline-block;
width: 50%;
margin-bottom: 1em;
font-family: sans-serif;
border-radius: 1rem;
box-shadow: 12px 12px 2px 1px rgba(0, 0, 0, .2);
}
.sidebar {
width: 25%;
margin-left: 5px;
}
<div class="article"></div>
<div class="article sidebar"></div>
✅ 正确
/* Layout */
.article, .sidebar {
display: inline-block;
}
.article {
width: 50%;
margin-bottom: 1em;
}
.sidebar {
width: 25%;
margin-left: 5px;
}
/* Lipstick */
.card {
font-family: sans-serif;
border-radius: 1rem;
box-shadow: 12px 12px 2px 1px rgba(0, 0, 0, .2);
}
<div class="article card"></div>
<div class="sidebar card"></div>
这些代码示例来自Painless CSS,这是一套从零开始教授 CSS 的书籍和视频课程。您可以下载包含课程中全部 60 个代码示例和解决方案的完整代码库。
将“涂口红”的工作与“布局”的工作分开,也称为关注点分离,这是一项常见的软件工程原则,有助于保持代码的可维护性和易理解性。
我们希望使用合适的工具来完成任务,因为这样分离 CSS 可以轻松地将元素移动到页面的其他位置而不会弄脏页面,也可以轻松地更改页面颜色而不会破坏布局。如果将两者混合使用,即使新功能只需要其中一项功能,每次添加新功能时也必须执行两项操作。
错误四:先设计桌面端,再设计移动端
过去那种移动网站只是开发机构为了增加收入而附加的可选项的日子已经一去不复返了。现在大多数人都用手机上网,超过50%的网站流量来自手机和平板电脑的情况也十分普遍。
人们喜欢推崇“移动优先”理念,却忘记了“移动优先”意味着桌面端处于劣势。相反,“移动优先”的拥护者们却反其道而行之,他们先编写桌面端代码,然后再试图将网站硬塞进手机里。他们使用@media查询来处理移动端的特殊情况,但实际上,桌面端才是真正应该被优先考虑的例外情况。
在这个移动时代,用户首先通过手机找到你,然后只有在他们足够喜欢你的产品后,才会升级到桌面体验。
但是,在你们的设计师、开发人员和产品经理心中,移动端真的占据了首要位置吗?你们是先编写移动网站代码,然后再构建桌面版本吗?你们的设计师会在创建桌面版线框图和模型之前,先创建移动端线框图和模型吗?在测试桌面版之前,你们会对网站的移动版进行 A/B 测试并征求用户反馈吗?
🚫 错误
.container {
width: 980px;
padding: 1em;
}
@media (max-width: 979px) {
.container {
width: 100%;
padding: 0.5em;
}
}
✅ 正确
.container {
width: 100%;
max-width: 980px;
padding: 0.5em;
}
@media (min-width: 980px) {
.container {
padding: 1em;
}
}
/*
Notice how this also avoids needing to
write 979 instead of 980, so you don't
need to search for two different values
*/
这些代码示例来自Painless CSS,这是一套从零开始教授 CSS 的书籍和视频课程。您可以下载包含课程中全部 60 个代码示例和解决方案的完整代码库。
用户群体以移动端为主并非优先开发移动端应用的唯一原因。主要原因在于,先针对小屏幕进行开发,再将设计缩放到大屏幕要容易得多,反之则不然。你可以随时放大现有元素来填充大屏幕上的空白区域,但要从大屏幕上移除元素以使其适应小屏幕则要棘手得多。

图片来源:Zurb
如果你只发布移动网站而没有桌面网站,现在构建移动网站需要花费 X 美元,以后再添加桌面网站还需要 X 美元。但如果你只发布桌面网站而没有移动网站,现在构建桌面网站需要花费 X 美元,以后再添加移动网站则需要花费 2X 美元。这就是人们所说的“技术债务”:你今天支付的成本较低,但从长远来看,却要付出更高的代价。
如果你正处于闪电式扩张阶段,那么先构建桌面网站来验证产品与市场的契合度,并考虑到移动网站后续会花费更多成本,这种“低效”的做法或许是合理的。但这毕竟是一个商业决策。工程师们通常会倾向于先构建移动网站,即使这并非总是符合商业逻辑。因此,你需要根据自身发展阶段调整这一建议。
错误三:未使用命名规则
命名空间真是个绝妙的主意——让我们多用用它!
—— PEP 20:Python之禅
总是很兴奋地直接开始编写代码,而不仔细考虑变量的命名规则。例如,你会把它叫做 ` a`img还是image`b`?blog-img或者img-blog`c` 还是blog-image`d` blog-img?如果你把它叫做 `a` ,之后你会和 `b`和 `c`blog-img达成一致吗?ad-imgthumbnail-img
这看似微不足道,但CSS比其他语言更难重构,因为我们目前没有任何静态分析工具可以对CSS进行自动重构/重命名。CSS类可以使用JavaScript动态添加、删除和构建,因此不可能找到“未使用”的CSS选择器——仅仅因为一段CSS代码在某个页面的某个状态下没有被使用,并不意味着它永远不会被使用。如果你的团队无法就某个选择器的名称达成一致,例如`<style>` 、` <style> `、 `<style>`或`<style> `,那么BEM也无法解决这个问题。.center.centre.centered.text-center.align-center
使用 CSS-in-JS 库可以部分解决这个问题,因为这些框架移除了 CSS 的全局作用域,并鼓励你将样式与其关联的组件放在一起。然而,截至 2019 年,CSS-in-JS 尚未得到广泛应用,我仍然希望有一个 CSS 静态分析工具——理论上,CSS-in-JS 应该能让这个工具的实现成为可能。
使用设计系统也能部分解决这个问题,在设计系统中,你可以就颜色、间距、字体等一组固定的变量达成一致,但是未使用的类往往会一直存在,因为我们没有自动识别和删除它们的方法来解决这个问题。
开发人员出于谨慎考虑,不愿移除任何可能导致网站崩溃的内容,因此他们宁愿保留大量冗余文件。更糟糕的是,除非你积极推广并清晰地传达你的设计系统,否则它很可能被忽视,因为你的同事会避免阅读你的文档,继续沿用他们原有的工作习惯。
错误二:未阅读文档
看起来很简单。只要安装 Bootstrap 就万事大吉了,对吧?可惜的是,如果你不真正理解 CSS 框架,或者无意中违背了它的原则,它往往会带来更多问题。无论你使用的是像 Bootstrap、Material Design、Foundation 这样的开源设计系统,还是公司自己开发的设计系统,都可能出现这种情况。
我职业生涯中最明智的决定之一,就是每次想使用新的编程语言或框架时,都抽出 4 到 8 个小时完整地阅读官方文档。不是粗略浏览文档,也不是只搜索与我当前需求相关的关键词,而是像读一本书一样,从头到尾认真阅读。
例如,在使用 Bootstrap 之前,我特意花了 6 个小时通读了它的文档。这为我之后的实现工作节省了无数时间,尤其是在避免网格嵌套问题方面——这类问题似乎很普遍,因为那些跳过文档的人并不知道 Bootstrap 容器是不允许嵌套的。
认真阅读文档至关重要,因为许多框架需要你摒弃从其他框架中养成的习惯,而且只有通读完整本手册,你才能发现其中的陷阱。例如,组件继承是 Backbone 等早期前端框架中常见的模式。然而,像 React 这样的新框架在使用组合而非继承时效果最佳,但如果你跳过文档,就不会意识到这一点,因为你仍然会默认使用你习惯的继承模式。
更普遍地说,被旧技术养成的肌肉记忆所束缚是危险的,这导致了最终的致命错误:
错误一:没有遵循系统的CSS学习计划
科技日新月异,保持与时俱进的唯一途径就是坚持不懈地学习和进步。
死记硬背教条式的知识是危险的。一些经验丰富的开发者一听到“内联样式”就会产生本能的抵触情绪,因为他们在职业生涯早期就被灌输了“永远不要使用内联样式”的最佳实践。
的确,“永远不要使用内联样式”在很久以前曾是一种最佳实践,因为那时HTML代码难以阅读、难以调试且难以修改。然而,技术不断发展,最终会颠覆那些导致这些“最佳实践”的假设。新的假设又会催生新的最佳实践。
只有手动编写内联样式时才会感到痛苦——但如果您使用 CSS-in-JS 库来管理内联样式,这些缺点就会消失,您只会享受到代码模块化、自动化测试和简单管理等优点,这些优点可以与 React 等前端 JavaScript 框架完美配合。
如果你固守“永远不要使用内联样式”的教条,就不会有好奇心去探索当最初的假设改变时意味着什么。学习 CSS 需要系统、结构化的学习计划,而不是仅仅在谷歌上搜索那些只关注表面技巧的教程。
很遗憾,我尝试寻找一些免费的在线资源,希望能系统地学习 CSS,但根本找不到什么好的资源。现有的 CSS 资源要么过于技术化,假定你已经了解浏览器 C++ 渲染引擎的工作原理(这根本无法理解),要么只提供一些权宜之计,而没有讲解基础原理。
由于缺乏能够从根本上构建CSS工作原理的优质资源,人们只能从Stack Overflow复制粘贴代码,然后祈祷它们有效。这导致许多人对CSS的了解支离破碎,仅能勉强解决一些特定的bug,但面对难以理解、似乎需要花费数小时才能修复的复杂bug时,却感到束手无策。
多年来,我为软件创业公司提供咨询服务,却屡屡看到人们在 CSS 方面犯同样的错误,这让我感到非常沮丧。于是,我决定亲力亲为,编写自己的资源。我创建了“轻松学 CSS”课程,旨在提供一套全面、基于基本原理的 CSS 学习指南,帮助你以正确的方式学习 CSS,并掌握编写专业级 CSS 所需的真正技能。
秘诀在于,一旦你掌握了正确的思维模式,CSS 实际上是一门非常简单的语言。我创建了“轻松学 CSS”课程,就是希望 CSS 能够摆脱不应有的恶名,浴火重生,成为它本应拥有的那门优美的编程语言。
希望您喜欢这篇文章,并能从中了解如何避免我在编写 CSS 时看到的十大最常见错误。我还看到人们在 CSS 编写中犯许多其他错误——您可以在Painless CSS课程中详细了解所有这些错误以及如何修复它们:www.painlesscss.com。
与此同时,我希望这篇文章对您有所帮助,并能激励您认真对待学习 CSS 的计划,无论您最终选择购买我的课程还是其他人的课程。现在正是学习前端 Web 开发的最佳时机,祝您在编程之旅中一切顺利。
文章来源:https://dev.to/billmei/top-10-most-deadly-css-mistakes-made-by-new-and-experienced-developers-100d
