如何为 html ::selection background-color 设置动画?

How to animate html ::selection background-color?

我想用类似于色调旋转动画的方式为 ::selection 背景颜色设置动画。由于 ::selection 背景 属性 只能包含颜色或变量,我假设应该以某种方式对包含颜色的 ::root 变量进行动画处理,但我不知道如何对可以动画的内容进行动画处理'没有 class.

也许有一个简单的 JS 解决方案,我现在可能忽略了。

首选 Vanilla JS 解决方案

可以肯定这是不可能的。 ::selection 伪不接受 animation-* 属性 (see MDN)

Only certain CSS properties can be used with ::selection:

  • color
  • background-color
  • cursor
  • caret-color
  • outline and its longhands
  • text-decoration and its associated properties
  • text-emphasis-color
  • text-shadow

这让我觉得这是不可能的。我们可以用 ::after 等其他伪代码来做到这一点,但每当我 select 文本时,它的背景颜色都不会改变。

.something {
  background-color: blue;
}

.something::selection {
  color: white;
  
  animation-duration: 3s;
  animation-name: colorize;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

.something::after {
  content: "after";
  display: inline-block;
  width: 50px;
  height: 50px;
  
  animation-duration: 3s;
  animation-name: colorize;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@keyframes colorize {
  from {
    background-color: green;
  }
  to {
    background-color: red;
  }
}
<span class="something">Hello</span>


即使尝试不断更新 CSS custom property 并“手动”为其设置动画似乎也不起作用,因为 selection 属性 在突出显示时不会更新.例如,您可以 select “Hello World!”文本,你应该看到每次突出显示时红色值都会改变,但不会 它会突出显示。

const thing = document.getElementById("thing");

let r = 0;
const loop = () => {
  thing.style.setProperty("--color", `rgb(${r}, 0, 0)`);
  r++;
  if (r > 255) {
    r = 0;
  }
  requestAnimationFrame(loop);
};

requestAnimationFrame(loop);
:root {
  --color: red;
}

#thing::selection {
  background-color: var(--color, black);
}
<div id="thing">Hello world!</div>

这在 chrome 和 firefox 中有效,但在 safari 中无效:


let r = 0;
const loop = () => {
var html = document.getElementsByTagName("html")[0];
  html.style.setProperty("--changing", `hsla(${r}, 50%, 50%, 0.999)`);
  r++;
 
  requestAnimationFrame(loop);
};

requestAnimationFrame(loop);