Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating an Accessible Image Carousel #166

Open
AleksandrHovhannisyan opened this issue Jun 23, 2022 · 10 comments
Open

Creating an Accessible Image Carousel #166

AleksandrHovhannisyan opened this issue Jun 23, 2022 · 10 comments
Labels
comments Comments section for an article.

Comments

@AleksandrHovhannisyan
Copy link
Owner

No description provided.

@AleksandrHovhannisyan AleksandrHovhannisyan added the comments Comments section for an article. label Jun 23, 2022
@sandersu
Copy link

sandersu commented Aug 16, 2022

Hi Alexander,

Firstly, great article. There was only one thing I found that wasn't correct in your article.

For improved performance, I’m also using the loading="lazy" attribute to enable native lazy loading, which defers loading images that aren’t currently visible. Once we enable overflow scrolling with CSS in a future section, this will defer loading images that are overflowing horizontally beyond the carousel’s client window.

By setting loading=lazy, all images with this attribute will be loaded later. This should only be applied to images that are offscreen.

Therefore, if you are using the carousel in the first view, this attribute should only be set on the + 4th images. Otherwise it will also defer the loading of images 1, 2 & 3.

Your scroll snap problem is probably also caused by this.

Regards,

Sander van Surksum

@AleksandrHovhannisyan
Copy link
Owner Author

@sandersu Thanks for the feedback!

I didn't want to get into the details of how loading="lazy" works to keep the article focused, but to clarify: Browsers use a certain threshold from the viewport to detect whether an image should be loaded into view. You can find the thresholds for Chrome in this article: https://web.dev/browser-level-image-lazy-loading/#distance-from-viewport-thresholds. This also applies to scroll containers.

If the carousel is in view on page load and you inspect the network tab, you should see that only the first two images or so get requested (the bottom two images in the following screenshot):

Inspecting network requests for a page load, with a horizontal image carousel in view. Only two images are requested.

Once you scroll the carousel, the remaining images get requested:

Inspecting network requests for a page load, with a horizontal image carousel in view that has been scrolled to the right. Two additional images are requested.

@sandersu
Copy link

@sandersu Thanks for the feedback!

I didn't want to get into the details of how loading="lazy" works to keep the article focused, but to clarify: Browsers use a certain threshold from the viewport to detect whether an image should be loaded into view. You can find the thresholds for Chrome in this article: https://web.dev/browser-level-image-lazy-loading/#distance-from-viewport-thresholds. This also applies to scroll containers.

If the carousel is in view on page load and you inspect the network tab, you should see that only the first two images or so get requested (the bottom two images in the following screenshot):

Inspecting network requests for a page load, with a horizontal image carousel in view. Only two images are requested.

Once you scroll the carousel, the remaining images get requested:

Inspecting network requests for a page load, with a horizontal image carousel in view that has been scrolled to the right. Two additional images are requested.

The problem lies in the fact that the browser has to detect whether an image is in the viewport, which takes time. Because the browser has to wait until the IntersectionObserver is available.

Generally, do not lazy load images images visible in the viewport

See this comparison between lazy in viewport vs non lazy in viewport.

https://www.webpagetest.org/video/compare.php?tests=220817_BiDc5N_9MT%2C220817_AiDcGV_9PB&thumbSize=200&ival=100&end=visual

Also see
https://web.dev/browser-level-image-lazy-loading/#avoid-lazy-loading-images-that-are-in-the-first-visible-viewport

@AleksandrHovhannisyan
Copy link
Owner Author

Generally, do not lazy load images images visible in the viewport

@sandersu Yup, this is a good point! I had to do that at one point on my own site because Lighthouse was flagging it (LCP images were lazily loaded). If you have control over your carousel (i.e., users aren't uploading dynamic images), and you have control over where on a page it is positioned, it's definitely worth taking this into consideration.

@shyke
Copy link

shyke commented Dec 27, 2022

Hi Alexander
Thanks for the wonderful article. It helped me a lot.
I can't seem to find any way to set the initial scrolLeft value on the scrolable container (this.scrollContainer).
The value always stays 0 (RTL), no matter how I set the value in the class. The only solution I could find for it was to change the value in the window.load event listener. However, the result is that the gallery scrolls upon load. This isn't what I want.
Can you please explain how to set the scrollable position of the gallery to the center in the class constructor ?

@AleksandrHovhannisyan
Copy link
Owner Author

@shyke I should've probably clarified this in the article, but scrollLeft is a bit of a misnomer in the DOM. It should really be called scrollStart. In RTL, scrollLeft will be 0 if the container has not been scrolled. Once you start scrolling, the values increase in magnitude but will be negative. I'd recommend taking a look at the CodePen demo linked in the article: https://codepen.io/AleksandrHovhannisyan/pen/zYRVoeb.

@shyke
Copy link

shyke commented Dec 29, 2022 via email

@AleksandrHovhannisyan
Copy link
Owner Author

@shyke Oh, I see. I don't think it's possible to programmatically center the carousel on a particular image initially without the user noticing. There's no CSS solution for this that I know of, so you'd need to scroll to that image on window load like you said.

@Pooja22singh
Copy link

Hey @AleksandrHovhannisyan Great article!!, I was wondering since you followed the approach of disabling the
previous next buttons , How
would you change the solution to adapt a continous scroll, ie on last image click it scrolls to first and vice-versa

@AleksandrHovhannisyan
Copy link
Owner Author

@Pooja22singh I wouldn't recommend taking that approach, as it could confuse users who normally expect the next button to take them to the next image (e.g., an image to the right).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comments Comments section for an article.
Projects
None yet
Development

No branches or pull requests

4 participants