likes
comments
collection
share

到底什么是伪元素 ?

作者站长头像
站长
· 阅读数 70

前言

前几天为了尝试 chatGPT 的打字机效果手写了一个 定时器 + css 的实现

在实现光标的闪烁的过程中,我将伪元素作为光标的主体,这时候伪元素就出现啦。

我想伪元素大家都不陌生吧,在学习 css 或是开发页面的过程中或多或少都会用到过。

但对于平时只知道用的我,从来也没想过在 DOM 中去获取它。

那既然这次实现中遇到了伪元素就来看看它到底为什么东西。

打字机效果实现

先看看我的打字机是怎么实现的 😂

import React, { useEffect } from "react";
import "./index.scss";

export default function Detail() {
  useEffect(() => {

    const element = document.getElementById("typewriter") as HTMLElement;
    // console.log(element.textContent);
    const text =
      "当你不知道该往哪走的时候,就先跑起来,耳边有风,风就是方向。";
    let i = 0;
    const typing = setInterval(() => {
      if (i > text.length) {
        console.log("输入完成");
        clearInterval(typing);
        // 输入完成取消光标输入样式
        element.setAttribute("data-attr", "");
      } else {
        element.setAttribute("data-attr", "|");
        element.textContent = text.slice(0, i);
        i++;
      }
    }, 200);
  });
  return <div id="typewriter" data-attr="|"></div>;
}

/* scss 光标闪烁样式 */
#typewriter {
  display: inline-block;
  width: 200px;
  height: 200px;

  &::after{
    display: inline-block;
    content: attr(data-attr);
    color:black;
    animation:  0.5s blink infinite  step-end ;
  }
}
@keyframes blink{
  from{
    opacity: 0;
  }

  50% {
    opacity: 1;
}
to {
  opacity: 0;
}

}

这里用到了一个 attr() 函数它是 CSS 的一个内置函数,用于获取元素的属性值。

content 属性通过 attr(data-attr) 获取元素的 data-attr 属性值,并将其作为伪元素的内容。

通过 data-attr 属性可以控制伪元素得展示和隐藏 。

当然在写这个效果得时候并没有那么顺利,想要控制光标的消失我也想过用 js 去获取伪元素的 DOM 结构,但是奈何假的就是假的,及时它再怎么像真的终究还是假的,DOM 中根本不存在这个节点,所以只能换个角度,通过样式的属性去控制伪元素的消失。

那么究竟什么是伪元素呢,我们该怎么去获取伪元素并修改他呢?

带着这个大大疑问开始今天的 6 月更文吧!!!

什么是伪元素?

在CSS中,伪元素(pseudo-elements)是用于选择元素的特定部分或生成额外内容的一种方式。

之所以称之为 '伪元素' 是因为它们是虚拟的,他可以被浏览器渲染但并不实际存在于 HTML 文档结构中的,而是通过CSS样式来创建和控制。

伪元素通过 content 属性向页面加入额外的内容,例如插入图标、添加装饰性的元素等。它们也可以用于选择元素的特定部分,例如选择元素的第一个字母或第一行文本等。

button::before {
  content: "+";
  font-size: 20px;
  margin-right: 5px;
}

这里向 button 元素前插入一个“+”图标,并设置了图标的大小和右侧间距。

这样可以让按钮看起来更加美观和易于理解。

伪元素的使用

CSS3 规范中的要求使用双冒号 (::) 表示伪元素,以此来区分伪元素和伪类。除了IE8及以下版本,所有浏览器都支持两个冒号的伪元素表示法。

常见的伪元素:

在这其中最常用的就是 ::after 和 ::before。

伪元素选中或创建出来的元素兼容性
::first-letter选中(仅适用于块级)元素中的第一个元素
::first-line选中首行
::before在元素前创建一个虚拟元素
::after在元素后创建一个虚拟元素
::placeholder选中表单元素的占位文本
::file-selector-button选中类型为 file 的 input 里面的 button
::selection选择被用户选中的文本部分⚠️
::backdrop选中视觉聚焦元素后面的背景元素⚠️
::marker选中 list 的 marker⚠️
  • 代表主流浏览器都支持(至少 95% 以上)
  • 代表大部分主浏览器都不支持(仅 20% 以下浏览器实现该特性)
  • ⚠️ 代表部分浏览器支持(可能需要加前缀,例如 :webkit-或 :-moz-等)

(参考自 juejin.cn/post/713608…)

使用伪元素可以增强页面的样式和布局,并提供更多的设计自由度,是CSS中非常有用的特性,用于创建各种效果和装饰。

什么是伪类?

伪类(pseudo-class)是 CSS 中选择器的一种,用于选择元素在特定状态或具有特定属性时的样式规则。它们可以根据元素的状态、位置、用户行为等进行选择,从而实现对元素的精细控制和样式化。

伪类使用单冒号(:)表示,例如 :hover、:active 和 :first-child 等。它们可以与选择器结合使用,用于选择特定的元素或元素的特定状态。

常见的伪类可以分为以下几类:

  1. 动态伪类:

    • :hover:鼠标悬停时应用样式
    • :active:元素被激活(鼠标按下)时应用样式
    • :focus:元素获取焦点时应用样式
    • :visited:已访问链接的样式
  2. 结构性伪类:

    • :first-child:选择父元素下的第一个子元素
    • :last-child:选择父元素下的最后一个子元素
    • :nth-child(n):选择父元素下的第n个子元素
    • :nth-last-child(n):选择父元素下的倒数第n个子元素
    • :nth-of-type(n):选择父元素下的第n个指定类型的子元素
    • :nth-last-of-type(n):选择父元素下的倒数第n个指定类型的子元素
    • :only-child:选择父元素下唯一的子元素
    • :only-of-type:选择父元素下唯一的指定类型的子元素
    • :empty:选择没有子元素或文本内容的空元素
  3. 状态伪类:

    • :enabled:选择可用的表单元素
    • :disabled:选择被禁用的表单元素
    • :checked:选择已选中的表单元素
  4. 其他伪类:

    • :not(selector):选择不匹配指定选择器的元素

    • :target:选择URL片段标识符(Hash)与当前URL匹配的元素

伪类可以根据元素的状态、结构或其他条件选择目标元素,并为其应用相应的样式,

通过使用不同的伪类组合和结合 CSS 选择器,可以实现对元素的精细控制和样式化。

如何获取伪元素

由于伪元素只存在于 CSS 渲染树中,仅用于样式化和装饰元素的特定部分,在渲染阶段被添加到渲染树中,并在最终的绘制阶段进行绘制。

所以 伪元素并不会在 DOM 树中增加额外的节点,也无法通过 js 去访问或操作伪元素。

那么我们是否可以通过 CSS 样式表去获取伪元素呢?

想要获取伪元素,可以通过 window.getComputedStyle() 获取到指定元素的计算样式对象,

当使用 getComputedStyle 方法时,它返回的是一个 CSSStyleDeclaration 对象,其中包含了指定元素的所有计算样式,包括伪元素的样式。

const element = document.getElementById("typewriter") as HTMLElement;
// 获取伪元素
const after = window.getComputedStyle(element, ":after");
after.display = "none";
console.log(after.display);

 // style 强制覆盖伪元素样式
element.innerHTML = "#typewriter::after{display:none}";

通过访问计算样式对象的属性来获取伪元素的具体样式值,

注意:伪元素的样式是只读的,只能用于获取伪元素的样式值,而不能用于修改它们。

获取元素属性值

在获取 CSS 样式声明对象后利用 getPropertyValue() 或 直接使用键值访问 来获取对应属性的值。

const element = document.getElementById("typewriter") as HTMLElement;
const after = window.getComputedStyle(element, ":after");
console.log(after.getPropertyValue("color"));    // rgb(0,0,0)
console.log(after.display);  // inline-block

到底什么是伪元素 ?

使用 getPropertyValue() 获取属性值会更加灵活,它可以获取任意 CSS 属性的值。

而直接使用键值访问则更适用于访问元素的 style 属性中的属性值,通常用于直接操作内联样式。

注意:伪元素默认的 display属性为 inline,但在设置 CSS 样式时可以手动修改其 display 属性为 block、inline-block 或 其他。

更改伪元素的样式

  1. 类名替换

在 CSS 中定义不同的 CSS 类名,并在 js 中通过添加或删除类名来改变伪元素的样式。

首先,在 CSS 样式表中定义类名对应的样式规则,

.element::before {
  /* 默认样式规则 */
}

.element.new-class::before {
  /* 新样式规则 */
}

.element.old-class::before {
  /* 旧样式规则 */
}

通过 JavaScript 来添加或移除这些类名,使得在不同类名下的伪元素样式发生变化

const element = document.querySelector('.element');
element.classList.add('new-class');
element.classList.remove('old-class');
  1. 使用 CSSStyleSheet 对象插入样式规则

通过对 CSSStyleSheet 对象插入 insertRule 方法来为伪元素插入新的样式规则。这个方法允许你动态地添加新的 CSS 规则到样式表中,包括针对伪元素的样式。

使用 insertRule 修改伪元素的样式:

const styleSheet = document.styleSheets[0]; // 获取文档的第一个样式表

// 定义插入的样式规则
const newRule = '.element::before { color: red; }';

// 使用 insertRule 方法将规则插入到样式表的末尾 并返回该规则在样式表中的索引位置
styleSheet.insertRule(newRule, styleSheet.cssRules.length);

// 注意:如果要修改伪元素的样式,确保已经定义了对应的伪元素样式规则

使用 insertRule 方法可以在运行时动态地修改伪元素的样式,提供了更大的灵活性。

然而,需要注意样式表的索引和规则的位置,以确保插入的样式规则被正确应用。

  1. 使用样式属性对象

通过修改元素的 style 属性来更改伪元素的样式。获取元素对象后,直接修改其 style 属性即可。

const element = document.querySelector('.element');
element.style.setProperty('--pseudo-element-color', 'red');

利用元素的行内属性来设置 CSS 变量定义伪元素的样式

.element::before {
color: var(--pseudo-element-color);
}

同样的利用这种方式可以实现伪元素中 content 的修改,就像开篇打字机效果设置的 data-attr 变量

通过行内属性改变伪元素的样式。

修改伪元素的样式,建议使用更换类名或利用 DOM 的动态属。

总结

伪元素的 content 属性很强大,除了插入文本和图像之外,还可以插入一些特殊的字符和符号。但是伪元素的内容只存在于 CSS 渲染树中,所以为了 SEO 优化,不要将重要的文本和信息放在伪元素中,可能会影响网站的可访问性和可读性,从而降低 SEO 的效果。在修改伪元素时,也建议使用更换类名或利用 DOM 的动态属性进行修改。

好啦,以上是目前我所了解的伪元素的内容啦,如果有新的发现我也会继续补充的,希望这些对你们也有所帮助,拜拜啦 !!!

参考

  1. 使用JS控制伪元素的几种方法
  2. 彻底搞懂 CSS 伪类和伪元素
转载自:https://juejin.cn/post/7242676549735465018
评论
请登录