减少对伪元素的需求

307 阅读9分钟

Reducing The Need For Pseudo-Elements

原文链接:www.smashingmagazine.com/2021/09/red…

简摘 ↬ 多年来,伪元素一直忠实地帮助前端开发者实现创意设计。虽然它们仍然有重要的地位,但由于有了新的CSS属性,在某些情况下,我们就可以抛开伪元素了。

根据 W3C 观察,”用一个伪元素来代表一个元素并不会直接出现在文档树中“。他们是从CSS规范的第一版开始出现的,当时 ::first-letter::first-line 都有被引入。在第二版中,流行的 ::before::after 伪元素被加入——这些代表了在原文件根本不存在的内容。 它们可以被认为是两个额外的元素,你可以把他们”贴“在原来的元素上。当前端开发者听到”伪元素“时,更容易想到 ::before::after ,因为我们作为前端开发者会用不同的方式去在我们的元素上添加这两个伪元素。

除此之外,还有一些额外的伪元素。他们在规范里被归为三个类别: typographichighlighttree-abiding(排版、高亮和守树)。

有趣的是,多年的 web 开发,我发现我从来没有用过 ::first-line,虽然它很整洁,而且对窗口的缩放响应很好!可以看看:

可以参考 Marcel 写的 ::first-line

::selection 是另一个经常用到的伪元素。当一个用户高亮了文本,那高亮颜色就会显示成你指定的颜色。

可以看看 Marcel 写的 ::selection

小贴士

伪元素在CSS规范的第一和第二版中使用一个冒号,但从第三版开始使用两个冒号。这就可以把它们和描述元素状态的伪类区分出来:伪类使用一个冒号。

  • 伪元素用两个冒号(例如: ::before::after::marker);
  • 伪类用一个冒号(例如::hover, :focus)。

伪元素不是一直都有必要

伪元素仍然有一席之地。这篇文章不是说”永远别用伪元素“而是说”我们没有必要使用那么多的伪元素“。我们可以在不需要伪元素的情况下对一些流行的用户界面元素进行样式设计。通过减少对伪元素的依赖,我们可以写更少的CSS,消除嵌套元素,忽略堆叠上下文问题,并忘掉定位。

接着看吧 ↓

用新的CSS属性再看一眼可信任的技术

多年来,我们耐心地等待着浏览器更快地采用CSS技术。当一些大公司宣布停止对IE11的支持时,对许多前端开发者来说是一个转折点:

  • 所有Microsoft 365 网页APP从2021年8月21号起停止;
  • Google 工作空间 (谷歌邮箱谷歌日历、_谷歌硬盘等等) 从2021年3月15日起停止支持。

这使我们中的许多人能够更自由地探索新的CSS技术:CSS Grid、clamp()background-blend-mode 等等。CSS属性的支持性就很好。而且随着浏览器的更新,支持的速度也在加快。

来举几个栗子!

带角的按钮

许多前端开发者对使用 ::before::after 伪元素和CSS边框规则来创建形状很熟悉。有许多专门用于此目的的生成器工具—— 这个 就是我收藏的一个。这些工具指导你选择一个形状(通常是三角形)和适当的CSS规则。

角度按钮需要能够处理单词的包装。

在创建有角度的按钮时,这些工具是救命稻草。对于有角度的按钮,它们不再是必要的。

带有伪元素的角形按钮可能需要更多的HTML元素。 (预览大图)

伪元素版本

你们中的许多人读到这里会习惯于伪元素的版本:

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

除了这些步骤外,我们的悬停样式必须同时考虑到我们的嵌套元素和伪元素。这对你来说可能是可控的,但我们的按钮设计越复杂,悬停样式的开销就越大。另外,在这个版本中,带有文字包装的按钮会报错。

参考 Marcel 写的Button angle with pseudo-element

无伪元素版本

没有伪元素就更容易了。

  • 我们用一个包装元素——我们的按钮<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改成另一个值,就可以看到我们按钮的角度也有相应地调整。

我们的悬停样式只需要考虑到一个元素——就是我们的按钮。而且,带有文字包装的按钮表现更优雅。

MarcelButton angle with NO pseudo-element

展示中其他的斜角按钮样式

最终的展示编码笔中有额外的斜角按钮例子。(大图)

访问最终展示,看看其他这些没有伪元素的按钮样式变得更容易。特别是,蓝色斜角按钮的伪元素版本是相当残酷的。还好有clip-path,整体工作量会大大减少。

按钮擦拭

擦除特效是一种流行的按钮风格。我已经用到了从左到右和从上到下的擦拭。

有时,需要一种擦拭的效果。

伪元素版本

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

  • 我们绝对定位一个::before伪元素,并给它一个变换:scaleX(0),这样它就不可见了;

  • 我们还必须明确设置它的transform-origin: 0 0以确保擦拭从左边而不是从中间(transform-origin默认为中间);

  • 我们在transform上设置了transitions,以便在悬停时制作一些流畅的爵士乐动画;

  • 因为我们的伪元素是绝对定位的,所以我们需要一个嵌套元素来容纳按钮的文本,在这个嵌套元素上的position: relative创建了一个新的堆叠环境,所以我们的文本保持在我们擦拭的伪元素之上。

  • 在悬停时,我们可以针对我们的伪元素,将其 scaleX 转换transition1 (transform: scaleX(1))

Marcel 写的Button wipe with pseudo-element

无伪代码版本

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

我们可以用 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-gradientbackground-size` 值。我已经通过CSS自定义属性改变了这些。

Marcel写的 Button wipe with NO pseudo-element

有屏幕颜色覆盖的瓷砖

瓷砖通常包含一个背景图像、颜色覆盖和文本内容。

这是一种常见的模式,半透明的颜色覆盖在瓷砖/卡片上。我们的例子中的瓦片也有一个背景图像。在这种模式中,保留一个固定的长宽比往往很重要,这样如果一组中出现多个瓷砖,瓷砖看起来就很统一。

伪元素版本

一些相同的东西在我们的伪元素版本中发挥作用。

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

Marcel写的: Tile screen color overlay with pseudo-element

无伪元素的版本

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

注意aspect-ratio 在Safari 14.x中还不支持,但在15版中可以。

也就是说,截至目前,caniuse列出了它的全球有70%以上支持。

  • padding-trick aspect-ratio: 400/240取代(我们可以在这里使用任何基于5:3的值)。
  • 我们使用background-imagebackground-color属性与background-blend-mode相结合——简单地改变悬停时磁贴元素的background-color
Background-blend-mode

background-blend-mode 用一个元素的 background-image混合了一种 background-color。任何一个Photoshop用户看到这里都会从 background-blend-mode 联想到Photoshop的混合模式。 background-blend-mode 不像 mix-blend-mode,没有创建新的叠加背景!一点也不 z-index

CSS现在提供仿Photoshop特效。

可以参考 Marcel 写的钢笔效果:

不带伪元素的瓦片屏幕颜色覆盖

结论

前端开发是令人兴奋且快速发展的。有了更新的CSS属性,我们就可以拂去旧技术上的灰尘,对其进行重新审视。这样做有助于促进减少和简化代码。伪元素是有帮助的,但我们没有必要过多地去使用它们。