减少对伪元素的需求
已发表: 2022-03-10 根据 W3C 规范,“伪元素表示不直接存在于文档树中的元素”。 它们从 CSS 规范的第 1 版开始就出现了,当时引入了::first-letter
和::first-line
。 流行的::before
和::after
伪元素是在版本 2 中添加的——它们表示源文档中根本不存在的内容。 它们可以被认为是两个额外的元素,你可以“附加”到它们的原始元素上。 当前端开发人员听到“伪元素”时,我们经常会想到::before
和::after
,因为我们以各种方式使用它们来为我们的元素添加装饰。
除了这些之外,还有其他伪元素。 它们在规范中列在三个类别中:印刷、突出显示和树型。
有趣的是,经过多年的 Web 开发,我从未发现自己使用过::first-line
,但它非常简洁,并且对窗口大小调整反应良好! 看看这个。
::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 规则。
在创建有角度的按钮时,这些工具是救生员。 对于有角度的按钮,它们不再是必需的。
伪元素版本
许多阅读本文的人会习惯于伪元素版本:
- 我们使用一个相对定位的带有大右填充的包装元素来适应我们的角度——这就是我们的
<button>
; - 我们中的许多人,滑动门技术的学生,习惯于嵌套一个元素来呈现按钮的背景色。
- 最后,我们将一个带有边框规则的伪元素绝对定位到
<button>
的右侧填充空白空间中——我们为此使用::before
。
除了这些步骤之外,我们的悬停样式必须同时考虑我们的嵌套元素和伪元素。 这对您来说似乎可以管理,但是我们的按钮设计越复杂,悬停样式的开销就越大。 此外,在此版本中,带有自动换行的按钮完全失败。
无伪元素版本
如果没有伪元素,这要容易得多。
- 我们使用一个包装元素——我们的
<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
为另一个值,以查看我们按钮的角度相应调整。
我们的悬停样式只需要考虑一个元素——我们的按钮。 此外,带有自动换行的按钮以更优雅的方式运行。
展示柜中更多有角度的按钮样式
访问最终展示,看看这些其他按钮样式在没有伪元素的情况下变得更容易。 尤其是蓝色斜角按钮的伪元素版本非常残酷。 由于clip-path
,整体工作量大大减少。
纽扣湿巾
擦拭效果是一种流行的按钮样式。 我已经包括从左到右和从上到下的擦拭巾。
伪元素版本
这可以通过transitioning
伪元素的transform
来实现。
- 我们绝对定位一个
::before
伪元素并给它一个transform: scaleX(0)
所以它不可见。 - 我们还必须显式设置它的
transform-origin: 0 0
以确保擦除从左侧而不是中心进入(transform-origin
默认为中心)。 - 我们在
transform
上设置了transitions
,以实现一些流畅的爵士动画开/关悬停。 - 因为我们的伪元素是绝对定位的,所以我们需要一个嵌套元素来保存按钮的文本,
position: relative
在这个嵌套元素上创建一个新的堆叠上下文,因此我们的文本保持在我们正在擦除的伪元素之上。 - 在悬停时,我们可以定位我们的伪元素并将它的
scaleX
transition
为现在为1 (transform: scaleX(1))
。
无伪元素版本
如果我们不必担心嵌套元素、伪元素定位、堆叠上下文和庞大的悬停规则,为什么还要担心呢?
我们可以使用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 自定义属性更改了这些。
带有屏幕颜色叠加层的瓷砖
这是一种常见的模式,其中半透明颜色覆盖瓷砖/卡片。 我们示例的图块也有一个背景图像。 在此模式中,保留一组纵横比通常很重要,这样如果一组中出现多个图块,则图块看起来一致。
伪版
我们的伪元素版本也有一些相同的东西:
- 我们使用纵横比“padding-trick”,为我们的 tile 设置 60% 的 padding-top 值(5:3 比率)。
- 我们必须定位我们的屏幕颜色覆盖伪元素,给它一个 100% 的
width
和height
来填充瓷砖——我们在悬停时定位这个伪元素来改变它的background-color
。 - 由于伪元素的绝对定位,我们必须为我们的文本内容使用嵌套元素,同时给它
position: absolute
以便它以堆叠顺序出现在我们的屏幕颜色叠加层之上,并确保它出现在它应该出现的位置瓷砖。
无伪元素版本
由于宽高比和背景混合模式属性,它可以简单得多。
注意: aspect-ratio
在 Safari 14.x 中不起作用,但在版本 15 中会起作用。
也就是说,在撰写本文时,caniuse 将其列为 70% 以上的全球支持。
- “填充技巧”被
aspect-ratio: 400/240
(我们可以在这里使用任何基于 5:3 的值)。 - 我们将
background-image
和background-color
属性与background-blend-mode
结合使用——只需在悬停时更改 tile 元素的background-color
。
Background-blend-mode
background-blend-mode
将background-color
与元素的background-image
混合。 任何阅读本文的 Photoshop 用户都会发现background-blend-mode
让人想起 Photoshop 的混合模式。 与mix-blend-mode
不同, background-blend-mode
不会创建新的堆叠上下文! 所以没有z-index
地狱!
- 您可以在此处找到完整的展示演示 →
结论
前端开发令人兴奋且发展迅速。 使用更新的 CSS 属性,我们可以拂去旧技术的灰尘,让它们焕然一新。 这样做有助于促进减少和更简单的代码。 伪元素是有帮助的,但我们不需要尽可能多地使用它们。