响应式设计
响应式网页设计(responsive web design,RWD),RWD 指的是允许 Web 页面适应不同屏幕宽度因素等,进行布局和外观的调整的一系列实践。
响应式 Web 设计不是单独的技术,它是描述 Web 设计的一种方式、或者是一组最佳实践的一个词,它是用来建立可以响应查看内容的设备的样式的一个词。
媒体查询
媒体查询基础
@media 媒体类型 and (媒体特征规则) {
/* CSS rules go here */
}
它由以下部分组成:
- 一个媒体类型,告诉浏览器这段代码是用在什么类型的媒体上的(例如印刷品或者屏幕);
- 一个媒体特征规则,是一个被包含的 CSS 生效所需的规则或者测试;
- 一组 CSS 规则,会在测试通过且媒体类型正确的时候应用。
媒体类型
你可以指定的媒体类型为:
- all,所有设备
- print,打印机设备
- screen,屏幕设备
- speech,语音识别设备
媒体类型是可选的,如果你没有在媒体查询中指示一个媒体类型的话,那么媒体查询默认会设为用于全部媒体类型。
媒体特征规则
宽
当屏幕宽度正好等于 600px 时触发
@media screen and (width: 600px) {
body {
color: red;
}
}
当屏幕宽度至少有 800px 时触发(大于等于 800px)
@media screen and (min-width: 800px) {
.container {
margin: 1em 2em;
}
}
当屏幕宽度最大为 400px 时触发(小于等于 400px)
@media screen and (max-width: 400px) {
body {
color: blue;
}
}
分辨率(dpi)
当屏幕的分辨率大于 192dpi(dpi 表示一英寸 192 个点,192dpi 是苹果视网膜屏幕的 dpi,以此当作一个参考值) 时触发:
@media (min-resolution: 192dpi) {
body {
color: blue;
}
}
朝向
设备处于横放时触发
@media (orientation: landscape) {
body {
color: rebeccapurple;
}
}
设备处于竖放时触发
@media (orientation: portrait) {
body {
color: rebeccapurple;
}
}
有光标的设备
用户使用有光标的设备时触发:
@media (hover: hover) {
body {
color: rebeccapurple;
}
}
媒体特征条件之间的逻辑
与
使用 and 表示与
@media screen and (min-width: 400px) and (orientation: landscape) {
body {
color: blue;
}
}
或
使用逗号表示或
@media screen and (min-width: 400px), screen and (orientation: landscape) {
body {
color: blue;
}
}
非
使用 not 表示非,直接反转了整个媒体查询的含义。因而在下面的例子中,文本只会在朝向为竖着的时候变成蓝色。
@media not all and (orientation: landscape) {
body {
color: blue;
}
}
断点
引入媒体查询的点就叫做断点。
@media screen (min-width: 400px) {}
比如这个媒体查询的断点为 400px
如何确定断点?
- (不推荐)根据某些具体的设备决定,如:iphone\ipad 竖屏\ipad 横屏\macbook
- (较推荐)将类似的设备分类而决定,如:手机\平板横屏\平板竖屏\笔记本
- (推荐)根据你的页面布局决定断点,如:对于桌面优先开发,逐渐缩小屏幕宽度,直到布局出现问题,此处便是断点的位置
移动优先?桌面优先?
泛泛地说,你可以采用两种方式实现响应式设计。你可以从桌面或者最宽的视图开始,然后随着视口变得越来越小,加上断点,把物件挪开;你也可以从最小的视图开始,随着视口变得越来越大,增添布局内容。第二种方式被叫做移动优先的响应式设计,很多时候是最值得仿效的做法。
用在最小的那个设备上的视图很多时候都是一个简单的单列内容,很像正常文本流显示的那样。这意味着,你很可能不需要为小设备做多少布局设计,合适地安排下你的源代码,默认情况下你就可以得到可读的布局。
主要考虑以下几点:
- 用户主要在移动端还是桌面端
- 客户一般更喜欢桌面端的网页原型
- 移动端布局简单,开发迅速
真的需要媒体查询吗?
弹性盒、网格和多栏布局都给了你建立可伸缩的甚至是响应式组件的方式,而不需要媒体查询。这些布局方式能否在不加入媒体查询的时候实现你想要的设计,总是值得考虑的一件事。
例如,你可能想要一组卡片,至少为二百像素宽,并在主文章里尽可能多地放下这些二百像素的卡片。这可以用网格布局实现,而完全不使用媒体查询。
grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
响应式布局
最初,只能通过浮动实现网格,解决响应式布局问题:
- 浮动网格(早期时候使用)
后来出现了现代布局技术:
- 多列布局
- 弹性盒子
- 网格布局
响应式图像
最简单的响应式图像处理:
img {
max-width: 100%;
}
max-width 可以限制图像的最大宽度,结合百分比属性值可以实现响应式图像,但这种方法有以下弊端:
- 图像有可能会显示得比它的原始尺寸小很多,以至于浪费带宽
- 有时候,你可能不想在移动端和桌面端有相同的图像宽高比例
后来的响应式图像,使用 <picture> 元素和 <img> 的 srcset 和 sizes 特性,很好地解决了这两个问题。HTML 中的响应式图像分为以下三种:
- DRP(设备像素比)越大,分辨率越大
- 图像尺寸越大,分辨率越大
- 美术风格:对于小屏设备,图像需要进行裁剪,从而突出图像内容主体
CSS 中也可以通过媒体查询实现响应式图像
响应式排版
响应式排版,是指实现响应式的字体。
例如,你可以通过媒体查询,在大屏幕上显示字体更大的标题,在小屏幕上显示较小的标题
或者,可以通过视口单位(vw)实现响应式排版:
h1 {
font-size: 6vw;
}
但是这样会产生问题,因为文本总是随着视口的大小改变大小,用户失去了缩放任何使用 vw 单位的文本的能力。当视口过窄时,会出现标题比正文小的情况。永远都不要只用 viewport 单位设定文本
h1 {
font-size: calc(1.5rem + 3vw);
}
以上是解决办法。使用了 calc(),如果你将 vw 单位加到了使用固定大小(例如 em 或者 rem)的值,那么文本仍然是可放缩的。
视口元标签
<meta name="viewport" content="width=device-width,initial-scale=1" />
这个元标签告诉移动端浏览器:
- width:可视区域的宽度为设备的宽度。
- intial-scale:页面首次被显示是可视区域的缩放级别,取值 1.0 则页面按实际尺寸显示,无任何缩放
元标签还可以设置以下值:
- minimum-scale:设定最小缩放级别。
- maximum-scale:设定最大缩放级别。
- user-scalable:如果设为 no 的话阻止缩放。
你应该避免使用 minimum-scale、maximum-scale,尤其是将 user-scalable 设为 no。用户应该有权力尽可能大或小地进行缩放,阻止这种做法会引起访问性问题。
为何需要 width=device-width?因为移动端浏览器倾向于在它们的视口宽度上说谎。原来 iPhone 发布以后,人们开始在小的手机屏幕上阅览网页,而大多数站点未对移动端做优化的缘故。移动端浏览器因此会把视口宽度设为 960 像素。通过设定 width=device-width,你用设备的实际宽度覆写了苹果默认的 width=960px,然后你的媒介查询也会像预期那样生效。