随着互联网上使用手机的用户数量不断增加,网站设计师越来越需要以适合各种屏幕尺寸的方式排列内容。自适应网页设计(这一概念最初是由 Ethan Marcotte 在 A List Apart 中提出的)是一种设计策略,它通过更改网站的布局以适应所用设备,从而响应用户的需求和设备的功能。例如,自适应网站可能会在手机上以单列视图显示内容,在平板电脑上以双列显示内容,在桌面计算机上以三列或四列显示内容。
由于支持互联网的设备有如此多的可能屏幕尺寸,因此您的网站必须能够适应任何现有或未来的屏幕尺寸,这一点非常重要。现代响应式设计还考虑了触摸屏等交互模式。我们的目标是为所有用户优化体验。
设置视口
对于针对各种设备优化过的网页,其文档标头中必须包含 meta viewport 标记。此标记可告知浏览器如何控制网页尺寸和缩放比例。
为尽力提供最佳体验,移动浏览器会以桌面设备的屏幕宽度(通常大约为 980px
,但不同设备可能会有所不同)来呈现网页,然后再增大字体并将内容缩放为适合屏幕的大小,从而改善内容的呈现效果。这可能会导致字体看起来不一致,并且需要用户放大才能查看内容并与之互动。
<!DOCTYPE html>
<html lang="en">
<head>
…
<meta name="viewport" content="width=device-width, initial-scale=1">
…
</head>
…
使用 meta viewport 值 width=device-width
可指示页面与屏幕宽度(以设备独立像素 [DIP] 为单位)进行匹配,DIP 是一种标准的视觉像素单位(在高密度屏幕上,它可以由许多物理像素组成)。这样,页面便可自动重排内容,使之适合不同的屏幕大小。
某些浏览器会在旋转到横向模式时保持固定的网页宽度,并通过缩放来填满屏幕,而不是自动重排。添加值 initial-scale=1
可指示浏览器在不考虑设备屏幕方向的情况下,将 CSS 像素与设备独立像素的比例设为 1:1,让网页完全占用横向宽度。
不含带 width
或 initial-scale
的 <meta name="viewport">
标记 Lighthouse 审核可帮助您自动确保 HTML 文档正确使用视口元标记。
根据视口调整内容大小
无论在桌面设备上还是在移动设备上,用户都习惯上下滚动网站,而不是横向滚动。如果用户必须横向滚动或缩小页面才能查看整个网页,那么这将给用户带来糟糕的体验。
开发带有视口元标记的移动网站时,开发者很容易在无意间创建出不太适合指定视口的网页内容。例如,如果图像宽度大于视口宽度,那么就会导致横向滚动。为避免出现这种情况,请调整内容以使其适合视口。
未根据视口正确设置内容尺寸 Lighthouse 审核可以帮助您自动检测内容溢出问题。
图片
如果固定尺寸的图片大于视口,则会导致页面滚动。我们建议为所有图片设置 max-width
为 100%
,以缩小图片以适应可用空间,同时防止图片超出其初始大小。
在大多数情况下,您可以通过向样式表中添加以下代码来实现此目的:
img {
max-width: 100%;
display: block;
}
将图片的尺寸添加到 img 元素
即使您设置了 max-width: 100%
,我们仍建议您向 <img>
代码添加 width
和 height
属性,以便浏览器在图片加载之前为其预留空间。这有助于防止布局偏移。
布局
由于不同设备(例如手机和平板电脑之间,甚至不同手机之间)的屏幕尺寸和宽度(以 CSS 像素为单位)差别很大,因此内容不应只在特定视口下正常显示。
过去,这需要以百分比设置布局元素。使用像素测量要求用户在小屏设备上水平滚动:
改用百分比后,在较小的屏幕上,列会变窄,因为每列始终占据屏幕宽度的相同百分比:
现代 CSS 布局技术(例如 Flexbox、网格布局和多列)可以大大简化这些灵活网格的创建。
Flexbox
如果您有一组不同大小的内容,并且希望它们能舒适地排列在一行或多行中,并且较小的内容占用较少空间,较大的内容占用较多空间,请使用 Flexbox。
.items {
display: flex;
justify-content: space-between;
}
您可以使用 Flexbox 将项显示为一行,也可以随着可用空间的减少而换行显示。
CSS 网格布局
CSS 网格布局可创建灵活的网格。您可以使用网格布局和 fr
单位(表示容器中可用空间的一部分)改进前面的浮动示例。
.container {
display: grid;
grid-template-columns: 1fr 3fr;
}
您还可以使用网格布局创建可容纳尽可能多项内容的常规网格布局。随着屏幕尺寸的减小,可用的轨道数量会减少。以下演示展示了一个网格,其中包含每个行上可容纳的尽可能多的卡片,且最小尺寸为 200px
。
多列布局
对于某些类型的布局,您可以使用多列布局 (Multicol),该布局使用 column-width
属性创建自适应数量的列。在以下演示中,当有空间放置另一个 200px
列时,页面会添加列。
使用 CSS 媒体查询实现自适应设计
有时,您可能需要对布局进行更广泛的更改,以支持上述方法不支持的特定屏幕尺寸。这时,媒体查询就派上用场了。
媒体查询是一种简单的过滤器,可应用于 CSS 样式,以便根据渲染内容的设备类型更改这些样式。它们还可以根据设备功能(包括宽度、高度、方向以及设备是否被用作触摸屏)更改样式。
如需为打印提供不同的样式,您可以定位到输出类型,并添加打印样式的样式表:
<!DOCTYPE html>
<html lang="en">
<head>
…
<link rel="stylesheet" href="print.css" media="print">
…
</head>
…
您还可以使用媒体查询在主样式表中添加打印样式:
@media print {
/* print styles go here */
}
对于响应式网站设计,最常见的查询是设备功能,因此您可以针对触摸屏或较小屏幕自定义布局。
根据视口大小应用媒体查询
借助媒体查询,您可以打造自适应体验,将特定样式应用于特定屏幕尺寸。针对屏幕尺寸的查询可以测试以下内容:
width
(min-width
、max-width
)height
(min-height
、max-height
)orientation
aspect-ratio
所有这些功能都具有出色的浏览器支持。如需了解更多详情(包括浏览器支持信息),请参阅 MDN 上的width、height、orientation 和 aspect-ratio。
根据设备功能的媒体查询
鉴于可用设备的范围,开发者不能假定每部大型设备都是普通桌面设备或笔记本电脑,也不能假定每部小型设备都使用触摸屏。媒体查询规范中新增了一些功能,可让您测试各种功能,例如用于与设备互动的指针类型,以及用户能否将指针悬停在元素上。
hover
pointer
any-hover
any-pointer
尝试在不同的设备(例如普通桌面设备、手机或平板电脑)上查看此演示。
所有新型浏览器都对这些新功能提供了良好支持。如需了解详情,请参阅 MDN 页面中的 hover、any-hover、pointer 和 any-pointer。
使用 any-hover
和 any-pointer
any-hover
和 any-pointer
功能用于测试用户能否将指针悬停在元素上(通常称为“悬停”),或者能否使用指针(即使指针不是用户与设备互动的主要方式)。使用这些功能时要非常小心,例如避免强制触摸屏用户切换到鼠标。不过,如果确定用户使用的是哪种类型的设备非常重要,any-hover
和 any-pointer
可能会很有用。例如,具有触摸屏和触控板的笔记本电脑应支持粗略和精细指针,以及悬停功能。
如何选择断点
请勿根据设备类别或任何产品、品牌名称或操作系统定义断点。这会使代码难以维护。而是让内容决定其布局如何更改以适应容器。
以从小屏幕开始、不断扩展的方式选择主要断点
先针对小屏幕尺寸进行内容设计,然后扩展至不同尺寸的屏幕,直到必须添加断点为止。这样一来,您就可以尽可能减少页面上的断点数量,并根据内容对其进行优化。
以下示例将逐步介绍本页开头的“天气预报”微件示例。第一步是使天气预报在小屏幕上呈现效果良好:
接下来,调整浏览器大小,直到元素之间的空白过多,widget 看起来不美观为止。具体应调整到多大在某种程度上由主观决定,但超过 600px
肯定就过宽了。
如需在 600px
处插入断点,请在组件的 CSS 末尾创建两个媒体查询:一个用于浏览器宽度不超过 600px
时,另一个用于浏览器宽度超过 600px
时。
@media (max-width: 600px) {
}
@media (min-width: 601px) {
}
最后,重构 CSS。在 600px
的 max-width
媒体查询内,添加仅适用于小屏幕的 CSS。在 601px
的 min-width
媒体查询内,为大屏幕添加 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 个单词时,请考虑添加断点。
在此示例中,大小为 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 有一个内置功能,可显示页面在不同断点下的显示效果。
如需查看网页在不同断点下的外观,请执行以下操作:
- 打开开发者工具。
- 开启设备模式。 默认情况下,此页面会以自适应模式打开。
- 如需查看媒体查询,请打开“Device Mode”菜单,然后选择Show media queries。这会将断点显示为网页之上的彩色横杠。
- 点击其中一个横杠便可在该媒体查询处于活动状态时查看网页。 右键点击某个条形可跳至该媒体查询的定义。