-
Notifications
You must be signed in to change notification settings - Fork 219
Fix: skewed placeholder of product image - issue#7553 #7651
Changes from 7 commits
82db041
1993312
c3a374c
d44008a
9f3677a
4763d7f
4004875
826f1d1
a8d13c8
20eef31
51434e5
53b608f
794b9ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,7 +62,10 @@ describe( 'Product Image Block', () => { | |
describe( 'with product link', () => { | ||
test( 'should render an anchor with the product image', () => { | ||
const component = render( | ||
<ProductDataContextProvider product={ productWithImages }> | ||
<ProductDataContextProvider | ||
product={ productWithImages } | ||
isLoading={ false } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you clarify why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure! I added
TS fixes/improvements were added as an extra to this PR and are not required as a fix for issue. I gathered them in a separate commit, but maybe I should've added it as a separate PR to avoid confusion. Let me know the way forward 🙌 |
||
> | ||
<Block showProductLink={ true } /> | ||
</ProductDataContextProvider> | ||
); | ||
|
@@ -79,14 +82,17 @@ describe( 'Product Image Block', () => { | |
); | ||
|
||
const anchor = productImage.closest( 'a' ); | ||
expect( anchor.getAttribute( 'href' ) ).toBe( | ||
expect( anchor?.getAttribute( 'href' ) ).toBe( | ||
productWithImages.permalink | ||
); | ||
} ); | ||
|
||
test( 'should render an anchor with the placeholder image', () => { | ||
const component = render( | ||
<ProductDataContextProvider product={ productWithoutImages }> | ||
<ProductDataContextProvider | ||
product={ productWithoutImages } | ||
isLoading={ false } | ||
> | ||
<Block showProductLink={ true } /> | ||
</ProductDataContextProvider> | ||
); | ||
|
@@ -97,10 +103,10 @@ describe( 'Product Image Block', () => { | |
); | ||
|
||
const anchor = placeholderImage.closest( 'a' ); | ||
expect( anchor.getAttribute( 'href' ) ).toBe( | ||
expect( anchor?.getAttribute( 'href' ) ).toBe( | ||
productWithoutImages.permalink | ||
); | ||
expect( anchor.getAttribute( 'aria-label' ) ).toBe( | ||
expect( anchor?.getAttribute( 'aria-label' ) ).toBe( | ||
`Link to ${ productWithoutImages.name }` | ||
); | ||
} ); | ||
|
@@ -109,7 +115,10 @@ describe( 'Product Image Block', () => { | |
describe( 'without product link', () => { | ||
test( 'should render the product image without an anchor wrapper', () => { | ||
const component = render( | ||
<ProductDataContextProvider product={ productWithImages }> | ||
<ProductDataContextProvider | ||
product={ productWithImages } | ||
isLoading={ false } | ||
> | ||
<Block showProductLink={ false } /> | ||
</ProductDataContextProvider> | ||
); | ||
|
@@ -129,7 +138,10 @@ describe( 'Product Image Block', () => { | |
|
||
test( 'should render the placeholder image without an anchor wrapper', () => { | ||
const component = render( | ||
<ProductDataContextProvider product={ productWithoutImages }> | ||
<ProductDataContextProvider | ||
product={ productWithoutImages } | ||
isLoading={ false } | ||
> | ||
<Block showProductLink={ false } /> | ||
</ProductDataContextProvider> | ||
); | ||
|
@@ -143,4 +155,24 @@ describe( 'Product Image Block', () => { | |
expect( anchor ).toBe( null ); | ||
} ); | ||
} ); | ||
|
||
describe( 'without image', () => { | ||
test( 'should render the placeholder with no inline width or height attributes', () => { | ||
const component = render( | ||
<ProductDataContextProvider | ||
product={ productWithoutImages } | ||
isLoading={ false } | ||
> | ||
<Block showProductLink={ true } /> | ||
</ProductDataContextProvider> | ||
); | ||
|
||
const placeholderImage = component.getByAltText( '' ); | ||
expect( placeholderImage.getAttribute( 'src' ) ).toBe( | ||
'placeholder.jpg' | ||
); | ||
expect( placeholderImage.getAttribute( 'width' ) ).toBe( null ); | ||
expect( placeholderImage.getAttribute( 'height' ) ).toBe( null ); | ||
} ); | ||
} ); | ||
} ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that
alt
prop was already empty before, but I'm wondering if it would be better to add some text to explicitly say it is a placeholder image instead. What do you think?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super-duper agreed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this suggestion! I was thinking about that, but then in a test I spotted the placeholder is searched by the empty alt:
const placeholderImage = component.getByAltText( '' );
and assumed it may be empty for a reason. But two
aye!
s are enough to convince me! 💪I'll double-check there's no other logic based on that and provide it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alt text added in the commit.
I considered what should be the alt text:
I went for a second option since the image itself is set externally through the settings and may change over time. Also, the content is kind of redundant in this context, the purpose matters. There are even opinions that placeholder image doesn't need alt text at all (https://www.seroundtable.com/google-alt-text-small-images-23672.html - thanks @imanish003 for sharing that! 🙌 ), but I'm not convinced.
Happy to hear your opinion!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @kmanijak. I think it is great that @imanish003 mentioned the fact that placeholder images may not need an alt text and yes I just remembered that are some situations in which the alt text must be empty, but I cannot remember from the top of my mind all those situations so I went ahead looking for resources related to that.
I found this alt Decision Tree from the W3C Web Accessibility Initiative (WAI) that I think we can use to make this decision: https://www.w3.org/WAI/tutorials/images/decision-tree/. It seems that if we consider the placeholder image as being just decorative or not intended for the user the best solution would be to leave it empty. Here is also a resource talking about Decorative Images: https://www.w3.org/WAI/tutorials/images/decorative/, it states that "Text values for these types of images would add audible clutter to screen reader output or could distract users if the topic is different from that in adjacent text", which is something I can agree since we can have dozens of placeholder images that is going to be read by the screen readers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a very interesting discussion. After reading it, I agree that alt text would add audible clutter to screen reader users. People do not need to hear over and over about the placeholder image which is there just to keep the layout, actually. Does not add any information.
I agree with removing it. Sorry @kmanijak for the extra work. But it's a good opportunity also because I saw there were some mistakes in the implementation which we take for granted and it's a good time to inform you about them. We never use naked strings in either JS or PHP code, we always use WordPress localization functions.
Here are two resources:
Most generally, you will see that you'll often find yourself using the
__
function.With that said, I think we should make this decision of leaving the alt text empty explicit by adding a comment in the relevant places, perhaps linking to this discussion thread. Someone else could see the empty alt text and it would be the same story all over again!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @thealexandrelara and @sunyatasattva for your valuable input! I'm happy with the conclusion.
The changes are available in this commit: