Responsive images using client hints
Last updated: Sep-02-2024
Client-Hints allow web browsers to inform servers (or CDN layers) of the required dimensions and pixel densities of each specific image download request. Taking advantage of this feature can allow a single dynamic Cloudinary URL to actually return different image sizes according to the specific needs of the responsive website in every user's device and browser. Browsers that support Client-Hints will send hints as HTTP request headers if this behavior is enabled for their websites. The relevant hints for automating responsive images are: Sec-CH-DPR (which represents the browser window’s current device pixel ratio), Sec-CH-Width (which represents the width, in device pixels, that the image will occupy within the responsive layout), and Viewport-Width (which represents the width, in CSS pixels, of the browser's window).
dpr_auto
and w_auto
with the actual values on the client side based on the screen properties and viewport width. The automatic features documented here allow you to simplify your code and perform the dynamic decisions on the server side (CDN level) based on Client-Hints, but only for supported browsers.The HTML page must also have Client-Hints enabled, which can be accomplished using either HTML or HTTP. To enable Client-Hints via HTML, add the following line in the <head>
of your page, before any <link>
, <style>
, or <script>
elements:
Alternatively, to enable Client-Hints via HTTP, add the following headers to your HTML document's response:
- If you are delivering images from a Private CDN or custom delivery hostname (CNAME), replace
https://res.cloudinary.com
in the snippets above with the origin of your image URLs. - Browsers will only attach client hints to requests for URLs that use the HTTPS protocol.
- In order to send the
Sec-CH-Width
hint, which is required for Cloudinary's automatic image width feature, the<img>
element must have asizes
attribute.
Once Client-Hints are properly enabled, browsers attach hints to outgoing image requests, informing Cloudinary about the layout width of an image on a user’s device and the pixel density of their screen. Cloudinary can then decide on the size of the image the browser needs for displaying to the user, and select and deliver an optimal resource – all at the CDN level.
For example, to deliver the sample
image automatically scaled to the width available for the image in the responsive layout:
The code above generates the following HTML image tag:
Cloudinary automatically adapts the image to fit the viewport, layout and resolution on any device, ensuring a visually-seamless user experience while improving performance, using one of the following options:
- Automatically deliver images matching the DPR setting of the user's device, rounded up to the nearest integer.
- Automatically scale the image to match the width available for the image in the responsive layout, rounded up to the closest multiple of 100 pixels (by default).
- Automatically scale the image to match the width available for the image in the responsive layout using optimal responsive breakpoints
Automatic pixel density detection
To deliver an image in a resolution that automatically matches the DPR (Device Pixel Ratio) setting of the user's device, set the client_hints
parameter to true
and the dpr
transformation parameter to auto
(dpr_auto
in URLs). The device's DPR value is received at the CDN level and rounded up to the nearest integer in order to avoid creating extra derived images and consuming extra transformations (e.g., a DPR value of 1.5 will be rounded up to 2.0).
For example, to deliver the sample
image filled to a width of 300 pixels, a height of 200 pixels, and with a DPR value suitable for the user's device:
- The CDN returns a
Vary
response header set toSec-CH-DPR
in order to allow the same URL to be cached differently for each DPR value. - If Client-Hints are not supported by the user's browser or if they are not available, a URL with
dpr_auto
will be treated asdpr_1.0
. - Setting a value of
dpr_1.0
is treated the same way asdpr_auto
and will also be replaced with the device's DPR. If you want to forcedpr_1.0
, you should do so by removing thedpr
option from the URL completely.
Automatic image width
- Currently only works on Chromium-based browsers (e.g., Chrome, Edge, Opera, and Samsung Internet).
- For customers with a custom delivery hostname or private CDN distribution, contact us to setup this feature.
To deliver an image automatically scaled to a width that matches the width available for the image in the responsive layout, set the:
-
width
parameter toauto
, -
crop
parameter tolimit
, -
client_hints
parameter totrue
, -
sizes
parameter to100vw
(this is the most common value to set, i.e., 100% of the available width, but you can give any value that the HTMLsizes
attribute accepts).
The width of the image is received at the CDN level and then rounded up in order to avoid creating extra derived images and consuming too many extra transformations. By default, the rounding up is made in steps of 100 pixels (e.g., 347 will be rounded up to 400 and w_auto
in this case will be treated as w_400
). To round up in steps of a different number of pixels, a numeric value can be appended to the auto
value, separated with a colon. For example, w_auto:50
means rounding up in steps of 50 pixels: 347 will be rounded up to 350 and w_auto:50
in this case will be treated as w_350
.
For example, to deliver the sample
image automatically scaled to the width available for the image in the responsive layout:
The code above generates the following HTML image tag:
Try the interactive demo to see this for yourself.
To avoid delivering large images, no matter what the width available for the image, a limit transformation can be chained with the w_auto transformation. For example, to deliver the sample
image filled to an aspect ratio of 16:9 and then automatically scaled to the width available for the image in the responsive layout (up to a maximum width of 1000 pixels):
The code above generates the following HTML image tag:
- The CDN returns a
Vary
response header set toSec-CH-Width, Sec-CH-DPR
in order to allow the same URL to be cached differently for each Width and DPR value. - If Client-Hints are not supported by the user's browser or if they are not available, by default
w_auto
will be treated as if no scaling is requested. This might mean delivering the original hi-res image dimensions, which is equivalent to omitting thewidth
parameter altogether. You can bypass this default behavior by specifying a default (fallback) value for the width that is only used if the information cannot be retrieved from a Client-Hints header. This default width value can be concatenated to the transformation value: e.g.,w_auto:40:360
means that Cloudinary will use a rounding step of 40 pixels, and in the absence of a Width hint from the browser, it will substitute a default value of 360.
Responsive images using client hints interactive demo
Open the following URL in a Chromium-based browser to see a demo of automatic image width in action:
https://cloudinary-devs.github.io/cld-docs-assets/demos/client-hints.html
View the demo code in GitHub.
Strict transformations and signed URLs
To support strict transformations and signed URLs, the explicit pixels step value has to be specified and included in the signed value of the width parameter. e.g., w_auto:100
(i.e., there is no default value in this case and the pixels step value must be explicitly included in the parameter value). The CDN layer will send the original requested path (e.g., /w_auto:100/sample.jpg
) together with the actual required rounded up width (e.g., w_400
). Cloudinary's service will validate the signature according to original requested width rather than according to the actual required image width (e.g., w_auto:100
instead of w_400
).
Automatic image width using optimal responsive breakpoints
- Currently only works on Chromium-based browsers (e.g., Chrome, Edge, Opera, and Samsung Internet).
- For customers with a custom delivery hostname or private CDN distribution, contact us to setup this feature.
The automatic width feature can be further enhanced using Cloudinary's intelligent responsive breakpoints generation feature. Arbitrarily rounding up the width value in constant steps (e.g., 100 pixels) does not optimize the process of reducing the file size vs. the number of images generated. Having too many image versions reduces the number of CDN cache hits for requested images and increases the average delivery time for images to your users. On the other hand, having too few image versions means delivering images to users that are larger than needed for the available width, and end up being scaled down by the browser.
Cloudinary can calculate the set of optimal rounding up steps, or breakpoints, by determining the optimal number of versions for every image that balances the number of image versions generated vs. the file size reduction between each version. The set of breakpoints are thus calculated based on a difference in the actual image file size at different widths.
To automatically determine the optimal width values of each image, individually set the:
-
width
parameter toauto:breakpoints
, -
crop
parameter tolimit
, -
client_hints
parameter totrue
, -
sizes
parameter to100vw
(this is the most common value to set, i.e., 100% of the available width, but you can give any value that the HTMLsizes
attribute accepts).
Cloudinary performs the breakpoints calculation and then rounds up the generated image width to the closest optimal breakpoint.
For example, to deliver the bike
image filled to an aspect ratio of 16:9 (ar_16:9,c_fill
) and then automatically scaled to the closest optimal breakpoint that is larger than the width available for the image in the responsive layout, where the optimal breakpoints are calculated using the default breakpoint request values (c_limit,w_auto:breakpoints
):
The code above generates the following HTML image tag:
Assuming (for the example above) that the Client-Hints request header returns a width of 347, and Cloudinary has calculated that the set of optimal breakpoints for this image are as follows: 50, 238, 356, 450, 542, 621, 692, 764, 834, 901, 955, 1000.
Then the selected breakpoint from the set will be 356 pixels (the first breakpoint greater than 347), and the delivery URL will be treated as ar_16:9,c_fill/c_limit,w_356
.
Breakpoints generation settings:
- Global breakpoints settings are applied with their default values as follows:
min_width=50
,max_width=1000
,bytes_step=20KB
,max_images=20
. For more information on these settings and possible values, see the responsive breakpoint request settings documentation. - The default settings can be overridden using a dynamic URL that includes the new values:
auto:breakpoints_[min_width]_[max_width]_[bytes_step_in_KBs]_[max_images]
e.g.,w_auto:breakpoints_200_1920_30_15
. - All 4 of the breakpoint request settings parameters must be included if you need to override any of them.
For example, to deliver the bike
image filled to an aspect ratio of 16:9 and then automatically scaled to the closest optimal breakpoint, where the optimal breakpoints are calculated using the following breakpoint request values - min_width=200
, max_width=1920
, bytes_step=30
, max_images=15
:
The code above generates the following HTML image tag:
Default value for browsers that don't support Client-Hints
If Client-Hints are not supported by the user's browser or if they are not available, by default w_auto:breakpoints
will be treated as if no scaling is requested. This might mean delivering the original hi-res image dimensions which is equivalent to omitting the width parameter altogether. You can bypass this behavior by specifying a default value for the width that is only used if the information cannot be retrieved from a Client-Hints header. This default width value can be concatenated to the transformation value, separated with a colon.
For example:
w_auto:breakpoints:500
tells Cloudinary to:
- Scale the image to the closest calculated breakpoint based on the width retrieved from the Client-Hints header, or
- Scale the image to the closest calculated breakpoint based on a default value of 500 pixels for the width, if the actual available width cannot be retrieved from a Client-Hints header (i.e., as if the Client-Hints header had returned a value of 500 for the width).
Calculated breakpoints delivery URL
Dynamic applications (e.g., JavaScript-based applications) can request that Cloudinary deliver the set of calculated breakpoints for an image instead of the transformed image itself. To request a JSON response containing the set of calculated breakpoints, set the width
transformation parameter to auto:breakpoints:json
. The breakpoints' JSON URLs are treated in a similar way to all other derived assets and are cached at the CDN layer like any derived image or file.
For example, to return the set of calculated breakpoints for the bike
image filled to an aspect ratio of 16:9:
Returned JSON example: