WordPress has native responsive-image support. For images in the Media Library, generate markup with wp_get_attachment_image() instead of writing a bare <img> tag. WordPress can then provide a srcset candidate list and a sizes declaration; the browser uses both to download an appropriately sized file. Set sizes to match the image’s actual CSS width, and keep loading="lazy" for below-the-fold images.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What responsive images mean in WordPress
A responsive image is not one file that magically resizes without cost. It is a set of files at different widths plus instructions that let the browser choose the smallest candidate that can cover the rendered slot at the current viewport density.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
WordPress has supported native responsive images since version 4.4. When an attachment image is rendered through wp_get_attachment_image(), WordPress can add:
srcset: the available image URLs and their intrinsic widths.sizes: the width the image is expected to occupy under different viewport conditions.loading: whether the browser should defer loading the image.
The browser makes the final file choice. WordPress supplies the candidates and layout information; your theme’s CSS and the sizes value must agree.
#1 Best Overall
Use the core image function first
Render a Media Library attachment
Pass the attachment ID, a registered image size, and an attribute array to wp_get_attachment_image(). This is the normal template-level solution for post images, featured images, galleries, and other Media Library attachments.
<?php
echo wp_get_attachment_image(
$attachment_id,
'large',
false,
array(
'class' => 'article-image',
'loading' => 'lazy',
'sizes' => '(max-width: 767px) 100vw, (max-width: 1199px) 70vw, 800px',
)
);
?>
Replace $attachment_id with the attachment ID you are displaying. Replace the size name and width breakpoints with the values used by your layout. The example says that the image occupies the full viewport up to 767 pixels, about 70% of the viewport through 1,199 pixels, and no more than 800 pixels above that.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use the result in a theme template
For a featured image, obtain the post’s thumbnail ID and pass it to the same function:
<?php
$thumbnail_id = get_post_thumbnail_id();
if ( $thumbnail_id ) {
echo wp_get_attachment_image(
$thumbnail_id,
'large',
false,
array(
'class' => 'post-card__image',
'sizes' => '(max-width: 699px) 100vw, (max-width: 1099px) 50vw, 360px',
)
);
}
?>
Do not copy this exact sizes string unless the card really follows those widths. A three-column grid, a sidebar, and a full-width hero all need different declarations.
How srcset and sizes work together
| Attribute | What it describes | What happens when it is wrong or missing |
|---|---|---|
srcset |
The candidate image URLs and their widths. | With no candidate list, the browser has only the single src file. With fewer than two usable candidate images, WordPress has no useful responsive list to output. |
sizes |
The image’s expected rendered width at different viewport widths. | If the markup has no useful declaration, the browser generally assumes the image spans the full viewport. It can therefore download a larger file than a narrow column needs. |
src |
The fallback or default image URL. | It remains important for browsers and contexts that do not use the candidate list. |
loading |
Whether loading is eager or deferred. | Changing it affects when the browser requests the image, not which width candidate is appropriate. |
The most influential setting for download size is usually sizes. Suppose a 3,000-pixel original is displayed in a 360-pixel card. If the browser is told that the slot can be the full viewport, it may select a much wider candidate than necessary. A declaration such as (max-width: 699px) 100vw, 360px tells it that the card is viewport-width on small screens and 360 CSS pixels otherwise.
Why a single image size produces no srcset
wp_calculate_image_srcset() and wp_get_attachment_image_srcset() build candidates from registered image sizes. If fewer than two candidate images are available, there is no useful responsive choice, so WordPress returns no practical srcset. Uploading only one size, deleting generated sizes, or requesting a size for which no alternatives exist can therefore make a seemingly correct template emit a single image.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteRank #2
Write a sizes value that matches your CSS
Start with the actual layout slot
Measure the rendered image slot, not the original file. Include the effects of a sidebar, grid gap, container max-width, and padding. Then express that relationship as media conditions from the smallest viewport upward.
- Full-bleed image:
100vwwhile the image is edge to edge. - Contained article image: a viewport percentage until the content container reaches its maximum width, then the container’s pixel width.
- Card grid: the card width at each breakpoint, including the number of columns.
sizes="(max-width: 639px) 100vw, (max-width: 999px) 50vw, 320px"
This example describes a full-width mobile image, a two-column tablet layout, and a 320-pixel desktop card. It is only correct if the CSS produces those widths.
Keep the declaration in sync with breakpoints
If CSS changes from two columns to three, update sizes in the same change. A stale declaration does not usually break rendering; it causes inefficient downloads. Check the widest and narrowest states, because a mistake at one breakpoint can affect every image using that template.
Lazy loading and WordPress 6.7
Use loading="lazy" on images that begin below the initial viewport. The loading argument controls lazy loading, and its default is determined by WordPress’s loading-optimization system. Passing false omits the attribute when you need to control loading yourself.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →<?php
echo wp_get_attachment_image(
$attachment_id,
'large',
false,
array(
'loading' => false,
'sizes' => '(max-width: 767px) 100vw, 800px',
)
);
?>
Do not disable lazy loading on every image. A prominent hero or logo that is visible immediately may need eager loading, while images farther down the page are generally better candidates for lazy loading. Make that decision per position in the page, not merely per file type.
Since WordPress 6.7, lazy-loaded images receive sizes="auto" prepended in browsers that support the feature. This behavior applies only when the image includes loading="lazy". The automatic value works with the browser’s current rendered dimensions; an explicit layout-aware sizes value remains useful when you know the slot and want predictable candidate selection.
If code changes the loading attribute after the image markup has been generated, use WordPress’s wp_img_tag_add_auto_sizes() helper to correct the sizes handling. Treat this as version-dependent code and test the final HTML, especially when another plugin also rewrites image attributes.
Customise attachment attributes with the documented filter
When many templates need the same correction, use wp_get_attachment_image_attributes rather than duplicating hand-written markup. The filter is intended for changing attributes on attachment images, including post thumbnails and gallery images.
Free tools Windows power users keep installed
One-click scans. No signup required.
<?php
add_filter(
'wp_get_attachment_image_attributes',
function ( $attr ) {
if ( empty( $attr['sizes'] ) ) {
$attr['sizes'] = '(max-width: 767px) 100vw, 800px';
}
return $attr;
}
);
?>
This example supplies a fallback only when no sizes value exists. A site with multiple layouts should use a more specific condition, such as the template or component that is rendering the image, so a global rule does not misdescribe sidebar and card images.
Control the candidate list carefully
The wp_calculate_image_srcset filter changes the candidate list calculated from the attachment metadata. It can be used to remove unsuitable candidates or to return an empty list, but it affects the browser’s available choices and should be applied narrowly. Log or inspect the resulting list after any change.
The max_srcset_image_width filter caps the largest width eligible for the candidate list. WordPress reference material has shown differing default-width summaries over time, so do not assume a particular default; set a cap deliberately if your site has a documented maximum display width and verify it against the WordPress version running in production.
Prefer these documented filters to replacing every image with manually assembled HTML. A hand-written tag can easily omit attachment metadata, responsive candidates, loading behavior, or future core improvements.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Rank #4
Make sure WordPress has usable image sizes
Register sizes that reflect real components
Responsive selection needs at least two candidate widths. Your theme or plugin should register sizes that cover the components you actually render: for example, a card width, an article width, and a larger feature width. After changing registered sizes, regenerate thumbnails for existing uploads; newly registered sizes are not automatically created for files uploaded before the change.
For custom cropped sizes, keep related candidates at compatible aspect ratios when they represent the same component. Mixing unrelated crops in one candidate family can produce choices that are technically valid widths but visually surprising. Use a separate image treatment when the composition must change, rather than expecting srcset alone to provide art direction.
Why a hand-written <img> often fails
A manually written tag may contain only one URL:
<img src="/uploads/example.jpg" alt="Example">
That markup has no candidate list, no layout declaration, and no loading policy. Even if you add srcset by hand, you must keep every URL, width descriptor, crop, and breakpoint accurate as media settings change. For Media Library files, let wp_get_attachment_image() generate the attributes and reserve custom markup for cases that genuinely need behavior core does not provide.
Troubleshoot “WordPress srcset not working”
1. Inspect the final HTML
Open the page in a browser, inspect the image element, and check whether srcset, sizes, and loading are present. Inspect the delivered HTML, not only the PHP template, because caching, optimization, or CDN layers may rewrite it.
2. Confirm that the image came from an attachment
Check that the template calls wp_get_attachment_image() with a valid attachment ID. A direct URL, an external image, or a custom field containing only a string cannot provide the attachment metadata that core uses to build candidates.
3. Check for at least two candidate files
Look at the upload’s generated files and the registered sizes. If only one usable width exists, the absence of srcset is expected. Fix the size registration or thumbnail-generation process, then regenerate missing derivatives.
Best Value
4. Check the sizes declaration
A correct srcset can still download an oversized file when sizes says the image is full viewport width. Compare the declared widths with the CSS at each breakpoint. In DevTools, resize the viewport and watch which candidate URL is requested.
5. Search for filters and optimisation rewrites
Review callbacks attached to wp_calculate_image_srcset and wp_get_attachment_image_attributes. Temporarily test without image-optimization, cache, or CDN rewriting to identify which layer changed the attributes. Re-enable layers one at a time after the core output is correct.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →6. Verify lazy-loading behavior by version
On WordPress 6.7 and later, check whether the image has loading="lazy" and whether the browser supports the automatic sizes="auto" behavior. If code removes or changes loading after generation, verify the resulting sizes value rather than assuming the original markup is still valid.
Core WordPress versus a CDN or image plugin
| Approach | Best use | Risks to check |
|---|---|---|
Core wp_get_attachment_image() |
Normal Media Library images in themes and plugins. | Registered sizes and layout-specific sizes values must be correct. |
Hand-written <img> |
Special markup where attachment metadata is unavailable or a custom art-directed treatment is required. | Easy to omit candidates, dimensions, loading behavior, or accessible alternative text. |
| CDN or image plugin rewriting | Delivery transformations, remote caching, or additional compression. | Rewriters can replace URLs, alter candidate widths, or overwrite sizes; inspect the final response. |
A CDN does not remove the need for an accurate sizes declaration. It may change where files are served from, but the browser still needs to know the rendered slot to choose efficiently.
A practical implementation checklist
- Use
wp_get_attachment_image()for Media Library images. - Provide a
sizesvalue that mirrors the component’s CSS breakpoints and maximum width. - Ensure at least two suitable registered image widths exist for each responsive component.
- Use lazy loading for below-the-fold images; make an explicit decision for above-the-fold images.
- On WordPress 6.7 or later, test lazy-loaded output for the automatic
sizes="auto"behavior. - Use
wp_get_attachment_image_attributesandwp_calculate_image_srcsetfor targeted customisation. - Do not assume a default maximum
srcsetwidth; configure and verify any cap throughmax_srcset_image_width. - Inspect the final HTML and the actual network request at mobile, tablet, desktop, and high-density display sizes.
- When a change affects existing uploads, regenerate the missing derivatives before judging the candidate list.
WordPress version notes
| Version or feature | Practical implication |
|---|---|
| WordPress 4.4 and later | Native srcset and sizes support is available when core generates attachment-image markup. |
| WordPress 6.7 and later | For lazy-loaded images, WordPress prepends sizes="auto" in browsers that support the feature. |
| Older or customised installations | Loading, dimension, and filter behavior can differ. Confirm the generated HTML and the functions available in the installed version before shipping a workaround. |
What success looks like
View source or inspect the element and see a core-generated attachment image with multiple width candidates, a sizes declaration that matches the CSS slot, and a loading mode appropriate to its position. Resize the viewport and confirm that the requested file changes without changing the image’s visual composition. If those checks pass, WordPress is doing the responsive work it was designed to do; further optimisation should target the specific filter, template, or delivery layer that is still producing an incorrect result.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




