自适应设计基础知识

随着使用手机上网的用户数量不断增加,网页设计师越来越需要以适合各种屏幕尺寸的方式来布局内容。自适应网页设计最初由 Ethan Marcotte 在 A List Apart 中定义,是一种设计策略,通过更改网站布局来适应所用设备,从而满足用户需求和设备功能。例如,自适应网站可能会在手机上以单列视图显示内容,在平板电脑上以双列视图显示内容,而在桌面计算机上以三列或四列视图显示内容。

随着屏幕变宽,微件会相应地改变形状。

由于支持互联网的设备有许多可能的屏幕尺寸,因此您的网站必须能够适应任何现有或未来的屏幕尺寸。现代自适应设计还考虑了触控屏等互动模式。我们的目标是为所有用户优化体验。

设置视口

针对各种设备优化的网页必须在文档的标头中包含视口元标记。此标记可告知浏览器如何控制网页的尺寸和缩放比例。

为了尽可能提供最佳体验,移动设备浏览器会以桌面设备屏幕宽度(通常约为 980px,不过具体数值因设备而异)呈现网页,然后尝试通过放大字体和缩放内容以适应屏幕来使内容看起来更美观。这可能会导致字体看起来不一致,并需要用户放大才能看到内容以及与内容互动。

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

使用元视口值 width=device-width 可告知网页将屏幕宽度与设备无关像素 (DIP)(一种标准视觉像素单位,在高密度屏幕上可由许多物理像素组成)相匹配。这样一来,网页就可以重新排布内容,以适应不同的屏幕尺寸。

一个页面,上面的文字难以看清,因为页面被大幅缩小。
未添加视口元标记的网页加载时会非常缩小,导致文字难以阅读。
同一页面,但文字大小可读。
设置视口元标记后,您无需放大即可阅读网页内容。

某些浏览器在旋转到横屏模式时会保持网页宽度不变,并通过缩放来填充屏幕,而不是重新排版。添加值 initial-scale=1 可告知浏览器,无论设备方向如何,都要在 CSS 像素和与设备无关的像素之间设置 1:1 的关系,从而让网页充分利用整个横向宽度。

“没有包含 widthinitial-scale<meta name="viewport"> 标记”Lighthouse 审核可帮助您自动执行以下流程:确保 HTML 文档正确使用视口元标记。

调整内容大小,使其适合视口

无论是桌面设备还是移动设备,用户都习惯于垂直滚动浏览网站,而不是水平滚动。强制用户横向滚动或缩小页面以查看整个页面会导致糟糕的用户体验。

使用视口元标记开发移动版网站时,经常会意外创建无法完全适应指定视口的网页内容。例如,如果显示的图片宽度大于视口宽度,则可能会导致水平滚动。为防止出现这种情况,请调整内容以使其适合视口。

未根据视口正确设置内容尺寸 Lighthouse 审核可以帮助您自动检测溢出的内容。

图片

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

在大多数情况下,您可以通过在样式表中添加以下内容来实现此目的:

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

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

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

布局

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

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

双列布局,其中第二列的大部分内容位于视口之外
使用像素的浮动布局。在 CodePen 上查看此示例

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

借助 flexbox、网格布局和多列等现代 CSS 布局技术,可以更轻松地创建这些灵活的网格。

Flexbox

如果您有一组大小不同的内容,并且希望它们舒适地排列在一行或多行中,其中较小的内容占用较少的空间,较大的内容占用较多的空间,请使用 Flexbox。

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

您可以使用 Flexbox 将内容显示为单行,或者随着可用空间减少,将内容换行到多行。

详细了解 Flexbox

CSS 网格布局

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

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

您还可以使用网格来创建常规网格布局,其中包含尽可能多的项。随着屏幕尺寸的减小,可用轨道数量也会减少。以下演示展示了一个网格,其中包含的卡片数量与每行可容纳的卡片数量相同,最小尺寸为 200px

详细了解 CSS 网格布局

多列布局

对于某些类型的布局,您可以使用多列布局 (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 */
}

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

基于视口大小的媒体查询

借助媒体查询,您可以打造自适应体验,将特定样式应用于特定屏幕尺寸。屏幕尺寸查询可以测试以下内容:

  • widthmin-widthmax-width
  • heightmin-heightmax-height
  • orientation
  • aspect-ratio

基于设备功能的媒体查询

鉴于设备的种类繁多,开发者不能假设每台大型设备都是常规的桌面设备或笔记本电脑,也不能假设每台小型设备都使用触摸屏。媒体查询规范中新增了一些功能,可用于测试以下特性:用于与设备互动的指针类型,以及用户是否可以将指针悬停在元素上。

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

尝试在不同设备上查看此演示,例如常规桌面设备以及手机或平板电脑。

所有现代浏览器都对这些新功能提供良好的支持。如需了解详情,请访问 MDN 页面,查看 hoverany-hoverpointerany-pointer

使用 any-hoverany-pointer

功能 any-hoverany-pointer 用于测试用户是否可以将指针悬停在元素上(通常称为“悬停”),或者是否可以使用指针(即使指针不是用户与设备互动的主要方式)。使用这些功能时请务必小心,例如,避免强迫触屏用户改用鼠标。 不过,如果需要确定用户使用的是哪种设备,any-hoverany-pointer 可能会很有用。例如,配备触屏和触控板的笔记本电脑应匹配粗略指针和精细指针,并支持悬停。

如何选择断点

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

从小处着手,逐步确定主要断点

先设计适合小屏幕尺寸的内容,然后扩大屏幕,直到需要断点为止。这样一来,您就可以尽可能减少页面上的断点数量,并根据内容优化这些断点。

以下示例将逐步介绍本页开头的天气预报 widget 示例。第一步是在小屏幕上呈现良好的天气预报效果:

宽度为移动设备宽度的天气应用
应用处于窄宽度状态。

接下来,调整浏览器大小,直到元素之间有太多空白,导致 widget 看起来不美观。此决定具有主观性,但超过 600px 肯定太宽了。

天气应用,项目之间有较大间距
在此尺寸下,应用的布局可能需要更改。

如需在 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 个字时添加一个断点。

移动设备上的一个文本页面
移动设备上的文字。
桌面浏览器上的一页文字
桌面浏览器中的相同文本,添加了断点以限制行长度。

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

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

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

请谨慎选择要根据屏幕尺寸隐藏或显示的内容。 不要仅仅因为内容无法完全显示在屏幕上就隐藏内容。屏幕尺寸无法预测用户可能想看的内容。例如,如果天气预报中没有花粉数量,对于需要根据该信息来决定是否可以外出的春季过敏患者来说,这可能是一个严重的问题。

在 Chrome 开发者工具中查看媒体查询断点

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

打开天气应用的开发者工具,并选择 822 像素的宽度。
开发者工具显示了在较大视口尺寸下的天气应用。
打开天气应用的开发者工具,并选择宽度为 436 像素。
开发者工具显示天气应用在较窄的视口大小下的状态。

如需在不同断点下查看网页,请执行以下操作:

  1. 打开开发者工具
  2. 开启设备模式。 默认情况下,此页面会在自适应模式下打开。
  3. 如需查看媒体查询,请打开“设备模式”菜单,然后选择显示媒体查询。 这会在网页上方以彩色条显示您的断点。
  4. 点击其中一个条形图,即可在相应媒体查询处于有效状态时查看您的网页。 右键点击某个条形图即可跳转到相应媒体查询的定义。