响应式图片

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费额度!

真正需要的是提供适合设备和环境的媒体,因为我们对任何特定的网络请求了解甚少。 我最近发布了一篇博客文章,里面有那么多图片,页面大小达到了 2.29 MB。 我应该在发布到 Twitter 时提醒大家:“如果你使用 3G 网络,就不要点击它,因为它可能要花很长时间才能加载,等你回家再看吧。”

理想情况下,我提供的这些图片都可以有一个较低分辨率的版本,在浏览器窗口大小较小或网络连接速度较慢的浏览器中显示。 即使在最先进的浏览器中,目前还没有原生方法来做到这一点。 所以现在是开始讨论我们作为网页开发者希望它如何运作的好时机。 也许我们可以影响规范的制定方式。

让我们将此讨论限制在内联栅格图像。 也就是说,今天作为 <img> 提供的服务。 我认为我们可以走三条路。

  1. 创建仅用于解决此问题的全新元素。
  2. 创建一种旨在解决此问题的新图片格式。
  3. 什么也不做,用其他技术解决我们的问题。

每种方法都有其优缺点。 让我们逐一看看。

创建新的元素

最有可能的候选者是 <picture>,正如在 W3C 社区中所讨论的那样。 Scott Jehl 有一个 JavaScript polyfill,它模拟了它的功能。 语法如下:

<picture alt="description of image">

  <!-- low-res, default -->
  <source src="small.jpg">

  <!-- med-res -->
  <source src="medium.jpg" media="(min-width: 400px)">

  <!-- high-res -->
  <source src="large.jpg" media="(min-width: 800px)">

  <!-- Fallback content -->
  <img src="small.jpg" alt="description of image">

</picture>

优点

  • 模仿其他媒体语法,例如 <video><audio>,这很有道理。
  • 回退功能使其与不支持它的浏览器向后兼容,这非常重要。 我们不能让图片在旧浏览器中无法正常显示。
  • 让我们这些网页作者能够控制在特定情况下显示的内容。

缺点

  • 它比 <img> 复杂得多。 难以教授,难以学习,需要编写更多代码。 容易出错。
  • 通过将媒体查询语法引入 HTML,它稍微混淆了 CSS 和 HTML 的界限。
  • 与内联样式的问题类似。 使未来的更新变得更加困难。 不是可重用的抽象。

新的图片格式

这篇博客文章的灵感来自于我和 Christopher Schmitt 的对话,以及他发表的一篇博客文章。 Christopher 认为,一种新的图片格式是理想的解决方案。

这种新的图片格式将包含多个版本的自己。

哪张图片被像网页浏览器这样的程序提供,可以通过浏览器和网页服务器之间的虚拟握手来确定。

因此,该文件可能总共有 800k,但其中包含四个不同的版本:500k、200k、50k 和 10k。 通过某种标准化的规则集,这四个图片中的一个将被传送到浏览器并显示。

听起来像天方夜谭吗? 实际上,已经存在一种名为 FlashPix 的图片格式,它可以处理更加剧烈的版本化。 认为新的图片格式无法实现吗? WebP 正在以相当快的速度获得支持。

最终,语法将保持现状

<img src="unicorn.rpng" alt="fancy unicorn">

我只是编造了这个文件扩展名,但“响应式 PNG”对我来说就足够了。

Christopher 喜欢这种方法,因为它

允许继续使用 IMG 元素,它已经深深地融入到了 Web 的骨髓和精髓之中。

我喜欢这种想法。 我们无需抛弃一个一直运作良好的元素。 当然,我们也不会这么做。 无需替换 <img>,只需在其基础上进行构建并提供替代方案即可。

优点

  • 保持语法简单。 工作方式与以往相同。
  • 也保持作者的编写简单。 一个文件,而不是多个文件。 采用速度可能会更快,更多人会实际使用它(较少人会为每个图片制作 4 个版本并手工制作查询来提供服务)。

缺点

  • 可能会失去控制。 为了保持简单,图片格式会决定到底提供什么内容的逻辑。 它总能做出正确的决定吗? 它考虑哪些因素? 父容器宽度? 网络连接速度? 像素密度? 多个因素的组合?
  • 与旧版本不兼容。 不支持新格式的浏览器会发生什么情况?

其他技术

我们当然可以依靠 JavaScript 来帮助我们。 它可以帮助我们使用新的图片格式。 我们将在 <img> 中使用普通的 png 和 jpg,并在新格式获得普遍支持之前,使用它来动态替换 src 属性。 这可能有点笨拙,但可行。

如果它能做到这一点,也许我们应该让它直接解决整个问题。 JavaScript 可以执行我们可能需要的所有“测试”(例如,窗口大小测试、网络速度测试),并且它可以负责将我们图片的 src 属性替换为更合适的图片。 Adam Bradley 的 foresight.js 库已经在做这件事了。 也许这就是 JavaScript 的用处,我们无需干涉。

认为 JavaScript 的客户端特性并不理想吗? 有几个解决方案可以将事情转移到服务器端。

Matt Wilcox 的 Adaptive Images 是一种非常巧妙的解决方案,它只使用少量的 JS 来测量当前屏幕大小并设置 cookie,然后所有对图片的请求都将通过一些 PHP 代码,根据屏幕大小确定要提供哪个版本的图片。

Sencha.io Src 是另一种完全无 JavaScript 的解决方案。 它通过 UA 嗅探来确定设备,并根据此决定要提供哪个大小的图片。 您只需在图片的 src 属性前加上 Sencha 服务的 URL 即可

<img src='//src.sencha.io/http://mywebsite.com/images/unicorn-hires.jpg' alt="unicorn" />

这是最简单的使用方法,它可以做得比这更复杂。 不过,这是一项第三方 Beta 服务,因此请注意它固有的风险(例如,服务停机,您的图片将无法加载)。 我想它最终会变成一项付费服务。

优点

  • 我们不会动摇标准。
  • 无需等待浏览器支持任何新功能。

缺点

  • 这仅仅是忽略问题吗? 标准不应该帮助解决实际问题吗?
  • 正确执行此操作所需的代码过于繁琐。

我的观点

仅仅依靠旧技术和技巧对我来说是不够的,但我无法决定我更喜欢新的格式还是新的语法。 也许两者都行? 也许是混合的方式? 我觉得语法更可能,因为对此的讨论更多。 格式的难度要大得多,而且我没有听说过任何关于此类事物的积极开发的传闻。

当我能够更新这篇文章,其中包含“官方”最佳实践时,那将是一个快乐的日子!

相关