Skip to content

[web-animations-1] Clarification about target and pseudoElement relationship #4745

Open
@graouts

Description

@graouts

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions