如何通过CSS检测WebP图像是否被支持

17

如何在CSS中检测WebP图像是否受支持?

.home-banner-background {
     background-image: url('img/banner.jpg');
 }
 /*Here is an if statement that will check if webp is supported*/ {
        .home-banner-background {
            background-image: url('img/banner.webp');
        }
}

有没有可以实现这个功能的“if”语句?


很确定仅使用CSS是不可能“检测”到的。 - misorude
CSS 中没有 if 语句。如果某些内容不被支持,它会简单地忽略该规则。由于 CSS 是有效的,因此缺少图像或不受支持的图像将不会被忽略。 - Persijn
1
只有 CSS 中的 "if 语句" 可以测试属性支持 -- @supports (property: value){/*rules*/} -- 而不是图像文件格式支持。如果能够执行 @supports (background-image: url('existing-image.webp')){/*...*/} 就太好了,但出于相当明显的原因,这是行不通的。 - myf
这里是一个工作解决方案示例: https://dev59.com/R7roa4cB1Zd3GeqPcgwi#64048033 - Alex
回复:“CSS 中没有 if 语句。” @media@supports 都代表了 if 结构。 - Rounin
8个回答

18

现代的webkit浏览器将使用此CSS设置WebP背景图像:

.map {background-image: url('../img/map.jpg');}
  @supports (background-image: -webkit-image-set(url('../img/map.webp') 1x)) {
    .map {background-image: -webkit-image-set(url('../img/map.webp') 1x) }
  }

1
那如果你问我,那其实是相当聪明的。想得很周到! - LukyVj
没能解决我的问题。Safari 13.1.3似乎支持-webkit-image-set,但不支持webp,因此它仍然尝试加载该图像格式,但无法实现。 - Dollique

11
你可以使用Modernizr。它是一种检测用户浏览器可用特性的工具。它只是要添加到你的网站中的一个脚本,有了它,你可以写出类似这样的代码:
.no-webp .home-banner-background {
     background-image: url('img/banner.jpg');
 }

.webp .home-banner-background {
     background-image: url('img/banner.webp');
}

4
为了澄清问题,回答这个问题的答案是“CSS目前无法直接检查浏览器是否支持WebP格式。” 这个解决方案使用JavaScript和CSS。 - Caleb

9
使用 type() 函数与 image-set() 一起,通过 CSS 提供替代图像格式。 在示例中,type() 函数用于提供 WEBP 和 JPEG 格式的图像。如果浏览器支持 webp,则会选择该版本。否则将使用 jpeg 版本。
.box {
  background-image: image-set(
    url("large-balloons.webp") type("image/webp"),
    url("large-balloons.jpg") type("image/jpeg"));
}

文档


目前这个解决方案在浏览器上的支持非常差。 - MarcGuay
1
感谢您添加这个答案!它对那些只需要针对特定浏览器的人可能会有帮助。我会收藏并在接下来的一年里关注浏览器兼容性 - 看起来很有前途... https://caniuse.com/mdn-css_properties_background-image_image-set - Dagmar
不要忘记备用方案:https://developer.mozilla.org/zh-CN/docs/Web/CSS/image/image-set#providing_a_fallback - Mihail H.

6

目前CSS不支持此功能。

CSS Images Module Level 4 Draft中,提出了一种备用方案,但目前还没有任何地方支持。(2.4. Image Fallbacks and Annotations: the image() notation

但如果它在未来成为标准的一部分,那么您可能能够编写:

.home-banner-background {
    image:image('img/banner.webp', 'img/banner.jpg')
}

在那之前,你需要使用像Modernizer这样的工具,如 Fifi 的答案中建议的那样。

另外,picture HTML 标签可能是你可以考虑的一个选项,但它是否适用取决于图像在你的网站上应该如何调整大小:

<picture>
  <source srcset="img/banner.webp" type="image/webp">
  <source srcset="img/banner.jpg" type="image/jpeg"> 
  <img src="img/banner.jpg">
</picture>



6
具有讽刺意味的是,当浏览器支持图像标记时,它们几乎肯定也会支持WebP。 - Nathan Dawson

3
您实际上可以将其添加到原始声明中,而不需要多个类、@supports或引入另一个类似于此的库。
.home-banner-background {
    background-image: url('img/banner.jpg');
    background-image: -webkit-image-set(url('img/banner.webp') 1x,
                                        url('img/banner-2x.webp') 2x),
                                        /* etc */;
}

Webkit将使用webp图像,其他所有浏览器将退回到常规图像。


7
Safari也支持“-webkit-image-set”,但不支持WebP格式。这在iOS上会失败。 - fregante
1
啊,说得好。最近在某些情况下,我一直在检查用户代理,并根据其使用适当的图像格式。迫不及待地希望有更好的方法。 - stinkysGTI
1
检查“Accept”头部中是否包含“image/webp”,比基于用户代理猜测要好得多。 - Luke Cousins
3
相信两幅图都会被下载,这就完全违背了使用WebP减小文件大小的初衷... - OZZIE

1

这个解决方案很好:

.home-banner-background {
  background-image: url('img/banner.jpg');
}

@supports (gap: 1px) {
  .home-banner-background {
    background-image: url('img/banner.webp');
  }
}

只针对支持 gap 属性的浏览器,可以确保与 WebP 图像非常相似的浏览器支持。 REF: https://caniuse.com/flexbox-gap


0

2022年,我将使用以下内容:

backround: url('image.jpg');
backround: url('image.webp');

而且浏览器仅下载 webp 格式的内容。


当然可以,但是不支持webp格式的浏览器也只会下载webp格式的图片。 - simon
@Simon,你测试了吗? - Karl Zillner
确实...找一台旧的Mac/iOS设备... - simon

0

目前(2023年第一季度),使用image-set并不是一个足够的解决方案,因为很多实际支持WebP的设备无法使用它。这两个功能的支持覆盖范围有很大的差异。

我会选择Modernizr,但它不能进行树摇。下面的代码可能对在<body>上设置a class或直接在图像包装器或指令中使用有用。

// inspired by Modernizr implementation
function supportsWebP() {
  return new Promise((resolve) => {
    const image = new Image();
    image.onerror = () => resolve(false);
    image.onload = event => resolve(event.type === 'load' && image.width === 1);
    image.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=';
  });
}

// example usage
const useWebP = await supportsWebP();
const backgroundImage = `/img/picture.${ useWebP ? 'webp' : 'png' }`;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接