w3c / w3c/csswg-drafts

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

Open
#4,745 30 comments 0 reactions 2 assignees View on GitHub

Nobody has claimed this yet.

web-animations-1 web-animations-css-integration
Dominant language
Bikeshed
Stars
4.9k
Forks
816
PR merge metrics
PR metrics pending

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.