减少对伪元素的需求

已发表: 2022-03-10
快速总结 ↬多年来,伪元素忠实地帮助前端开发人员实施创意设计。 虽然它们仍然占有重要地位,但由于更新的 CSS 属性,我们现在可以在某些情况下留下伪元素。

根据 W3C 规范,“伪元素表示不直接存在于文档树中的元素”。 它们从 CSS 规范的第 1 版开始就出现了,当时引入了::first-letter::first-line 。 流行的::before::after伪元素是在版本 2 中添加的——它们表示源文档中根本不存在的内容。 它们可以被认为是两个额外的元素,你可以“附加”到它们的原始元素上。 当前端开发人员听到“伪元素”时,我们经常会想到::before::after ,因为我们以各种方式使用它们来为我们的元素添加装饰。

除了这些之外,还有其他伪元素。 它们在规范中列在三个类别中:印刷、突出显示和树型。

有趣的是,经过多年的 Web 开发,我从未发现自己使用过::first-line ,但它非常简洁,并且对窗口大小调整反应良好! 看看这个。

请参阅 Marcel 的 Pen [`::first-line`](https://codepen.io/smashingmag/pen/gORgXxN)。

请参阅 Marcel 的 Pen ::first-line

::selection是许多人可以使用的另一个伪元素。 当用户突出显示文本时,突出显示颜色将是您指定的颜色。

请参阅 Marcel 的 Pen [`::selection`](https://codepen.io/smashingmag/pen/rNwjYGz)。

请参阅 Marcel 的 Pen ::selection
小建议

伪元素在 CSS 规范的版本 1 和 2 中使用了一个冒号,但在版本 3 中使用了两个冒号。这将它们与描述元素状态的伪类区分开来。 伪类使用一个冒号。
  • 对伪元素使用两个冒号(例如::before::after::marker )。
  • 伪类使用一个冒号(例如:hover:focus )。

伪元素并不总是需要

伪元素仍然有一席之地。 这篇文章不是“永远不要使用伪元素”,而是“我们不再需要尽可能多地使用伪元素”。 我们可以在不需要伪元素的情况下为许多流行的用户界面元素设置样式。 通过减少对伪元素的依赖,我们可以编写更少的 CSS,消除嵌套元素,忽略堆叠上下文问题,并忘记定位。

跳跃后更多! 继续往下看↓

重新审视具有新 CSS 属性的可信技术

多年来,我们耐心等待浏览器更快地采用 CSS 技术。 当一些主要参与者宣布将停止对 Internet Explorer (IE11) 的支持时,许多前端开发人员的转折点出现了:

  • 所有 Microsoft 365 Web 应用已于 2021 年 8 月 21 日停止支持 IE11。
  • Google Workspace( Gmail日历云端硬盘等)已于 2021 年 3 月 15 日停止支持 IE11。

这让我们中的许多人可以更自由地探索更新的 CSS 技术:CSS Grid、 clamp()background-blend-mode等等。 CSS 属性支持的状态很好。 借助可更新的浏览器,支持正在加速。

举个例子!

斜角按钮

许多前端开发人员都熟悉使用::before::after伪元素和 CSS 边框规则来创建形状。 有许多专门用于此目的的生成器工具——这是我收藏的一个。 这些工具指导您选择形状(通常是三角形),为您提供正确的 CSS 规则。

角度按钮需要能够处理自动换行。

在创建有角度的按钮时,这些工具是救生员。 对于有角度的按钮,它们不再是必需的。

带有伪元素与不带伪元素的角度按钮的构建块的比较
带有伪元素的角度按钮可能需要更多的 HTML 元素。 (大预览)

伪元素版本

许多阅读本文的人会习惯于伪元素版本:

  • 我们使用一个相对定位的带有大右填充的包装元素来适应我们的角度——这就是我们的<button>
  • 我们中的许多人,滑动门技术的学生,习惯于嵌套一个元素来呈现按钮的背景色。
  • 最后,我们将一个带有边框规则的伪元素绝对定位到<button>的右侧填充空白空间中——我们为此使用::before

除了这些步骤之外,我们的悬停样式必须同时考虑我们的嵌套元素和伪元素。 这对您来说似乎可以管理,但是我们的按钮设计越复杂,悬停样式的开销就越大。 此外,在此版本中,带有自动换行的按钮完全失败。

请参阅 Marcel 的 Pen [Button angle with pseudo-element](https://codepen.io/smashingmag/pen/xxrgPpj)。

请参阅 Marcel 的带有伪元素的 Pen Button 角度。

无伪元素版本

如果没有伪元素,这要容易得多。

  • 我们使用一个包装元素——我们的<button>
  • 我们使用clip-path属性来只显示我们想要的按钮部分,使用calc()和 CSS 自定义属性来调整我们的角度——这些点集对应于左上角、右上角、右中角、底部右和左下角: polygon(0% 0%, calc(100% - var(--angle-width)) 0%, 100% 50%, calc(100% - var(--angle-width)) 100%, 0% 100%)

在 CodePen 示例中,您将--angle-width自定义属性从2rem为另一个值,以查看我们按钮的角度相应调整。

我们的悬停样式只需要考虑一个元素——我们的按钮。 此外,带有自动换行的按钮以更优雅的方式运行。

请参阅 Marcel 的 Pen [Button angle with NO pseudo-element](https://codepen.io/smashingmag/pen/PojWOQY)。

请参阅 Marcel 的带有 NO 伪元素的 Pen Button 角度。

展示柜中更多有角度的按钮样式

两个额外的角度按钮,具有更复杂的角度。
最后的展示 codepen 有额外的角度按钮示例。 (大预览)

访问最终展示,看看这些其他按钮样式在没有伪元素的情况下变得更容易。 尤其是蓝色斜角按钮的伪元素版本非常残酷。 由于clip-path ,整体工作量大大减少。

纽扣湿巾

擦拭效果是一种流行的按钮样式。 我已经包括从左到右和从上到下的擦拭巾。

有时,需要擦拭效果。

伪元素版本

这可以通过transitioning伪元素的transform来实现。

  • 我们绝对定位一个::before伪元素并给它一个transform: scaleX(0)所以它不可见。
  • 我们还必须显式设置它的transform-origin: 0 0以确保擦除从左侧而不是中心进入( transform-origin默认为中心)。
  • 我们在transform上设置了transitions ,以实现一些流畅的爵士动画开/关悬停。
  • 因为我们的伪元素是绝对定位的,所以我们需要一个嵌套元素来保存按钮的文本, position: relative在这个嵌套元素上创建一个新的堆叠上下文,因此我们的文本保持在我们正在擦除的伪元素之上。
  • 在悬停时,我们可以定位我们的伪元素并将它的scaleX transition为现在为1 (transform: scaleX(1))

请参阅 Marcel 的 Pen [使用伪元素擦除按钮](https://codepen.io/smashingmag/pen/KKqayGW)。

请参阅 Marcel 的带有伪元素的 Pen Button 擦除。

无伪元素版本

如果我们不必担心嵌套元素、伪元素定位、堆叠上下文和庞大的悬停规则,为什么还要担心呢?

我们可以使用linear-gradient()background-size来确定这一点。

  • 我们给我们的<button>一个background-color作为它的默认状态,同时还通过background-image设置一个linear-gradient ——但是background-size将是0 ,所以默认情况下我们不会看到任何东西。
  • 在悬停时,我们将background-size转换为100% 100% ,这给了我们擦除效果!

请记住, linear-gradient()使用background-image属性,而background-image取代了background-color ,所以这在悬停时优先。

而已。 不需要嵌套元素。 想要垂直擦拭? 只需更改linear-gradient方向和background-size值。 我已经通过 CSS 自定义属性更改了这些。

请参阅 Marcel 的 Pen [无伪元素的按钮擦除](https://codepen.io/smashingmag/pen/MWoJOVo)。

请参阅 Marcel 的使用 NO 伪元素的 Pen Button 擦除。

带有屏幕颜色叠加层的瓷砖

平铺通常包含背景图像、颜色叠加层和文本内容。

这是一种常见的模式,其中半透明颜色覆盖瓷砖/卡片。 我们示例的图块也有一个背景图像。 在此模式中,保留一组纵横比通常很重要,这样如果一组中出现多个图块,则图块看起来一致。

伪版

我们的伪元素版本也有一些相同的东西:

  • 我们使用纵横比“padding-trick”,为我们的 tile 设置 60% 的 padding-top 值(5:3 比率)。
  • 我们必须定位我们的屏幕颜色覆盖伪元素,给它一个 100% 的widthheight来填充瓷砖——我们在悬停时定位这个伪元素来改变它的background-color
  • 由于伪元素的绝对定位,我们必须为我们的文本内容使用嵌套元素,同时给它position: absolute以便它以堆叠顺序出现我们的屏幕颜色叠加层之上,并确保它出现在它应该出现的位置瓷砖。

请参阅 Marcel 的 Pen [平铺屏幕颜色叠加与伪元素](https://codepen.io/smashingmag/pen/YzQNEOM)。

请参阅 Marcel 的带有伪元素的 Pen Tile 屏幕颜色叠加。

无伪元素版本

由于宽高比和背景混合模式属性,它可以简单得多。

注意aspect-ratio在 Safari 14.x 中不起作用,但在版本 15 中会起作用。

也就是说,在撰写本文时,caniuse 将其列为 70% 以上的全球支持。

  • “填充技巧”被aspect-ratio: 400/240 (我们可以在这里使用任何基于 5:3 的值)。
  • 我们将background-imagebackground-color属性与background-blend-mode结合使用——只需在悬停时更改 tile 元素的background-color
Background-blend-mode

background-blend-modebackground-color与元素的background-image混合。 任何阅读本文的 Photoshop 用户都会发现background-blend-mode让人想起 Photoshop 的混合模式。 与mix-blend-mode不同, background-blend-mode不会创建新的堆叠上下文! 所以没有z-index地狱!

CSS 现在提供类似 Photoshop 的效果。

请参阅 Marcel 的 Pen [Tile screen color overlay with NO pseudo-element](https://codepen.io/smashingmag/pen/mdwRqjN)。

请参阅 Marcel 的带有 NO 伪元素的 Pen Tile 屏幕颜色叠加。
  • 您可以在此处找到完整的展示演示 →

结论

前端开发令人兴奋且发展迅速。 使用更新的 CSS 属性,我们可以拂去旧技术的灰尘,让它们焕然一新。 这样做有助于促进减少和更简单的代码。 伪元素是有帮助的,但我们不需要尽可能多地使用它们。