响应式 Web 设计基础知识

随着互联网上手机用户的数量不断增加,对于 Web 设计师来说,以适合各种屏幕尺寸的方式布局内容变得越来越重要。响应式 Web 设计最初由 Ethan Marcotte 在 A List Apart 中定义,是一种设计策略,通过更改网站的布局以适应正在使用的设备,从而响应用户的需求及其设备的功能。例如,响应式站点可能会在手机上以单列视图显示内容,在平板电脑上以两列视图显示内容,在台式计算机上以三列或四列视图显示内容。

随着屏幕变宽,小部件会响应地改变形状。

由于支持互联网的设备有如此多的屏幕尺寸,因此您的网站必须适应任何现有或未来的屏幕尺寸。现代响应式设计还考虑了触摸屏等交互模式。目标是优化每个人的体验。

设置视口

针对各种设备优化的页面必须在文档的 head 中包含一个 meta 视口标记。此标记告诉浏览器如何控制页面的尺寸和缩放。

为了尽力提供最佳体验,移动浏览器以桌面屏幕宽度(通常约为 980px,尽管这因设备而异)渲染页面,然后尝试通过增加字体大小和缩放内容以适合屏幕来使内容看起来更好。这可能会使字体看起来不一致,并要求用户放大才能查看内容并与之交互。

<!DOCTYPE html>
<html lang="en">
  <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
      </head>
  

使用 meta 视口值 width=device-width 告诉页面在设备无关像素 (DIP) 中匹配屏幕的宽度,DIP 是一种标准的视觉像素单位(在高密度屏幕上可以由许多物理像素组成)。这使页面可以重排内容以匹配不同的屏幕尺寸。

Screenshot of a
    page with the text hard to read because it's very zoomed out.
没有视口 meta 标记的页面加载时会非常缩小,导致文本难以阅读。 请参阅 Glitch 上的此示例
Screenshot of
    the same page with the text at a size that can be read.
设置视口 meta 标记后,您可以无需放大即可阅读页面。 请参阅 Glitch 上的此示例

某些浏览器在旋转到横向模式时保持页面宽度不变,并缩放以填充屏幕,而不是重排。添加值 initial-scale=1 告诉浏览器设置 CSS 像素和设备无关像素之间 1:1 的关系,而与设备方向无关,从而使页面能够利用完整的横向宽度。

不包含带有 <meta name="viewport"> 标记以及 widthinitial-scale 的标记 Lighthouse 审核可以帮助您自动化确保 HTML 文档正确使用视口 meta 标记的过程。

调整内容大小以适应视口

在桌面设备和移动设备上,用户都习惯于垂直滚动网站,而不是水平滚动网站。强迫用户水平滚动或缩小以查看整个页面会导致糟糕的用户体验。

在开发带有 meta 视口标记的移动网站时,通常会意外创建页面内容,使其无法完全适应指定的视口。例如,宽度大于视口显示的图像可能会导致水平滚动。为防止这种情况,请调整您的内容以使其适合视口内部。

内容大小未针对视口正确调整 Lighthouse 审核可以帮助您自动化检测溢出内容的过程。

图片

具有固定尺寸的图像如果大于视口,则会导致页面滚动。我们建议为所有图像设置 max-width100%,这会缩小图像以适应可用空间,同时防止它们拉伸超出其初始大小。

在大多数情况下,您可以通过将以下内容添加到样式表中来完成此操作

img {
  max-width: 100%;
  display: block;
}

将图像的尺寸添加到 img 元素

即使您设置了 max-width: 100%,我们仍然建议在您的 <img> 标记中添加 widthheight 属性,以便浏览器可以在图像加载之前为其预留空间。这有助于防止布局偏移

布局

由于 CSS 像素的屏幕尺寸和宽度在设备之间差异很大(例如,手机和平板电脑之间,甚至不同手机之间),因此内容不应依赖于特定的视口宽度来良好呈现。

过去,这需要以百分比设置布局元素。使用像素测量需要用户在小屏幕上水平滚动

Screenshot of a two-column layout with most of the second column outside the viewport
使用像素的浮动布局。 请参阅 Glitch 上的此示例

改为使用百分比会使列在较小的屏幕上更窄,因为每列始终占据屏幕宽度的相同百分比

现代 CSS 布局技术(如 Flexbox、Grid Layout 和 Multicol)使创建这些灵活的网格变得更加容易。

Flexbox

当您有一组不同大小的项目,并且希望它们舒适地排列在一行或多行中时,请使用 Flexbox,较小的项目占用较少的空间,而较大的项目占用更多的空间。

.items {
  display: flex;
  justify-content: space-between;
}

您可以使用 Flexbox 将项目显示为单行,或在可用空间减少时换行到多行。

阅读有关 Flexbox 的更多信息.

CSS Grid Layout

CSS Grid Layout 创建灵活的网格。您可以使用网格布局和 fr 单位来改进早期的浮动示例,fr 单位表示容器中可用空间的一部分。

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

您还可以使用 Grid Layout 创建规则的网格布局,其中包含尽可能多的项目。随着屏幕尺寸的减小,可用轨道数也会减少。以下演示显示了一个网格,其中每行包含尽可能多的卡片,最小尺寸为 200px

阅读有关 CSS Grid Layout 的更多信息

多列布局

对于某些类型的布局,您可以使用多列布局 (Multicol),它使用 column-width 属性创建响应式列数。在以下演示中,当有空间容纳另一列 200px 列时,页面会添加列。

阅读有关 Multicol 的更多信息

使用 CSS 媒体查询来实现响应式

有时,您可能需要对布局进行更广泛的更改,以支持某些屏幕尺寸,而不仅仅是前面描述的技术所允许的更改。这就是媒体查询变得有用的地方。

媒体查询是您可以应用于 CSS 样式的简单过滤器,以根据呈现内容的设备类型来更改这些样式。它们还可以根据设备功能(包括宽度、高度、方向以及设备是否用作触摸屏)来更改样式。

要为打印提供不同的样式,您可以定位输出类型并包含打印样式的样式表

<!DOCTYPE html>
<html lang="en">
  <head>
        <link rel="stylesheet" href="print.css" media="print">
      </head>
  

您还可以使用媒体查询在主样式表中包含打印样式

@media print {
  /* print styles go here */
}

对于响应式 Web 设计,最常见的查询是设备功能,因此您可以自定义触摸屏或较小屏幕的布局。

基于视口大小的媒体查询

媒体查询使您可以创建响应式体验,将特定样式应用于特定屏幕尺寸。屏幕尺寸查询可以测试以下内容

  • width (min-width, max-width)
  • height (min-height, max-height)
  • 方向
  • 纵横比

所有这些功能都具有出色的浏览器支持。有关更多详细信息,包括浏览器支持信息,请参阅 MDN 上的 widthheightorientationaspect-ratio

基于设备功能的媒体查询

鉴于可用设备的范围,开发人员不能假设每个大型设备都是常规台式机或笔记本电脑,或者每个小型设备都使用触摸屏。媒体查询规范的一些新增功能使您可以测试诸如用于与设备交互的指针类型以及用户是否可以将指针悬停在元素上方等功能。

  • hover
  • pointer
  • any-hover
  • any-pointer

尝试在不同设备(例如常规台式计算机和手机或平板电脑)上查看此演示。

这些较新的功能在所有现代浏览器中都具有良好的支持。在 MDN 页面上了解更多信息:hoverany-hoverpointerany-pointer

使用 any-hoverany-pointer

功能 any-hoverany-pointer 测试用户是否可以将指针悬停在元素上方(通常称为悬停),或者是否可以使用指针,即使它不是他们与设备交互的主要方式。使用这些功能时要非常小心,例如,避免强迫触摸屏用户切换到鼠标。但是,如果确定用户拥有的设备类型很重要,则 any-hoverany-pointer 可能很有用。例如,具有触摸屏和触控板的笔记本电脑应匹配粗略和精细指针,以及悬停能力。

如何选择断点

不要根据设备类别或任何产品、品牌名称或操作系统来定义断点。这会使您的代码难以维护。相反,让内容决定其布局如何更改以适应容器。

从小处着手,然后逐步向上,选择主要断点

首先设计内容以适应小屏幕尺寸,然后扩大屏幕,直到需要断点。这使您可以最大程度地减少页面上的断点数量,并根据内容优化它们。

以下示例逐步介绍了本页开头的天气预报小部件示例。第一步是使预报在小屏幕上看起来不错

Screenshot of
    a weather app at a mobile width
窄宽度下的应用。

接下来,调整浏览器大小,直到元素之间有太多空白区域,使小部件看起来不好看。该决定是主观的,但超过 600px 肯定太宽了。

Screenshot of
    a weather app with wide gaps between items
在此尺寸下,应用的布局可能应该更改。

要在 600px 处插入断点,请在组件 CSS 的末尾创建两个媒体查询:一个在浏览器为 600px 或更窄时使用,另一个在浏览器宽度大于 600px 时使用。

@media (max-width: 600px) {

}

@media (min-width: 601px) {

}

最后,重构 CSS。在 max-width600px 的媒体查询内,添加仅适用于小屏幕的 CSS。在 min-width601px 的媒体查询内,添加适用于较大屏幕的 CSS。

必要时选择次要断点

除了在布局发生重大更改时选择主要断点之外,调整次要更改也很有帮助。例如,在主要断点之间,调整元素上的边距或内边距,或增加字体大小,以使其在布局中感觉更自然可能会有所帮助。

此示例遵循与上一个示例相同的模式,从优化较小的屏幕布局开始。首先,在视口宽度大于 360px 时提高字体。之后,当有足够的空间时,您可以将高温和低温分开,使它们位于同一行,并使天气图标更大。

@media (min-width: 360px) {
  body {
    font-size: 1.0em;
  }
}

@media (min-width: 500px) {
  .seven-day-fc .temp-low,
  .seven-day-fc .temp-high {
    display: inline-block;
    width: 45%;
  }

  .seven-day-fc .seven-day-temp {
    margin-left: 5%;
  }

  .seven-day-fc .icon {
    width: 64px;
    height: 64px;
  }
}

对于大屏幕,我们建议限制预报面板的最大宽度,使其不占用整个屏幕宽度。

@media (min-width: 700px) {
  .weather-forecast {
    width: 700px;
  }
}

优化文本以方便阅读

经典的易读性理论表明,理想的列应包含每行 70 到 80 个字符(在英语中约为 8 到 10 个单词)。请考虑在文本块的宽度超过约 10 个单词时添加断点。

Screenshot of a
    page of text on a mobile device
移动设备上的文本。
Screenshot of a a page of text on a desktop browser
在桌面浏览器中添加了断点以约束行长的相同文本。

在此示例中,1em 的 Roboto 字体在较小的屏幕上每行产生 10 个单词,但较大的屏幕需要断点。在这种情况下,如果浏览器宽度大于 575px,则理想的内容宽度为 550px

@media (min-width: 575px) {
  article {
    width: 550px;
    margin-left: auto;
    margin-right: auto;
  }
}

避免隐藏内容 (:#avoid-hiding-content)

在选择根据屏幕尺寸隐藏或显示哪些内容时,请务必小心。不要仅仅因为屏幕上放不下内容而隐藏内容。屏幕尺寸无法预测用户可能想看什么。例如,从天气预报中删除花粉计数对于春季过敏症患者来说可能是一个严重的问题,他们需要该信息来决定是否可以外出。

在 Chrome DevTools 中查看媒体查询断点

设置媒体查询断点后,请检查它们如何影响网站的外观。您可以调整浏览器窗口大小以触发断点,但 Chrome DevTools 具有内置功能,可显示页面在不同断点下的外观。

Screenshot of DevTools with our weather app open and a width of 822 pixels selected.
DevTools 显示较宽视口尺寸下的天气应用。
Screenshot of DevTools with our weather app open and a width of 436 pixels selected.
DevTools 显示较窄视口尺寸下的天气应用。

要在不同断点下查看您的页面

  1. 打开 DevTools.
  2. 启用设备模式。默认情况下,这会在响应式模式下打开。
  3. 要查看您的媒体查询,请打开设备模式菜单并选择显示媒体查询。这会将您的断点显示为页面上方的彩色条。
  4. 单击其中一个条以在媒体查询处于活动状态时查看您的页面。右键单击一个条以跳转到该媒体查询的定义。