当您采用响应式网页设计路线时,部分交易内容是流体网格。 也就是说,容器元素以百分比宽度设置。 举个例子:一个包含博客文章的<article>
元素在小屏幕设备上可能宽 320px,而在大屏幕上可能宽 690px。 文本可以调整大小,并且会流畅地填充容器。 这并不难。 但是媒体——图片、视频播放器和音频播放器——需要更多关注(例如,一个从屏幕边缘伸出的视频==不好)。 本文旨在总结处理这些媒体的方法。
灵活的图片

如果您习惯于 IE 7 及更高版本的支持。 这种小巧美妙的功能就足够了。
img {
max-width: 100%;
/* just in case, to force correct aspect ratio */
height: auto !important;
}
如果您关心 IE 7 支持(我希望不是,但我理解有些情况下您必须这样做),请使用此方法确保图像在缩小后能完好无损。
img {
-ms-interpolation-mode: bicubic;
}
此处查看更多相关内容。
如果您需要关心 IE 6(再次...)Ethan Marcotte 的这篇文章提供了一个 JavaScript 解决方案。 对于一个已经很慢的浏览器来说,加载额外的 JavaScript 有点令人沮丧,但是 c’est la vie。
思维转变
曾经,调整图片大小是一件禁忌。 浏览器在调整图片大小方面很糟糕,而且带宽被浪费了。 现在这种态度已经消失殆尽,主要是因为浏览器现在在调整图片大小并使其看起来不错的方面做得很好。 事实上,随着“视网膜”显示变得流行,为容器提供过大的图片反而是一种好事,因为缩小它们可以使它们看起来更清晰。
然而,带宽问题仍然是一个(重大)问题。 这就是为什么响应式图片现在如此热门的原因。 关键是:在考虑灵活图片时,也要考虑响应式图片。 您可以在此处了解更多关于 当前解决方案。
灵活的视频
灵活的视频比图片稍微复杂一些。 如果您直接使用 HTML5 <video>
,好消息是它保持着与图片相同的纵横比,因此相同的技巧也适用。
video {
max-width: 100%;
/* just in case, to force correct aspect ratio */
height: auto !important;
}
但是,我开始认为直接使用 HTML5 <video>
并不是一个好主意。 这些年来,所需的格式一直在不断变化,而且还没有结束。 再加上以下事实:1)托管视频会占用大量带宽,而且价格昂贵;2)流媒体是另一个完全复杂的领域;3)在不同格式、设备和可用带宽下维护适当的质量很难;4)在播放器上制作一致的皮肤控制也很难……嗯……直接使用 HTML5 视频太麻烦了。
相反,我强烈建议使用像 YouTube 或 Vimeo 这样的视频服务。 当您从这些服务中嵌入视频时,您会嵌入一个<iframe>
。 iframe 内的内容可能是 HTML5 视频,但您不必直接处理它。
所有这些都说明:<iframe>
存在纵横比问题。
Thierry Koblentz 多年前在他的 A List Apart 文章 Creating Intrinsic Ratios for Video 中解决了这个问题。
基本思想是,您创建一个高度为零、顶部填充以百分比设置的视频包装器 div。 该百分比实际上将是宽度的百分比,使其保持纵横比。 然后,您将视频绝对定位在内部,这为您提供了保持纵横比的难以捉摸的能力。 我们将针对 iframe 进行绝对定位,因为正如前面提到的,视频不需要这样做,但 iframe 需要。 基本知识
.video-wrapper {
height: 0;
padding-bottom: 56.25%; /* 16:9 */
position: relative;
}
.video-wrapper iframe {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
请查看 该文章,了解更多关于旧版浏览器支持的细微差别和细节。 我还在我的 .net mag 文章 Create Fluid Width Videos 中涵盖了所有这些内容,并包含了一些自制的 JavaScript 解决方案(带有演示)。
复杂性足够了,让我们简单点
如果您使用 jQuery 并且厌倦了围绕灵活宽度视频问题所带来的复杂性,我建议您尝试 FitVids.js。 我与 Dave Rupert 共同编写了这个 jQuery 插件,专门用于解决这个问题。 它使用了与上面解释的完全相同的概念,只是它会自动执行。 这意味着 1)在您编写的标记中没有非语义包装器;2)纵横比与单个视频匹配(并非所有视频都相同)。

FitVids.js 可以开箱即用,适用于所有主要的视频播放器,并且可以非常轻松地扩展以支持任何播放器。
使用 Sublime Video?
我有一篇教程,介绍如何使他们的播放器具有灵活宽度。
使用 MediaElements.js?
MediaElements.js 是一个非常棒的 HTML5 视频播放器,它减轻了我前面提到的 HTML5 视频的一些问题。 具体来说,它提供了一个漂亮的一致播放器皮肤,并能够回退到旧技术来播放视频,例如 Flash 和 Silverlight。 它不是万能药,因为它无法解决移动平台上的平台之争(这些平台通常没有 Flash 或 Silverlight),也不能帮助解决流媒体或质量问题,但它仍然很好。
MediaElements.js 中有很多固定像素计算内容,但我过去已经能够通过一些 !important 覆盖来强制它具有灵活宽度。
.mejs-container {
width: 100% !important;
height: auto !important;
padding-top: 57%;
}
.mejs-overlay, .mejs-poster {
width: 100% !important;
height: 100% !important;
}
.mejs-mediaelement video {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
width: 100% !important;
height: 100% !important;
}
响应式视频?
还记得响应式图片是一个热门话题,因为我们试图负责任地不提供不必要的大图片吗? 视频也存在同样的问题,只是它被...嗯...整个视频中的帧数(可能很多)所加剧。
一个半生不熟的解决方案是根据浏览器窗口宽度提供不同的视频源。 我有一篇关于此的教程。
另一个解决方案是在视频源上使用媒体属性,并希望支持变得更好,并且它不会被删除。
<video controls>
<source src="video-small.mp4" type="video/mp4" media="all and (max-width: 480px)">
<source src="video-small.webm" type="video/webm" media="all and (max-width: 480px)">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
</video>
最好的解决方案是使用视频服务,让他们为您处理。
灵活的音频
您只能“看到” HTML5 音频,前提是您在元素上专门使用 controls 属性。
<audio controls src="audio.ogg">
<p>Fallback.</p>
</audio>
好消息是,您只需将 width: 100%;添加到这个家伙,它就会变得灵活。
audio {
width: 100%;
}
WebKit 浏览器出于某种原因将它们的宽度限制为 800px。 但是播放器仍然保持在该空间内居中。 Opera 和 Firefox 没有这种最大宽度。 它们都具有略微不同的播放器,但基本上都执行相同的操作(播放声音并具有播放和暂停按钮等)。
目前另一个非常流行的嵌入式声音播放器是 SoundCloud 播放器,它默认情况下具有灵活宽度(团队万岁!)。
我并不一定相信响应式设计中网格的整个概念。我现在正在做一个个人项目,放弃了网格方法。当使用默认标记作为具有百分比宽度的容器时,它并不难。Gridless 是一个类似方法的 HTML5 和 CSS3 模板。
我的观点是,你可能用网格模板节省的任何时间在最终得到臃肿且非语义的标记时都是无关紧要的。
我个人也不太喜欢复杂的网格框架,因此,[不要过度思考网格。](https://css-tricks.org.cn/dont-overthink-it-grids/) 但是,如果你有一个 75% 宽的主内容区域和一个 25% 宽的侧边栏,那就是一个网格,现在是时候开始考虑灵活的媒体了。
我同意,也喜欢你关于灵活媒体的文章。我一直以这种方式设置我的图片。我从未将两个百分比宽度的内容块视为网格,但现在我明白了你的意思。
我一定会看看你的另一篇文章。谢谢。
如果你充分利用了像 SASS 这样的 CSS 预处理器,你就不会有臃肿且非语义的标记。
如果使用网格会导致这种情况,那就是没有正确实现。即使是最依赖网格的用户、倡导者或了解如何使用像 SASS 这样的预处理器的公司也会采用使用网格的方法,而不会因为网格而添加太多甚至任何额外的标记。
预处理器是为了解决 vanilla CSS 中的这种问题而构建的,除了让 CSS 开发更快、更简单(最终)和更易于阅读之外。包括 SASS 3.2 中的占位符选择器,基本上没有理由在同一个句子中出现“语义上无用的分类”和“精通预处理器用户”。
Foundation 是一个使用 SASS 和许多混合方法来实现这一点的框架。Bootstrap 甚至允许你这样做,但大多数人不会利用或 bother 使用 LESS 来实现相同(或类似)的效果。如果你自己尝试一下,你会发现你可以将网格与实际内容的类或 id 相关联。
这意味着不需要有“omega3 last”、“grid3”或你可能熟悉的所有与旧网格实现相关的网格类标记。
很棒的文章,资源也很棒。
我在我的灵活 img 类中添加了这一行
width: auto\9; /* ie8 */
我不知道为什么,但它应该能修复一些 IE 的 bug…现在,这真的有必要吗?
题外话
你的“\9”也会被 IE9 识别。不确定你是否知道这一点。
要只针对 IE9 及更高版本,请使用
:root .class/#id { property:value /IE9; }
更多信息请访问:http://blog.vervestudios.co/blog/post/2011/05/13/IE9-Only-CSS-Hack.aspx
两件事
1. 如果你与几乎不了解 HTML5 甚至最佳实践的开发人员合作怎么办?就我个人而言,像这样的文章虽然非常有用且有帮助,但我永远不会使用这里提到的任何内容。失败。
我真的羡慕那些能够使用的人…
2. “带宽媒体查询”不应该只是“带宽查询”吗?
我的意思是,带宽与媒体真的没有关系。
只是说…
感谢你的信息,Chris。
在我看来,HTML5 仍然处于起步阶段。很多人想赶时髦,但很多人并不真正了解最佳实践是什么,以及最佳技术是什么。HTML5 是一个流行语,虽然它带来了一些很棒的东西,但它仍然是一个流行语。另一方面,CSS3…嗯,就说 CSS3 将会彻底改变我们所知道的网络吧。
关于你的后面一点,我对你说到带宽媒体查询的陈述感到困惑。你可以直接说响应式元素。比如他上面列出的那些,比如:视频、音频和图片。就这么简单。
网络正在经历一个以简明性为目标的复兴时期,以对抗未来发展趋势。视网膜显示屏、移动设备等。我们不再生活在一个像素完美的世界上,你最好尽快适应,因为很快,这些实践或演变后的实践将成为一份工作所必需的。把它想象成表格和 Div 之间的斗争。这场战斗持续了数年,直到人们意识到表格很糟糕,它们只适用于表格数据。
感谢你分享这些很棒的技巧,Chris。
昨天我尝试让 fitvid 为 jwplayer 工作,但我无论如何也搞不明白。有没有关于它的文档?看起来它似乎只适用于来自 YouTube 和 Vimeo 等流行托管网站的视频。
一如既往,好东西。我第一次从 Ethan Marcotte 的 An Event Apart 演示中学习到响应式视频技巧。
在上述会议上提到的一个有趣的观点是,响应式设计即将结束。许多开发人员社区的人不再把它看作是一种“潮流”,而是开始意识到(响应式设计)对于所有项目来说都是一个好主意。响应式设计不会消亡,它只会成为开发人员标准工具包的一部分。
像这样的文章对此有所帮助,感谢你花时间撰写它。
Chris,非常棒的博客文章。总是有用,可以获得关于如今响应式设计的更多信息。
我真的很喜欢 Thierry Koblentz 的填充方法来保持响应性。非常非常巧妙。
不错的文章,我正在拥抱响应式设计:),我在让谷歌地图 API JavaScript v3 正常运行方面遇到了一些问题。有没有人成功地让它响应,就像设置 img{max-width:100%} 时 img 的行为一样?
嗯... 好像我以前做过,虽然我让它响应整个浏览器窗口,然后通过 iframe 嵌入它。我已经很久没有这样做过了,我不确定我到底是怎么做的。
有一个 jQuery 插件可以使谷歌地图响应,但我自己没有尝试过,所以我不能告诉你太多,除了文章的链接。
http://joggink.com/2012/01/responsive-google-maps/
一篇关于响应式设计的好文章。我一直在努力在我的工作中采用一些响应式设计技术,这将是其中之一。
很棒的研究,非常有用的信息。谢谢!
这里有很多很棒的技巧…尤其是在那些视频服务方面的技巧…它们看起来很棒…我指的是 Sublime Video 和 MediaElements.js…这些对我来说是新东西…但我会试一试…
我 100% 同意 HTML5 视频…使用 video 标签的纯 HTML5 视频很痛苦…直接使用视频服务吧…对大多数客户来说,这种解决方案效果很好…
@Dave Z: 我最近写了一篇关于使用网格的好方法的文章。关于 Neat,你不需要这种非语义的 HTML:http://stefanvermaas.nl/html-css/designing-html5-pretty-neat-huh/
感谢 Chris 分享这些有用的技巧!
Chris- fitvids.js 是否支持 Google Maps 的 iframe?如果没有,你能添加支持吗?
这篇文章涵盖了你需要的所有内容。=] 我一直在努力创建一个 基本响应式样式表,其中包含大部分内容,包括视频包装器辅助类,比如 class=rwd-wrap-16:9 和 class=rwd-wrap-4:3
您好,
非常感谢。我正在使用 YouTube 的响应式视频嵌入。具体来说,我正在嵌入一个播放列表。
奇怪的是,响应式嵌入后,播放列表只会播放第一个视频。但是,使用 YouTube 提供的默认代码嵌入时,视频像魅力一样循环播放列表。似乎奇怪的是,'width:100%' 应该阻止视频播放,但我找不到其他错误。你可能有什么想法吗?
目前我遇到了一个问题,即 IE 9 会调整引用 svg 文件的图片元素的宽度(
<img src="logo.svg">
),但高度不会缩放,即使使用height: auto;
:'(我真的很需要一个简单的方法来让 Vimeo 视频响应,所以我很高兴找到了你的文章。感谢你的这些技巧,Chris!
Chris 的帖子很棒,一如既往。有一个拼写错误:aspet(aspect)比率(2 次)。
嗨,我是新手,但我真的很喜欢 css-tricks.com。我有一些问题。
我过去使用 display none 来隐藏响应式页面中的图像,但是如果用户屏幕很小,如何动态地阻止图像/对象加载?
你能给点建议吗?也许使用脚本?
谢谢!!
@benny,如果可以不使用 JavaScript 加载图像(这是一个很大的限制),那么你可以创建一个带有
data-image="imagesrc"
的元素,然后使用 JS 修改该元素。例如,使用此 HTML:
<a href="foo" rel="nofollow"></a>
以及此 JS(假设使用 jQuery)
你首先需要检查你的屏幕是否具有正确的宽度,但希望这能让你走上正轨。我在 http://arvadacenter.org 上使用了这种技术。