Jump to content
Search Community

gsap.from with autoAlpha breaks keyboard navigation

CoreMarketing test
Moderator Tag

Go to solution Solved by mvaneijgen,

Recommended Posts

As the title says really — when I try to use gsap.from with autoAlpha, I'm unable to tab through the links inside each panel.

 

Try with the demo: Open in full page view and then try to tab through the links. You should be able to tab through Panel #1, Link #1 and Link #2, but Panel #2 is not accessible by keyboard. If you first scroll down so that the animation plays, you can then tab through all links as normal.

 

For this demo I've added:

.animated > * {
  visibility: hidden;
}

to prevent the animation from 'flickering' (the animated element was visible in its base state for a split second before the animation moved it to the from state).

 

If you remove this, a different, but similar, issue presents itself. Now you can tab from panel to panel, but as soon as Link #1 is focused, the animation plays and resets the focus back to the body. Pressing tab again focuses Link #2.

 

This seems to be because visibility: hidden removes any interactivity from the element and autoAlpha sets this behind the scenes. Once the element has animated, that CSS is no longer set so the links can be navigated normally.

 

Is there a way to achieve this effect while keeping full keyboard navigation?

See the Pen bGMwLXm by IAmAdamTaylor (@IAmAdamTaylor) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @CoreMarketing welcome to the forum!

 

If `autoAlpha` doesn't fit your solution, then don't use it, right? Instead use any of the other properties that will hide your element, but that doesn't disable interactivity. eg `opacity`,  `scale`,  `translate`, just pick the one that does fit your solution. 

 

Quote

autoAlpha

Identical to opacity except that when the value hits 0 the visibility property will be set to hidden in order to improve browser rendering performance and prevent clicks/interactivity on the target. When the value is anything other than 0, visibility will be set to inherit. It is not set to visible in order to honor inheritance (imagine the parent element is hidden - setting the child to visible explicitly would cause it to appear when that’s probably not what was intended). And for convenience, if the element’s visibility is initially set to hidden and opacity is 1, it will assume opacity should also start at 0. This makes it simple to start things out on your page as invisible (set your CSS visibility: hidden) and then fade them in whenever you want.

https://greensock.com/docs/v3/GSAP/CorePlugins/CSSPlugin

  • Like 2
Link to comment
Share on other sites

Hi,

 

An alternative is to add this in the CSS:

.animated > * {
  opacity: 0;
}

And in the JS use this to prevent the flash before your JS runs:

ScrollTrigger.batch('.animated', {
  once: true,
  onEnter: batch => {
    batch.forEach((item, index) => {
      gsap.set(item.children, { autoAlpha: 1 });
      gsap.from(item.children, {
        y: 75,
        stagger: 0.15,
        autoAlpha: 0,
        clearProps: "transform"
      })
    })
  },
  onEnterBack: batch => {
    batch.forEach((item, index) => {
      gsap.to(item.children, {
        autoAlpha: 1,
        stagger: 0.05
      })
    })
  },
});

Another option is to use a fromTo instance:

ScrollTrigger.batch('.animated', {
  once: true,
  onEnter: batch => {
    batch.forEach((item, index) => {
      gsap.fromTo(item.children, {
        y: 75,
        autoAlpha: 0,
        clearProps: "transform"
      }, {
        y: 0,
        stagger: 0.15,
        autoAlpha: 1,
      })
    })
  },
  onEnterBack: batch => {
    batch.forEach((item, index) => {
      gsap.to(item.children, {
        autoAlpha: 1,
        stagger: 0.05
      })
    })
  },
});

Happy Tweening!!!

Link to comment
Share on other sites

Thanks both!

 

I swear I'd tried with opacity multiple ways and hadn't found a result that solved all problems, but of course after trying again it's working perfectly now 😀

 

Final solution below if anyones looking at this.

 

Remove any initial CSS styling, in this case get rid of:

.animated > * {
  visibility: hidden;
}

 

Then in the JavaScript:

gsap.utils.toArray(".animated").forEach((elem, index) => {
	gsap.set(elem.children, {
		opacity: 0,
	});

	ScrollTrigger.create({
		trigger: elem,
		once: true,
		start: 'top 90%',
		onEnter: () => {
			gsap.fromTo(elem.children, {
				y: 75,
				opacity: 0
			}, {
				y: 0,
				stagger: 0.15,
				opacity: 1,
				clearProps: "transform,opacity"
			});
		},
		onEnterBack: () => {
			gsap.to(elem.children, {
				duration: 0.3,
				opacity: 1,
				stagger: 0.05
			});
		}
	});
});

Note: Switching from a batch to a create seemed to help fix some of the final issues

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...