Description
I'm not sure the spec is clear about what the animation target is if pseudoElement
is not null
.
Consider these two tests in web-animations/interfaces/Animatable/animate.html for instance:
test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
getComputedStyle(div,"::before").content; // Sync style
const anim = div.animate(null, {pseudoElement: '::before'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::before',
'The returned Animation targets the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'the correct pseudo-element');
test(t => {
const div = createDiv(t);
const anim = div.animate(null, {pseudoElement: '::before'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::before',
'The returned Animation targets the correct selector');
}, 'animate() with pseudoElement without content creates an Animation object targeting ' +
'the correct pseudo-element');
In the first example, I understand what's happening: the target element has a ::before
pseudo-element with content and it's created before Element.animate()
is called. It seems clear that the animation target is the ::before
pseudo-element.
In the second example, I'm not so sure. When Element.animate()
is called the target div
has no ::before
pseudo-element. So what is the effective target of that animation? Does it actually target any element? What if the animation starts and the div
gets a ::before
pseudo-element? Does the animation then affects that element?
I guess my question is whether we need a targeted pseudo-element to exist when the API tries to reference it, or if it's all resolved live.
Similarly, I'm confused by this test in web-animations/interfaces/Animation/commitStyles.html:
test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
const animation = div.animate(
{ opacity: 0 },
{ duration: 1, fill: 'forwards', pseudoElement: '::before' }
);
assert_throws_dom('NoModificationAllowedError', () => {
animation.commitStyles();
});
}, 'Throws if the target element is a pseudo element');
At the time Animation.animate()
is called, style resolution has not happened yet and there is no ::before
pseudo-element for div
. However, there would be when Animation.commitStyles()
is called.
Up until pseudoElement
was added, it was clear whether an animation was targeting something, because you'd have to pass a value to KeyframeEffect.target
. Now that the target is specified across a pair of properties without a direct reference to an Element
, it's not as clear.