基于屏幕断点的适配图片渲染方案优化:替代PHP用户代理检测的可靠实现
Since PHP runs entirely on the server, it can't access the client's screen width directly—so relying on HTTP_USER_AGENT was never going to cut it for accurate breakpoint detection. Let's fix this with front-end-native approaches that work regardless of device or browser devtools mode. Here are your best options:
1. Use the HTML <picture> Element (Recommended)
The <picture> tag is made exactly for this scenario: serving different images based on media queries. It's native, no JavaScript required, and works reliably across all modern browsers.
Modify your get_featured_image function to output a <picture> container instead of a plain <img>. We'll define a media query for screens ≤700px, and fall back to the desktop image for everything larger:
function get_featured_image($post_id) { $mobile_thumbnail = get_field('featured_image_mobile', $post_id); $desktop_thumbnail = get_the_post_thumbnail_url($post_id); // Start building the picture element echo '<picture class="imagery featured-image-selection">'; // Add mobile image source if it exists if ($mobile_thumbnail) { echo '<source media="(max-width: 700px)" srcset="' . esc_url($mobile_thumbnail['sizes']['medium']) . '" alt="">'; } // Add desktop image (fallback for all cases) if ($desktop_thumbnail) { echo '<img src="' . esc_url($desktop_thumbnail) . '" alt="" class="imagery featured-image-selection">'; } echo '</picture>'; }
Why this works:
- Browsers evaluate the
mediaattribute before loading any images, so it won't load both versions unnecessarily. - If the mobile ACF field is missing, it just falls back to the desktop image everywhere.
- Works even when users toggle mobile view in desktop devtools, since the media query checks the actual screen width.
2. Use srcset with sizes
If you prefer a single <img> tag instead of <picture>, you can use srcset and sizes to achieve the same result. This is great if you want to serve images based on both screen width and pixel density:
function get_featured_image($post_id) { $mobile_thumbnail = get_field('featured_image_mobile', $post_id); $desktop_thumbnail = get_the_post_thumbnail_url($post_id); if ($desktop_thumbnail) { $srcset = esc_url($desktop_thumbnail) . ' 1x'; $sizes = '(min-width: 701px) 100vw, '; // Add mobile image to srcset if available if ($mobile_thumbnail) { $srcset .= ', ' . esc_url($mobile_thumbnail['sizes']['medium']) . ' 1x'; $sizes .= '(max-width: 700px) 100vw'; } else { $sizes .= '100vw'; } echo '<img src="' . esc_url($desktop_thumbnail) . '" srcset="' . $srcset . '" sizes="' . $sizes . '" alt="" class="imagery featured-image-selection"/>'; } }
Note:
The sizes attribute tells the browser which size the image will be displayed at for each breakpoint, and srcset provides the corresponding image URLs. Browsers will pick the best match automatically.
3. JavaScript-Based Switch (For Advanced Logic)
If you need more control (like handling resize events after page load), you can use JavaScript to swap the image source dynamically. Pair this with a noscript tag for users who have JS disabled:
function get_featured_image($post_id) { $mobile_thumbnail = get_field('featured_image_mobile', $post_id); $desktop_thumbnail = get_the_post_thumbnail_url($post_id); if ($desktop_thumbnail) { // Default to desktop image echo '<img id="featured-image" src="' . esc_url($desktop_thumbnail) . '" alt="" class="imagery featured-image-selection"/>'; // Add mobile image data if available if ($mobile_thumbnail) { echo '<script> function updateFeaturedImage() { const img = document.getElementById("featured-image"); const mobileSrc = "' . esc_url($mobile_thumbnail['sizes']['medium']) . '"; const desktopSrc = "' . esc_url($desktop_thumbnail) . '"; img.src = window.innerWidth <= 700 ? mobileSrc : desktopSrc; } // Run on page load updateFeaturedImage(); // Run on window resize window.addEventListener("resize", updateFeaturedImage); </script>'; } // Fallback for no JS echo '<noscript> <img src="' . esc_url($desktop_thumbnail) . '" alt="" class="imagery featured-image-selection"/> </noscript>'; } }
Caveat:
This might cause a brief flash of the desktop image on mobile before JS runs, so the <picture> or srcset methods are better for performance and user experience.
内容的提问来源于stack exchange,提问作者user12394904

