-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
Describe the current behavior
Images for products and collections turn out to be blurry.
Describe the expected behavior
Images must be clear on any screen size.
Version information (Dawn, browsers and operating systems)
- Dawn Version: 2.1.0
- Firefox Version 92.0
- Windows 10 Version 20H2
Possible solution
Perhaps we're doing responsive images wrong. These guidelines on MDN as well as the HTML Standard could help. 🙂
Additional context/screenshots
It's my first time using Dawn theme as I wanted to explore OS 2.0 and upgrade my skill-set as a Shopify web developer. My client for whom I used the theme (with some of my own modifications) complained that the product images are too blurry. Upon testing, I found out that the srcset attribute value is not rendered correctly, so the browser is unable to access the highest possible resolution. I had to do this crazy fix below to fix the problem.
diff --git a/snippets/product-thumbnail.liquid b/snippets/product-thumbnail.liquid
index 3b9aaac..8ebbb7e 100644
--- a/snippets/product-thumbnail.liquid
+++ b/snippets/product-thumbnail.liquid
@@ -73,11 +73,11 @@
<div class="product__media media media--transparent" style="padding-top: {{ 1 | divided_by: media.preview_image.aspect_ratio | times: 100 }}%;">
<img
- 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 %}"
+ srcset="{{ media.preview_image | img_url: '288x' }} 288w,
+ {% if media.preview_image.width >= 288 %}{{ media.preview_image | img_url: '576x' }} 576w,{% endif %}
+ {% if media.preview_image.width >= 576 %}{{ media.preview_image | img_url: '750x' }} 750w,{% endif %}
+ {% if media.preview_image.width >= 750 %}{{ media.preview_image | img_url: '1100x' }} 1100w,{% endif %}
+ {% if media.preview_image.width >= 1100 %}{{ media.preview_image | img_url: '1500x' }} 1500w{% endif %}"
src="{{ media | img_url: '1500x' }}"
sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | times: 0.64 | round }}px, (min-width: 750px) calc((100vw - 11.5rem) / 2), calc(100vw - 4rem)"
loading="lazy"I had to push the width check one step up, because with the original code, if the image is not wide enough, a smaller version of it is shown. This meant the clarity was already compromised at the source no matter what the viewport width was.
The problem with the original Liquid code here is that it doesn't add a line to the srcset attribute for the original width of the image. As an example, take an image that is 900 pixels wide. In the original code, it stops at 750w with the condition media.preview_image.width >= 750 and the browser never sees the original image that's 900px wide.
In the modified one, the condition media.preview_image.width >= 750 adds the image for 1100w as well. This has two advantages:
- The browser will see and use the image that is 900px wide when the viewport is greater than
750w, although the image is accessed through an image URL with1100xsuffix. - Shopify never up-scales the image, so the image served through the image URL with
1100xsuffix is the original image that is 900px wide.
Can we apply this modification for the Liquid code on all srcset declarations in the Dawn theme?