最新更新: 该插件已合并到 WordPress 核心。 因此,如果您运行的是 WordPress 4.4 或更高版本,则会自动拥有它。
更新: 本文创建的插件 已移至此处,现在使用 更合适的 srcset
属性。 它是响应式图像社区小组的官方 WordPress 插件,并得到 WordPress 核心团队的认可。 它很可能最终会被纳入 WordPress 核心。 太酷了!
以下文章由 Tim Evko (@tevko) 客串撰写。 WordPress 具有内置的媒体上传系统。 当您上传图像时,它会自动创建并保存该图像的不同版本。 Tim 将向我们展示如何定制和利用该功能来帮助我们处理内容中的响应式图片。
如果您像我一样,需要构建一个相对容易更新的响应式网站,那么 WordPress 通常是您构建该网站的 CMS。 如果您更像我,您可能会跳过响应式图片解决方案,转而使更新工作更轻松。 幸运的是,使用几行 PHP 和一些 JavaScript,您现在可以将自动响应式图片功能添加到您的 WordPress 网站。
在这里,我将向您展示如何以 一个小型 WordPress 插件 的形式,为您的 WordPress 网站添加响应式图片支持。
我们最终想要的标记
我们将在此处使用 Picturefill 库。 现在,我们将使用该库建议的标记,它与 <picture>
元素 即将推出的内容非常相似。
<picture>
元素正在进入浏览器,因此本文中的插件/代码已更新,可以直接使用该语法。<picture>
<source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
<source srcset="examples/images/large.jpg" media="(min-width: 800px)">
<source srcset="examples/images/medium.jpg">
<!-- fallback -->
<img srcset="examples/images/medium.jpg" alt="alt text">
</picture>
这是基本的标记模式,虽然它可能变得 稍微复杂 以适应一些浏览器错误。
我们不会直接在博文帖子中使用该标记,我们将让 WordPress 来帮助我们完成这项工作。
主题
您只需确保主题的 functions.php 文件中存在这行代码即可。
add_theme_support('post-thumbnails');
这将确保您的主题授予 WordPress 调整上传图像大小的权限。 没有它,插件将无法正常工作。
插件
将其作为 WordPress 插件进行处理很有意义,因为无论激活哪个主题,我们都希望它保持活动状态。 我们可以将其制作成一个包含 PHP 文件的文件夹,作为插件代码本身,以及 Picturefill 库的副本。

添加库
负责任地排队
function get_picturefill() {
wp_enqueue_script('picturefill', plugins_url( '/js/picturefill.js', __FILE__ ));
}
add_action('init', 'get_picturefill');
这将确保 WordPress 在前端加载此 JavaScript 库。
定义尺寸
告诉 WordPress 您希望在上传时创建哪些尺寸的图片。
add_image_size('large-img', 1000, 702);
add_image_size('medium-img', 700, 372);
add_image_size('small-img', 300, 200);
您可以根据需要进行设置。 add_image_size 具有可以调整的各种参数。 在我上传的 1024×768 兔子 JPG 的情况下,会创建一些版本。

制作一个 [shortcode]
让我们通过制作一个响应式图片短代码来扩展此插件,使其具有真正的功能。 这样,我们就可以将其直接放在文章内容中。
[responsive imageid="12" size1="0" size2="500" size3="1000"]
它将输出我们需要 Picturefill 的标记。
我们将将其分为三个函数。 一个用于定义短代码和输出 HTML,一个辅助函数用于返回 alt 文本,以及一个专门用于循环遍历并输出图像源的函数。
function tevkori_get_img_alt( $image ) {
$img_alt = trim( strip_tags( get_post_meta( $image, '_wp_attachment_image_alt', true ) ) );
return $img_alt;
}
function tevkori_get_picture_srcs( $image, $mappings ) {
$arr = array();
foreach ( $mappings as $size => $type ) {
$image_src = wp_get_attachment_image_src( $image, $type );
$arr[] = '<source srcset="'. $image_src[0] . '" media="(min-width: '. $size .'px)">';
}
return implode( array_reverse ( $arr ) );
}
function tevkori_responsive_shortcode( $atts ) {
extract( shortcode_atts( array(
'imageid' => 1,
// You can add more sizes for your shortcodes here
'size1' => 0,
'size2' => 600,
'size3' => 1000,
), $atts ) );
$mappings = array(
$size1 => 'small-img',
$size2 => 'medium-img',
$size3 => 'large-img'
);
return
'<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->'
. tevkori_get_picture_srcs( $imageid, $mappings ) .
'<!--[if IE 9]></video><![endif]-->
<img srcset="' . wp_get_attachment_image_src( $imageid[0] ) . '" alt="' . tevkori_get_img_alt( $imageid ) . '">
<noscript>' . wp_get_attachment_image( $imageid, $mappings[0] ) . ' </noscript>
</picture>';
}
然后启用短代码
add_shortcode( 'responsive', 'tevkori_responsive_shortcode' );
理想情况下,您在这里的插件中定义断点,然后在使用短代码时根本不传递它们,例如
[responsive imageid="12"]
然后,仅在您需要覆盖断点的极少数情况下才使用短代码属性。
更改媒体上传器输出
此短代码将非常有用(请记住,我们甚至可以在将来以编程方式调整标记以使其成为正确的 <picture>
)。 但是,我们如何知道要使用的图片 ID? 媒体上传器 UI 并未提供该信息。 不过,它知道该 ID,通过一个简单的过滤器,我们可以调整发送到编辑器的内容。
function responsive_insert_image($html, $id, $caption, $title, $align, $url) {
return "[responsive imageid='$id' size1='0' size2='600' size3='1000']";
}
add_filter('image_send_to_editor', 'responsive_insert_image', 10, 9);
现在,从编辑器中选择并插入图片将按如下方式工作

就这样! 您可以在这里看到它的工作原理

您还可以做的事情
- 如果您希望获得更广泛的支持,请考虑安装 Matchmedia.js。 它将使 @media 查询在旧版浏览器中开始工作,然后自动使 Picturefill 也正常工作。
- 除了使用短代码或调整媒体上传器输出外,您还可以使用 高级自定义字段 使其与特殊图片字段一起工作。
- 您可以调整标记以允许使用 WordPress 喜欢使用的 align-*。 或者使用
<figure>
和<figcaption>
元素。 还有 alt 标签。 - 您可以让断点的设置通过插件创建的 UI 进行设置,而不是硬编码到插件中。
- 以下是 另一种方法,它使用 Picturefill 2 且不使用短代码。
如果您想贡献,以下是 GitHub 代码库。
希望 Joomla 也能有这样的功能!
有趣。 我很好奇,可视化编辑器中的用户是如何看到它的?
我一直通过在内容区域设置图像的最大宽度为 100% 来使用媒体查询解决此问题。 这始终处理了 99% 的情况。
这不是一个坏的做法。 使图像适合其容器非常棒。 但这与提供不同尺寸的图片有关,这与性能有关。
是的,我考虑过这一点。 我可以肯定地想到一些情况下,由于这种情况,您必须执行类似的操作。 像其他所有东西一样,它在合适的应用程序中是一个很棒的解决方案。
我使用与 Josh 相同的想法,但这是关键!
这很有趣,但这些数字会把客户、Joe 和懒惰的人吓跑。我认为,与其定义断点(这些断点可能总是相同的,如果不是,您就需要花时间完美地调整数字),不如直接设置 `article img{max-width: 100%}` 并使用 **sizeX** 来加载不同的图像。
一些图像缩小后会变得很丑,例如品牌/像素艺术/我女朋友的照片,所以能够替换该图像的完全不同的渲染我认为会更好地利用时间和带宽。
嘿,Oz,幸运的是,这个插件有默认选项。如果用户将某些内容留空(除了图像 ID),或者从 WordPress 上传器中选择图像,默认尺寸将接管,并且仍然会生成必要的标记。希望这能解决大多数懒惰问题!
之前写过类似的东西,唯一的区别是,我直接修改了 `the_content();` 中所有图像(除了表情符号)的输出,而不是使用短代码。我强烈建议与 手动图像裁剪插件 结合使用。这样,您还可以单独裁剪每个图像尺寸,从而实现更高的艺术指导水平(我说的是稍微高一点,因为它仍然没有提供为每个尺寸使用完全不同图像的可能性)。
快速问题:通过屏幕方向调整屏幕大小是否会不断地加载较小和较大的图片,是否有办法让它识别较大的图片已经加载,并使用 CSS 调整该图片的大小?
这对于响应式页面来说效果很好,但它不是响应式图像,我认为它会增加页面加载时间。
不正确。这是重点。它只加载适合媒体查询的图像。虽然存在额外的 JavaScript,但一张图像的节省很可能抵消了这一点。
我很喜欢这个,但所有常见的附件显示设置都不起作用,而我的客户会想要这些设置。感谢您分享这一点。
我使用一个类似但更复杂的系统。基本上,我在媒体上传器中有一个选项,允许我设置图像将出现在的“上下文”,因此它可能包括:侧边栏正常、侧边栏全宽、主要内容小、主要内容正常、主要内容全宽等等。
然后,每个上下文都有一个与特定断点相关的图像尺寸数组,这允许我为相当复杂的布局提供合适的图像尺寸。
但是,您确实需要注意,否则最终会在标记中出现大量节点,并且会创建和存储过多的图像尺寸。
我没有将短代码用作输出(没有想到!),但我使用 Jetpack 订阅,这意味着 Jetpack 发送的电子邮件中不会有图像,而是会显示短代码。我不确定是否有什么办法可以解决这个问题。
希望我们也能在 jQuery 中做到这一点!干得好!
太棒了。我甚至没有想到要这样做。我通常坚持插入大图像并将 `max-width` 设置为 `100%`,并将高度设置为自动的方式。我会在即将到来的客户项目中尝试一下,看看他们喜欢不喜欢。
挑剔:您应该在 `wp_enqueue_scripts` 操作而不是 `init` 操作中将脚本排队。请参见 http://wordpress.stackexchange.com/questions/55924/when-to-use-add-actioninit-vs-add-actionwp-enqueue-scripts
你说得对!感谢您指出这一点!您介意在 Github 上提交一个问题吗?
感谢您分享这个很棒的解决方案。我遇到的一个错误是,您必须在 `header.php` 中使用 `<?php wp_head(); ?>` 以及在 `footer.php` 中使用 `<?php wp_footer(); ?>`。如果没有使用 `<?php wp_head(); ?>`,则图像将不会显示。
Jonas,您的标题和页脚文件中的这些包含是必需的,并且应该存在于您的主题中。没有它们,您将无法访问大量 WordPress 功能。
Tim,这看起来确实是一个不错的解决方案。您会将它提交到代码库吗?我总是有点犹豫,在没有经过审查流程的情况下,在生产网站上尝试类似的事情。
Becky,我正在考虑是否将它提交到 WordPress 代码库。在此之前,我想添加一些功能,也许还添加一个 UI。如果您想看看这个插件是如何工作的,我建议您在 WP 的开发/本地/沙盒版本上安装它并在那里进行测试。
听起来不错。我会在开发环境中尝试一下,但请告知您是否发布了!谢谢。
感谢 Tim,很棒的帖子。但是,我正在寻找一些针对背景图像的 CSS 技巧。如果我为包装器设置了背景图像,我会使用 `background-size: cover` 以及背景标签中的 `center center`。那么,正确的做法是什么?
谢谢
非常有趣的想法,从未想过这种方向。唯一的缺点是您无法在 WYSIWYG 中看到图像,只能看到短代码(这对内容编辑器来说是个问题)。还有一点,预短代码图像将不会响应(您需要手动编辑帖子),如果您关闭插件,您将根本看不到图像。我将尝试使用默认的 img 标签,并使用输出 `the_content()` 的过滤器对其进行修改。看起来应该可以解决上面提到的问题。
这是一个非常有趣的想法,使用 `the_content` 过滤图像标签。如果您想要上下文,可以在图像标签上添加适当的类或数据,您可以使用这些类或数据进行过滤。我很想看看您的结果。
如果您弄明白了,一定要分享!:P
在我看到您的帖子之前,我考虑了一下使用 `content-filter` 过滤 img。使用 `image_send_to_editor` 过滤器可以将图像 ID 等必要变量放入 img 字符串中,以便更容易找到图像并获取 ID。从那时起,一切都变得轻而易举了。;-)
您将如何实现这一点?我试过,但完全失败了。
这对于固定宽度来说很棒,但正如 Draz 所说,似乎应该构建一个机制来首先检查是否已经加载了较大版本,然后回退到最大宽度值,而不是加载下一个较轻的版本。
例如,旋转平板电脑的操作如下:
横向 - js 加载 980px 图像版本
纵向 - js 加载 480px 图像版本(如果横向已经加载,现在我们就请求了两个图像,这是不必要的)。
编辑 *固定宽度* - 我的意思是当设备在 DOM 加载后没有改变其宽度时。
我认为如果脚本检测屏幕比例并加载与最近匹配尺寸的匹配比例图像,效果会更好。
仍然会忽略一些分辨率和屏幕比例(制造商正在进行大量实验),在这种情况下,脚本应该查找最近尺寸的图像并对其应用 `max-width: 100%` CSS。
您也可以使用 Noel Tock 的插件 Hammy
您好,我的代码运行良好,但在 IE8-9 中不起作用?
我以为 picturefill 库可以提供回退,在 Github 页面上它说要进行一些 shiv 操作来添加 picture 元素等,但是在这个版本中我们没有使用它。可能是因为使用此代码它无法正常工作吗?
我错过了什么吗?
提前感谢!:)
我有时会打印图片,我用胶水把图片粘在电脑屏幕上,如果图片太小,我会用黑色油漆把周围的电脑屏幕涂黑。
这是一个缓慢的过程,但油漆在干燥的时候,我可以带我的狗出去跑步。
一个方便且便宜的小贴士,可以让你的朋友或朋友(如果你不止一个)看到你的图片,就是把它们放在一个信封里,通过邮政服务寄给他们,这比从屏幕上刮掉黑色油漆要快一些,特别是如果你找不到你的狗的时候。
我对 wordpress 和 php 还不太了解。
如何将它与 Advanced Custom Fields 一起使用?
嗨 Lily,
可能有一种更好的方法来做到这一点,但这就是我如何在我的高级自定义图片字段中使用它的方法
在我的 .php 文件中
https://gist.github.com/funzeye/f48f7363ac9aeaa1e618
在这种情况下,它来自我的 front-page.php 文件,我的图片在一个 figure 中 - 但可以忽略这一点。
还要记住,进入你的“自定义字段”设置,并将你的图片返回值更改为 Image ID(如果还没有的话)…
看看响应式网站的示例 - http://designmodo.com/responsive-design-examples/ 非常好的做法。
我想知道是否有一种方法可以为网站上已有的图片创建这些尺寸的缩略图?或者 WordPress 会在您尝试以特定尺寸使用图片时动态创建缩略图吗?可能不会,但会很好!
实际上,我刚刚找到了几个我认为应该能满足我需求的插件
http://wordpress.org/plugins/ajax-thumbnail-rebuild/
http://wordpress.org/plugins/regenerate-thumbnails/
有没有办法让图片仍然可以在编辑器中加载,但背景中有短代码?客户不希望看到这个短代码。可怕的数字!我的图片去哪儿了?!!
还没有尝试过,但理论上你只需要从 function.php 中删除“更改媒体上传器”代码。
然后你将需要在你的 php 页面中获取图片 ID
这段代码可能会有所帮助:https://gist.github.com/funzeye/f48f7363ac9aeaa1e618
实际上,取消这个想法,
我认为你可能只是在你的 php 中使用“the_content”,所以你可能无法单独从编辑器中获取每个图片。所以这可能不会奏效。
也希望找到一个好的解决方案……