【前端基础】1 - 16 响应式设计
§1-16 响应式设计
1-16.1 响应式设计简述
响应式设计并不是一个 Web 技术,而是一种 Web 设计的一种方式。响应式设计允许 Web 页面适应不同的屏幕宽度因素等,进行布局和外观的调整的一系列实践。
MDN 上的响应式设计文章:响应式设计 - 学习 Web 开发 | MDN (mozilla.org)
“响应式设计” 一词由 Ethan Marcotte 在 2010 年提出,他将其描述为三种技术的混合使用:液态网格、液态图像、媒体查询。
1-16.2 媒体查询
在上一节我们已经学习使用媒体查询检测视口的宽度从而执行差异化的 CSS,但所使用的检测方式是检测固定的视口尺寸,这在实际中并不可取。相反,我们会利用媒体查询检测视口宽度所在的区间范围。
/* 检测视口宽度最大值 */
@media (max-width: 768px) {
/* CSS code */
}
/* 检测视口宽度最小值 */
@media (min-width: 1200px) {
/* CSS code */
}
使用 max-width
,视口宽度会在小于等于该值时执行其中的 CSS;使用 min-width
,视口宽度会在大于等于该值时执行其中的 CSS。这样,就实现了基于区间检测的媒体查询,更加灵活。
示例一:视口宽度双区间检测
@media (max-width: 768px) {
body {
background-color: pink;
}
}
@media (min-width: 768px) {
body {
background-color: cornflowerblue;
}
}
示例二:视口范围多区间检测。
此时,建议统一使用 min-width
或 max-width
,还需要注意书写顺序,避免样式被错误覆盖。
若使用 min-width
,宽度应从小到大;若使用 max-width
,宽度应从大到小。
/* 主体背景色默认为灰色 */
body {
background-color: #ccc;
}
/* 大于等于 768px,背景色为粉色 */
@media (min-width: 768px) {
body {
background-color: pink;
}
}
/* 大于等于 992px,背景色为绿色 */
@media (min-width: 992px) {
body {
background-color: green;
}
}
/* 大于等于 1200px,背景色为天蓝色 */
@media (min-width: 1200px) {
body {
background-color: skyblue;
}
}
示例三:根据视口大小隐藏/显示元素
要求:当视口尺寸小于等于 768px 时隐藏左边 <div>
。
<div class="box">
<div class="left">
调整浏览器窗口大小
</div>
<div class="right">
响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局响应式布局
</div>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.box {
display: flex;
width: 100%;
height: 25rem;
}
.left {
flex: 1;
background-color: pink;
line-height: 25rem;
text-align: center;
}
@media (max-width: 768px) {
.left {
display: none;
}
}
.right {
flex: 3;
overflow: auto;
background-color: cornflowerblue;
}
1-16.3 媒体查询的完整写法与 <link>
在前文,我们所书写的媒体查询都是简化写法,其完整写法为:
@media logical_operator media_type and (media_feature) { /* CSS code */ }
完整写法中包含逻辑运算符、媒体类型、媒体特性和 CSS。
逻辑操作符有:and
, not
, only
, or
。媒体类型有:all
(所有类型设备)、screen
(屏幕)、print
(打印媒体)。媒体特性用于描述用户代理、输出设备或环境的具体特征,部分媒体特性有:
媒体特性 | 说明 | 值 |
---|---|---|
width , height |
视口宽高 | 数值 |
max-width , min-width |
视口最大/最小宽度 | 数值 |
max-height , min-height |
视口最大/最小高度 | 数值 |
orientation |
屏幕方向 | portrait , landscape |
prefers-color-scheme |
用户倾向的暗色或亮色配色方案 | no-preference , light , dark |
一般地,我们都会使用媒体查询的简化写法,即只填写媒体特性部分。
在实际开发中,媒体查询中所使用的 CSS 代码并不会十分简单,反而可能十分庞大、复杂。这样的 CSS 应当单独形成一份文件而不是直接嵌入在媒体查询中。为避免样式表过于繁杂、难以维护,可以使用 <link>
标签,结合媒体查询,引入外部样式表。
<link>
标签同样也支持媒体查询,在标签内使用属性 media
,并附上媒体查询声明作为属性值即可。同样也支持简化写法。
<link rel="stylesheet" media="(media_feature)" src="./css/style.css">
示例:使用 <link>
结合媒体查询实现网页元素根据系统配色更换配色方案。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>媒体查询</title>
<link rel="stylesheet" href="./css/base.css">
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="./css/index_dark.css">
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="./css/index_light.css">
</head>
<body>
<div class="box">
<p>This is a text.</p>
</div>
</body>
</html>
/* index_light.css */
/* light mode */
body {
background-color: #ffffff;
color: #333333;
}
.box {
margin: 5rem auto;
width: 20rem;
height: 10rem;
background-color: #eeeeee;
color: #333333;
}
.box p {
line-height: 10rem;
text-align: center;
}
/* index_dark.css */
/* dark mode */
body {
background-color: #333333;
color: #eeeeee;
}
.box {
margin: 5rem auto;
width: 20rem;
height: 10rem;
background-color: #2f2f2f;
color: #eeeeee;
}
.box p {
line-height: 10rem;
text-align: center;
}
/* base.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: #ffffff;
}
img {
width: 100%;
height: 100%;
vertical-align: middle;
}
li {
list-style: none;
}
em, i {
font-style: normal;
}
strong, b {
font-style: normal;
}
input {
border: none;
outline: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 400;
}
1-16.4 Bootstrap 框架
Bootstrap 是由 Twitter 公司开发维护的一套前端 UI 框架,它提供了大量编写好的 CSS 样式,允许开发者结合一定的 HTML 结构以及 JavaScript,快速编写功能完善的响应式网页以及常见交互效果。
我们可以使用 Bootstrap 框架,节省开发时间,提高开发效率,快速编写一个响应式设计的网页。
1-16.4.1 使用步骤
下载生产文件:访问 Bootstrap 主页,点击 Download 访问而文档。在文档中点击 Download 按钮下载生产文件(已编译的 CSS 与 JS)。
生产文件可直接用于项目以实现响应式布局,而若选择下载源码,则可查看框架的底层实现。在这里,我们关心如何使用框架,因而选择下载生产文件。
得到的生产文件为打包好的压缩包,将其解压,框架将分为两个子目录:css
和 js
。在 css
目录中有两个样式表 bootstrap.css
和 bootstrap.min.css
。二者所应用的样式相同,前者体积较大,且源码适合人类阅读;后者将代码压缩至极少行,体积小,适用于实际项目中。
将解压得到的文件存放至项目的 bootstrap
目录下,并在 HTML 文档中导入样式表:
<link rel="stylesheet" src="./bootstrap/css/bootstrap.min.css">
1-16.4.2 栅格
使用 Bootstrap 的一般方式是给元素添加不同的类名,以将框架内定义的布局应用至元素上。
版心居中:若要实现响应式版心居中,需要将类名 .container
添加到元素中。如:
<div class="container">
版心居中
</div>
调整浏览器视口宽度,可以看到实际上框架使用媒体查询判断视口宽度将不同样式应用至元素上。
栅格布局:栅格布局将元素按网格形式排列。Bootstrap 框架中已内置了应用栅格布局的类名,使用时将需要应用栅格布局的元素添加相应类名即可。
栅格系统将网页等分为 12 份,每个元素占用网页的部分尺寸。需要应用栅格布局的元素应当被包围在父级元素 .row
中,子级元素使用 .col-xxx-x
确定子级元素在不同尺寸屏幕下的分布情况。
.col-xxx-
被称为类前缀,实用类前缀可以确定在指定的屏幕尺寸下,在一行内元素的排列个数。
xs < 576 px |
sm >= 576 px |
md >= 768 px |
lg >= 992 px |
xl >= 1200 px |
xxl >= 1400px |
|
---|---|---|---|---|---|---|
Container max-width |
None (auto) | 540px | 720px | 960 px | 1140 px | 1320 px |
Class prefix | .col- |
.col-sm- |
.col-md- |
.col-lg- |
.col-xl- |
.col-xxl- |
因此,一般而言,我们也会考虑将 .row
包围在更高一级父级元素 .container
以实现响应式版心居中。这张表显示了 Bootstrap 是如何为不同的屏幕尺寸设置版心居中的,它将屏幕尺寸划分为了 6 个不同的区间:
断点 | 类前缀 | 区间 |
---|---|---|
Extra small | None | < 576 px |
Small | sm |
>= 576 px |
Medium | md |
>= 768 px |
Large | lg |
>= 992 px |
Extra Large | xl |
>= 1200 px |
Extra extra large | xxl |
>= 1400 px |
类前缀后紧跟单行内每个元素所占比例。该值可以确定单行内排列的元素个数。该如何确定单个元素所占比例呢?考虑到 Bootstrap 将网页等分为 12 份,有下列计算公式:
单行每个元素所占比例 = 12 / 单行每个元素排列个数;
若希望在 >= 1200 px 的屏幕上,单行显示 4 个元素,应用上述算式,得到单个元素所占比例为 12 / 4 = 3
。那么,所需要的层级结构为:
<div class="container">
<div class="row">
<div class="col-xl-4"></div>
<div class="col-xl-4"></div>
<div class="col-xl-4"></div>
<div class="col-xl-4"></div>
</div>
</div>
示例:按照不同的屏幕尺寸,更改元素的排列方式。
要求:视口宽度大于等于 1200px 时,一行排列 4 个元素;视口宽度大于等于 768px 时,一行排列 2 个元素;视口宽度大于等于 576px 时,一行排列一个元素。
<div class="container">
<div class="row">
<div class="col-xl-3 col-md-6 col-sm-12">1</div>
<div class="col-xl-3 col-md-6 col-sm-12">2</div>
<div class="col-xl-3 col-md-6 col-sm-12">3</div>
<div class="col-xl-3 col-md-6 col-sm-12">4</div>
</div>
</div>
1-16.4.3 元素样式
Bootstrap 内置了许多可应用于 HTML 元素上的样式,详见官方文档。
按钮样式:默认情况下,用户代理样式表中的按钮具有轮廓与背景。可以使用 Bootstrap 修改按钮样式。
相关样式可详见官方文档。通过施加类名应用样式。
<button class="btn">Default</button>
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-info">Info</button>
<button class="btn btn-light">Light</button>
<button class="btn btn-dark">Dark</button>
表格样式:默认情况下,用户代理样式表中的表格并不具有外轮廓。可以使用 Bootstrap 修改按钮样式。
<table class="table table-bordered table-dark table-striped">
<caption>Front-end web developer course 2021</caption>
<thead class="table-light">
<tr>
<th scope="col">Person</th>
<th scope="col">Most interest in</th>
<th scope="col">Age</th>
</tr>
</thead>
<tbody class="table-striped">
<tr>
<th scope="row">Chris</th>
<td>HTML tables</td>
<td>22</td>
</tr>
<tr>
<th scope="row">Dennis</th>
<td>Web accessibility</td>
<td>45</td>
</tr>
<tr>
<th scope="row">Sarah</th>
<td>JavaScript frameworks</td>
<td>29</td>
</tr>
<tr>
<th scope="row">Karen</th>
<td>Web performance</td>
<td>36</td>
</tr>
<tr>
<th scope="row" colspan="2">Average age</th>
<td>33</td>
</tr>
</tbody>
</table>
对于是用于其他 HTML 元素的样式,详见官方文档。
1-16.4.4 组件
Bootstrap 也提供了大量现成的组件以节省开发效率,在官方文档中定位 Components,即可查看 Bootstrap 所内置的所有组件。常用的组件有手风琴(Accordion)、警告信息(Alerts)、徽章(Badges)、面包屑(Breadcrumb)、轮播图(Carousel)、导航栏(Navbar)等。
只需要定位至所需的组件,复制 HTML 代码,按需自行修改即可。若考虑需要实现动态效果,还需要在 <body>
底部引入 JavaScript 脚本。Bootstrap 的 JavaScript 脚本位于 bootstrap/js
目录中。同 CSS,bootstrap.js
体积较大,适合人类阅读,bootstrap.min.js
体积小,适用于项目中。
导航栏:以 Navbar 为例,在官方文档中定位
1-16.4.5 字体图标
Bootstrap 也提供了一套字体图标。这是一套开源的字体图标。
引入方法:将下载得到的压缩文件解压,将其中的 font
文件夹整体放入项目的 bootstrap
目录中。
导入方法:在 HTML 文档的 <head>
标签内使用 <link>
导入字体图标所依赖的 CSS 文件。
<link rel="stylesheet" src="./bootstrap/font/bootstrap-icons.min.css">
使用方法:不同于阿里字体图标库,Bootstrap 图标使用以下标签调用字体图标:
<i class="bi-xxx"></i>
其中,xxx
为字体的类名,可在 Bootstrap 字体图标主页搜索查询。
1-16.X 外部链接
响应式设计 - 学习 Web 开发 | MDN (mozilla.org)
@media - CSS:层叠样式表 | MDN (mozilla.org)
Bootstrap · The most popular HTML, CSS, and JS library in the world. (getbootstrap.com)
Get started with Bootstrap · Bootstrap v5.3 (getbootstrap.com)
Bootstrap 教程 | 菜鸟教程 (runoob.com)
Bootstrap Icons · Official open source SVG icon library for Bootstrap (getbootstrap.com)