跳到主要内容

响应式设计(responsive web design, RWD)指的是允许 Web 页面适应不同屏幕宽度因素等,进行布局和外观的调整的一些列双离合集。可以让页面能更好的给到观者使用体验。

响应式 Web 设计不是单独的技术,它是描述 Web 设计的一种方式、或者是一组最佳实践的一个词,它用来建立可以响应查看内容的一个词。

结合媒体查询可以让开发者使用同一套代码实现多端的展示。

一、 媒体查询(Media Queries)

根据设备的特性(宽度、高度、分辨率等)应用不同的 CSS。语法为 @media () {}

常见断点为(320px 手机、768px 平板、1200px 桌面),遵循“移动优先”(先写移动端样式,再用 min-width 扩展)。

建立在大于 800px 的媒体查询
@media screen and (min-width: 800px) {
.container {
margin: 1rem 2rem;
}
}

二、 相对单位

相对于 pxcmmm等用户固定布局的绝对单位,相对单位实用性更强。

  • em: 相对于父元素字体的大小(嵌套时易混乱)
  • rem:相对于跟元素(html)字体大小(响应式布局常用)
  • vw/vh:相对于视口宽度/高度的 1% (全局布局常用)
  • %:相对于父元素对应属性的百分比 (宽度依赖父元素宽度、高度依赖于父元素高度)
  • vmax:以百分比表示 vwvh 的最大值()
  • vmin:以百分比表示 vwvh 的最小值
  • 特别是 rem 在响应式设计中的优势

三、 视口(Viewport)

在移动设备和其他窄屏设备中,某些内容在普通屏幕更宽的虚拟窗口或视口中渲染页面,然后缩小渲染的结果,以便可以一次看到所有的内容。然后,用户可以平移和缩放以查看不同的区域(手持端浏览器类似于“以电脑版打开”)。

这是由于并非所有页面都针对移动设备进行了优化,并且以最小的视口宽度渲染时会被截断。虚拟视口则是一种使非移动设备优化页面在窄屏设备上开起来更好的一个方法。(向后兼容)

但是,此机制不太适用于使用媒体查询针对窄屏幕进行优化的页面。

<meta name="viewport" content="width=device-width, initial-scale=1.0"> 确保移动端正确解析屏幕宽度,避免默认缩放,width=device-width 使视口宽度等于设备宽度。

"viewport" meta 标签的基本属性如下:

  • width:控制视口大小。这可以设置为特定的像素(如 width=600),也可以设置为特殊值 device-width,即 100vw ,100% 的视口宽度。最小值为 1,最大值为 10000 ,负值将被忽略
  • height:制视口大小。这可以设置为特定的像素(如 height=600),也可以设置为特殊值 device-height,即 100vh ,100% 的视口宽度。最小值为 1,最大值为 10000 ,负值将被忽略
  • initial-scale:控制页面首次加载时显示的缩放倍数。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略
  • minimum-scale:控制页面允许缩小的倍数。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略
  • maximum-scale:控制页面允许放大的倍数。设置一个低于 3 的值将不具备无障碍访问性。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略
  • user-scalable:控制是否允许页面上的放大和缩小操作。有效值为 01yesno。默认值为 1,与 yes 相同。将值设置为 0(即与 no 相同)将违反 Web 内容无障碍指南(WCAG)
  • interactive-widget:指定交互式 UI 组件(如虚拟键盘)对页面视口的影响。有效值:resizes-visualresizes-contentoverlays-content。默认值:resizes-visual

四、 响应式图片

1. 分辨率切换:不同的尺寸

使用 srcsetsizes 来提供额外的资源图像和提示,帮助浏览器选择最合适的资源。

html(复制于 MDN)
<img
srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w"
sizes="(max-width: 600px) 480px,
800px"
src="elva-fairy-800w.jpg"
alt="Elva dressed as a fairy"
/>

sizes 定义了一组媒体条件(例如屏幕宽度)并且指明当前某些媒体条件为真时,什么样的图片尺寸是最佳选择。

有了这些属性,浏览器会:

  • 查看屏幕尺寸、像素密度、缩放级别、屏幕方向和网络速度
  • 找出 sizes 列表中第一个为真的媒体条件
  • 查看该媒体查询对应的插槽大小
  • 加载 srcset 列表中引用的与插槽大小相同的图片,如果没有,则加载第一个大于所选插槽大小的图片
备注

如果支持响应式图片的浏览器以 480px 的视口来加载页面,那么 (max-width: 600px) 的媒体条件为真,因此 480px 的插槽会被选择,继而将加载 elva-fairy-480w.jpg,因为该图片的固有宽度(480w)最接近于插槽宽度。800px 的照片大小为 128KB,而 480px 版本仅有 63KB 大小——节省了 65KB

2. 分辨率切换:相同的尺寸,不同的分辨率

使用 srcset 结合 x 描述符,而不是 sizes ,来让浏览器选择合适分辨率的图片。

复制于 MDN
<img
srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x"
src="elva-fairy-640w.jpg"
alt="Elva dressed as a fairy"
/>

3. 美术设计(<picture>

复制于 MDN
<picture>
<!-- 如果视口的宽度为 799px 或者更少,会显示第一张 -->
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg" />
<!-- 如果视窗宽度是 800px 或更大,就显示第二张图片 -->
<source media="(min-width: 800px)" srcset="elva-800w.jpg" />
<!-- -->
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva" />
</picture>
  • source 元素包含一个 media 属性,这一属性包含一个媒体条件---就像第一个 srcset 例子那样,这些条件决定那张图片会显示---第一个条件为真的图片会显示。
  • srcset 属性包含要显示图片的路径。
  • 在任何条件下,都应在 <picture> 标签最后提供一个 <img> 标签一个它的 srcalt 属性,否则图片可能在媒体条件都不为真、浏览器不支持 <picture> 时不显示。

4. 为什么不使用 CSS 或 JavaScript 来控制

当浏览器开始加载时,它会在主解析器开始加载和解释页面的 CSS 和 JavaScript 之前,预先加载(预加载)所有图片。这种机制通常有助于减少页面的加载时间,但对于响应式图像并不有用,因此需要实现类似 srcset 的解决方案。

提示

如果使用 <img> 元素,然后使用 JavaScript 检测视口宽度,然后再根据需要动态更改源图像为较小的图像。

这时候,原始图像已经被加载,如果又加载小图像,则是属于南辕北辙的优化。