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

Product Media Layout updates #937

Merged
merged 25 commits into from
Dec 16, 2021
Merged

Conversation

LucasLacerdaUX
Copy link
Contributor

@LucasLacerdaUX LucasLacerdaUX commented Nov 23, 2021

Why are these changes introduced?
Adds three new settings to product page:

  • Large screens layout
  • Media size
  • Mobile thumbnails

Closes #828.

What approach did you take?

  • Created a new MediaGallery component to manage the GalleryViewer. This component manages two sliders (gallery and thumbnails) and keeps them in sync. It also serves as an interface for other components, like VariantSwitch. Instead of changing the DOM directly, we now make this request via a setActiveMedia(media, prepend) function.
  • Thumbnails are implemented using a <slider-component>. This is different to the dots/numbers in the Slideshow component that @ludoboludo implemented on Slideshow section #840, because both thumbnails and viewer can be controlled separately. The same HTML is used for both Mobile and Desktop.

Setting 1: Large screens layout

  • Stacked: if sticky column setting is enabled, info column is sticky.
  • Thumbnails: if sticky column setting is enabled, media column is sticky. Will limit the height of media.

Setting 2: Media size

  • Small: 45% media / 55% content. 4 thumbnails per row. 20x20 thumbnail badges. 500px maximum height if Thumbnails layout is set.
  • Medium: 55% media / 45% content. 5 thumbnails per row. 30x30 thumbnail badges. 600px maximum height if Thumbnails layout is set.
  • Large: 65% media / 35% content. 6 thumbnails per row. 30x30 thumbnail badges. 600px maximum height if Thumbnails layout is set.

Setting 3: Mobile thumbnails

  • Hide will use < 1/3 > format for slider.
  • Show can be enabled independently from the Large screens layout setting. Uses the same Thumbnails component, but inside a slider. Pressing the next/prev button will scroll 3 slides at a time. If user scrolls the main gallery slider, the thumbnail slider will be kept in sync.

Accessibility:

  • Thumbnails (button) have a aria-controls="GalleryViewer-{{ section.id }}" and are labelled (via aria-label) depending on the media type:
    • Images: Load image {{ index }} in gallery view
    • 3D Models: Load 3D Model {{ index }} in gallery view
    • Videos: Play video {{ index }} in gallery view
  • If set to Thumbnails mode, the gallery viewer will have a <h2>Gallery Viewer</h2> at the top.
  • When you click on a Thumbnail:
    • If it's a video or 3D Model, it will autoplay.
    • If it's an image, a role="status" div will receive Image {{ index }} is now available in gallery view once the <img> is loaded for the first time.

Demo links

Checklist

@LucasLacerdaUX LucasLacerdaUX changed the title [Draft] Product Media Layout updates Product Media Layout updates Nov 25, 2021
@LucasLacerdaUX LucasLacerdaUX marked this pull request as ready for review November 25, 2021 05:49
Copy link
Contributor

@ludoboludo ludoboludo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good. Found the code nice to read as well 👌

Tested quite a few scenarios and left a few notes on what I noticed.

assets/global.js Outdated
onButtonClick(event) {
event.preventDefault();
const slideScrollPosition = event.currentTarget.name === 'next' ? this.slider.scrollLeft + this.sliderLastItem.clientWidth : this.slider.scrollLeft - this.sliderLastItem.clientWidth;
const step = event.currentTarget.dataset.step || 1;
const slideScrollPosition = event.currentTarget.name === 'next' ? this.slider.scrollLeft + (step * this.sliderLastItem.clientWidth) : this.slider.scrollLeft - (step * this.sliderLastItem.clientWidth);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a bit of a delay happening sometimes between the thumbnail sliding to the currently active image: video

Copy link
Contributor Author

@LucasLacerdaUX LucasLacerdaUX Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea how to fix this without a big refactor on the slider component.

I don't think it should be a blocker, though. Would it be okay to solve this on follow up PRs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah! not a blocker at all 👍

@tyleralsbury tyleralsbury self-requested a review November 26, 2021 15:18
@svinkle
Copy link
Member

svinkle commented Nov 26, 2021

Initial Desktop first-pass observations:

  1. On first click of a video, focus shifts to the video or related iframe element. Subsequent clicks do not shift focus. Focus should remain on the thumbnail button.

  2. Each media type should have its own index. This helps to provide accurate control accessible naming.

    Ex., tabbing through thumbnail controls with mixed media (2 images, then a video, then another image, then a 3D model) would ideally announce:

    🗣 "Load image 1 in gallery view Tab Load image 2 in gallery view Tab Play video 1 in gallery view Tab Load image 3 in gallery view Tab Load 3D Model 1 in gallery view"

  3. The gallery viewer markup in this view needs some adjustment. It doesn't make sense to reuse the list structure for the gallery view since there will ever only be 1 list item presented at a time.

    When the conditions of the Thumbnail layout and desktop viewport are true, inside the slider-component element, remove semantic meaning by applying role="presentation" to the ul and each li.

  4. The heading I suggested in Figma throws off the heading order. Let's remove this but instead, create a landmark for the gallery viewer.

    Add aria-label="Gallery viewer" and role="region" to the media-gallery component.

  5. I see the role="status" in the DOM but I don't see any updates being pushed to this element. I believe there should be something pushed for when an image has loaded?

Copy link
Contributor

@tyleralsbury tyleralsbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a quick pass on the code, this is looking really great. I only have one comment so far, plus the vid I sent you on Slack. Great catches by Ludo as well. 👍

Comment on lines 79 to 85
srcset="{% if media.preview_image.width >= 288 %}{{ media.preview_image | img_url: '288x' }} 288w,{% endif %}
{% if media.preview_image.width >= 576 %}{{ media.preview_image | img_url: '576x' }} 576w,{% endif %}
{% if media.preview_image.width >= 750 %}{{ media.preview_image | img_url: '750x' }} 750w,{% endif %}
{% if media.preview_image.width >= 1100 %}{{ media.preview_image | img_url: '1100x' }} 1100w,{% endif %}
{% if media.preview_image.width >= 1500 %}{{ media.preview_image | img_url: '1500x' }} 1500w,{% endif %}
{{ media.preview_image | img_url: 'master' }} {{ media.preview_image.width }}w"
src="{{ media | img_url: '1500x' }}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will need to be a multiplier on the values in the gallery for optimal desktop image sizes dependent on the width of the gallery. Ping me if you want details, but for example... if the original width of the container was 50% and an image size for that is 1000, and the setting is now 60%, the image needs to be 1200 when that setting is selected.

I think it will take some assigns, unfortuantely.

@svinkle
Copy link
Member

svinkle commented Nov 29, 2021

After adding alt text to the thumbnails on this page, I realize each thumbnail control has very little context to what is actually being loaded into the viewer.

I'd like to propose including hint text onto each button. Add the aria-describedby attribute on each, referencing the id of its image thumbnail.

<button
  class="thumbnail thumbnail--narrow"
  aria-label="{btn.label}"
  aria-controls="GalleryViewer-template--15085127434262__main"
  aria-describedby="thumbnail-{i}"
>
  <img
    id="thumbnail-{i}"
    src="{img.src}}"
    alt="{img.alt}"
    height="200"
    width="200"
    
  />
</button>

With this screen readers will announce:

🗣 "Load image {i} into gallery viewer, button, {img.alt}"

@svinkle
Copy link
Member

svinkle commented Nov 29, 2021

In addition to the desktop review, here's some notes on the mobile experience:

  • When swiping through ul.product__media-list, each item was loaded into the gallery viewer. Ideally items would be hidden until a thumbnail control has been activated revealing the media (similar to how desktop behaves.)
  • Each gallery viewer button.product__media-toggle includes a generic "open media {i}" label. Ideally these would be updated to reference the media type and its unique type index, as on the desktop view. (Load image, play video, load 3D model, etc.)

@svinkle
Copy link
Member

svinkle commented Nov 30, 2021

Product images are not visible in Windows Hight Contrast mode in Firefox. Adjust the CSS of the button to use the :after pseudo element. Review the product card CSS as an example.

Dawn product page in Windows Hight Contrast mode in Firefox. Gallery viewer is an empty black area.

Copy link

@duygukalaycioglu duygukalaycioglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Decrease the spacing below the image and the thumbnails on mobile.

spacing on mobile

  • When the thumbnails are hidden, decrease the spacing above the product title on mobile.

thumbnails hidden - spacing

Thanks!

@katycobb
Copy link
Contributor

katycobb commented Dec 7, 2021

Hi @LucasLacerdaUX I've been working with @duygukalaycioglu to make some content updates. They're reflected in the Figma file + listed below. Let me know if you need more info, and D let me know if there's anything I've missed!

  • Checkbox copy: Enable sticky content on desktop
  • Large screens layout --> Desktop layout
  • Add help text below Desktop layout: Thumbnails is the default mobile layout.
  • Media size --> Desktop media size
  • Add help text below Desktop media size: Media is automatically optimized for mobile.

@LucasLacerdaUX
Copy link
Contributor Author

LucasLacerdaUX commented Dec 7, 2021

@katycobb @duygukalaycioglu I have a question about:

Thumbnails is the default mobile layout.

Does that mean we are changing Mobile thumbnails default from Hide to Show? Right now, the default is Hide.

image

Even if we are updating that setting's default, the closest option to the default mobile experience is actually Thumbnail carousel, not Thumbnails 👀

@katycobb
Copy link
Contributor

katycobb commented Dec 7, 2021

@LucasLacerdaUX oof, good question. @duygukalaycioglu let's chat about this!

@katycobb
Copy link
Contributor

katycobb commented Dec 7, 2021

@LucasLacerdaUX I connected with @duygukalaycioglu: we'll update the help text to Thumbnails is the default mobile layout.

No change to the mobile thumbnail default needed!

@LucasLacerdaUX
Copy link
Contributor Author

@katycobb Not sure if I understand? The help text looks the same as before? 👀

@LucasLacerdaUX
Copy link
Contributor Author

LucasLacerdaUX commented Dec 8, 2021

I pushed a few updates to the branch. I've addressed most of the comments from reviewers, except for the thumbnail sizing logic (will look into that tomorrow) and some minor bugs. Hopefully this will be fully ready for new reviews tomorrow morning.

The new demo links are:
Preview Links
Theme Editor


Accessibility updates

cc @svinkle

Fixed

  • Clicking a thumbnail will always announce that the image is loaded.
  • The Gallery Viewer title is now applied to the media-gallery component via aria-label and role="region" instead of being an <h2>
  • If thumbnails are enabled and we're using desktop viewport, role="presentation" is applied to the <ul> and all <li> in the Gallery Viewer. (Edit: just found a bug. If you set it to Stacked but enable Mobile thumbnails, it'll apply the role="presentation" on the stacked list. I'll fix tomorrow)
  • aria-describedby was added to thumbnail buttons, linking them to the img element.
  • Each media type now has its own index.
  • Firefox - Windows High Contrast mode fixed by styling the ::after pseudoelement instead of the button :)

Not addressed

On first click of a video, focus shifts to the video or related iframe element. Subsequent clicks do not shift focus. Focus should remain on the thumbnail button.

Unfortunately, this seems to be caused by YouTube's video player. I couldn't find a way to prevent this autofocus. Will keep looking for a solution.

Mobile: When swiping through ul.product__media-list, each item was loaded into the gallery viewer. Ideally items would be hidden until a thumbnail control has been activated revealing the media (similar to how desktop behaves.)

Hmm. When you say hidden, do you mean visually hidden or are we talking about aria-hidden / removing tabindex when not in focus?

If we are considering visually hiding the invisible elements like we do on desktop, can you add more on the rationale behind this so we can discuss this with designers? This would limit the current UX as it would no longer allow mobile users to navigate through the media via swipe gestures.


New decisions

  • We'll no longer automatically scroll to the media when using the thumbnails layout. This reduces content jumping and provides a more consistent user experience. The (keyboard) focus remains on the thumbnails.
  • Height limitation was removed from the Thumbnails layout to avoid empty gaps / wasted space when using portrait images.
  • A new Thumbnails carousel option was added. This allows merchants to use the same mobile carousel for the thumbnails on the desktop viewport.
  • Media are now vertically centered on mobile to reduce the gap between controls when there's a significant variation in media sizes.

@svinkle
Copy link
Member

svinkle commented Dec 8, 2021

@LucasLacerdaUX

Clicking a thumbnail will always announce that the image is loaded.

Confirmed. New issue being this text can be found when navigating via virtual cursor. If you can set a timeout to clear #GalleryStatus after a couple seconds that'd be great.

The Gallery Viewer title is now applied to the media-gallery component via aria-label and role="region" instead of being an <h2>

Confirmed.

If thumbnails are enabled and we're using desktop viewport, role="presentation" is applied to the <ul> and all <li> in the Gallery Viewer.

Confirmed on desktop and mobile for the thumbnail view. Although, now that I'm aware of the swipe feature on mobile (see note below) I'd say this would apply to desktop only. Is this possible?

aria-describedby was added to thumbnail buttons, linking them to the img element.

Confirmed.

Each media type now has its own index.

Confirmed, though image type seems to start at 0. Let's start at 1.

Firefox - Windows High Contrast mode fixed by styling the ::after pseudoelement instead of the button :)

Confirmed. New issue being the focus ring is placed below and to the left of the larger image in the gallery viewer. Seems to be images only. Please review.

Unfortunately, this seems to be caused by YouTube's video player.

Thanks for looking into this. It seems to be true for hosted, non YouTube video as well.

This would limit the current UX as it would no longer allow mobile users to navigate through the media via swipe gestures.

Ah, no worries. I didn't realize the swipe feature existed. With this context in mind, ignore my original comment.

@katycobb
Copy link
Contributor

katycobb commented Dec 8, 2021

Hi @LucasLacerdaUX: Melissa, D and I connected and aligned on the behavior of this section and have made some content updates we think will better describe the settings. Let me know if this makes sense given your feedback and knowledge of the section!

  • Remove help text under Desktop layout
  • Rename Mobile thumbnails field label to Mobile layout
  • Update options under Mobile layout to: Show thumbnails and Hide thumbnails

cc: @duygukalaycioglu and @melissaperreault

@LucasLacerdaUX
Copy link
Contributor Author

LucasLacerdaUX commented Dec 9, 2021

@svinkle

Demo links

Confirmed. New issue being this text can be found when navigating via virtual cursor. If you can set a timeout to clear #GalleryStatus after a couple seconds that'd be great.

I've followed the aria-hidden => true pattern we've used in other components. Does that work? Let me know if you would prefer setting its content to empty instead.

Confirmed on desktop and mobile for the thumbnail view. Although, now that I'm aware of the swipe feature on mobile (see note below) I'd say this would apply to desktop only. Is this possible?

Updated. It now checks if the component is using a non stacked layout (thumbnails or thumbnails carousel) and if the viewport width is >750px.

Confirmed, though image type seems to start at 0. Let's start at 1.

Fixed! It now starts at 1 for every media type.

Confirmed. New issue being the focus ring is placed below and to the left of the larger image in the gallery viewer. Seems to be images only. Please review.

Is this issue restricted to when we are using VoiceOver / another assistive technology? Or does it also happen with the browser's regular focus ring? This is what the (browser's) keyboard focus ring looks like for me:

However, VoiceOver definitely shows an additional ring around the button element:

This duplicated focus ring also happens on the product card, which I based this solution on. However, in that case, we have the product title inside the full-size link (the one with that uses the ::after trick):

Do you have any ideas on how I could solve this for product images without breaking High Contrast Mode? If I set the button to wrap the entire image, we'll end up with the same issue we originally had before applying the ::after.

Thanks for looking into this. It seems to be true for hosted, non YouTube video as well.

Oh, you're right! That's why I was unable to get it fixed for YouTube 🤦 We had a .focus() when initializing ANY deferred media (models, videos and external videos).

Fixed. The focus now remains on the thumbnail regardless of the media type you select.


@katycobb Thanks for the update! Looks perfect to me now!

Demo links

@svinkle
Copy link
Member

svinkle commented Dec 9, 2021

@LucasLacerdaUX

I've followed the aria-hidden => true pattern

Confirmed. 👍

It now checks if the component is using a non stacked layout

Looks good.

Is this issue restricted to when we are using VoiceOver

Seems to be Safari only, when using Tab.

Screenshot Dawn product page. Product image in gallery view features small focus ring in bottom left corner.

The focus now remains on the thumbnail regardless of the media type you select.

Confirmed.

@LucasLacerdaUX LucasLacerdaUX force-pushed the product-media-layout-updates branch from a3349c4 to 23b1e24 Compare December 13, 2021 16:51
@LucasLacerdaUX LucasLacerdaUX force-pushed the product-media-layout-updates branch from 18d5eee to 56a370e Compare December 14, 2021 21:03
@LucasLacerdaUX
Copy link
Contributor Author

Seems to be Safari only, when using Tab.

Should be fixed now! Thanks, @svinkle.

@LucasLacerdaUX
Copy link
Contributor Author

PR is ready for final reviews.

Thumbnails / image srcset will be updated later this morning, but I would suggest to review everything else in the meantime :)

cc @tyleralsbury @ludoboludo @duygukalaycioglu

Copy link

@duygukalaycioglu duygukalaycioglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great!!

Copy link
Contributor

@ludoboludo ludoboludo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking very nice 👌

Left a few comments of things I noticed. Nothing major though 🤔

"label": "t:sections.main-product.settings.gallery_layout.options__2.label"
},
{
"value": "thumbnail_slider",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should had an info here. But it might be overkill and self explanatory anyway:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! I think it is self explanatory but a good candidate for help doc precisions.

.product--thumbnail .product__media-gallery,
.product--thumbnail_slider .product__media-gallery,
.product--stacked .product__info-container--sticky {
display: block;
position: sticky;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I notice here with position sticky on the media gallery is that it makes it a bit annoying to get to see the video: video

Copy link
Contributor

@melissaperreault melissaperreault Dec 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, this is interesting. A few things come to mind:

  • This is not only impacting videos but any media in a landscape ratio
  • This is not something that was concerning with the stacked layout because we had more vertical visuals to view
  • Since merchants can deactivate the Enable sticky header setting and the other one, I am not too concerned. That behaviour is not meant for all instances and this is the reason why the settings exist.
  • Our defaults set merchants for success if they remain with the Stacked layout.

@LucasLacerdaUX
Copy link
Contributor Author

LucasLacerdaUX commented Dec 15, 2021

@ludoboludo and @tyleralsbury Image sizes have been updated for both main media, deferred-media posters and thumbnails :)

I've also addressed all of Ludo's comments about code. This should be ready for a final review.

}

removeListSemantic() {
this.elements.viewer.slider.setAttribute('role', 'presentation');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do sometimes get an error in the console but I think it only happens in the theme editor before you hit Save: screenshot

ludoboludo
ludoboludo previously approved these changes Dec 16, 2021
Copy link
Contributor

@ludoboludo ludoboludo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted maybe one thing that could be changed in the PR. The vertical alignment of the thumbnail slider buttons. Otherwise didn't notice any other issues.

}
if (!this.elements.thumbnails || this.dataset.desktopLayout === 'stacked') {
activeMedia.scrollIntoView({behavior: 'smooth'});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda feel like it's nice to have it scroll back to the top of the media being opened. But I guess it's weird to keep focus on the thumbnail button and potentially have it outside of the viewport 🤔

This can be a follow up conversation anyway. Not a blocker and quick fix if needed.
video

ccing @melissaperreault for future conversation on this.

Comment on lines +1 to +2
if (!customElements.get('media-gallery')) {
customElements.define('media-gallery', class MediaGallery extends HTMLElement {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever. Using this approach we might even be able to inline some of our smaller custom elements. Keeping this one in the back of my mind for asset management ideas.

Copy link
Contributor

@tyleralsbury tyleralsbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - I gave it some tests and looked again at the code. 🚢

@LucasLacerdaUX LucasLacerdaUX merged commit 639d839 into main Dec 16, 2021
@LucasLacerdaUX LucasLacerdaUX deleted the product-media-layout-updates branch December 16, 2021 19:44
phapsidesGT pushed a commit to Gravytrain-UK/gt-shopify-dawn-theme that referenced this pull request Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Product template media layout update
7 participants