# 多终端响应式项目开发最佳实践
TIP
本节课,我们一起来学习响应式布局,首先我们需要了解什么是响应式布局。
什么是响应式布局 ?
响应式布局是一种网页设计方法,使网页能够自动适应不同设备(桌面电脑,平板,手机等)的屏幕尺寸,提供最佳的浏览体验。
我们前面学习的流体布局、 rem 布局 、 vw 布局
,是专门用来实现移动端网页开发的。它们开发出来的网站在屏幕尺寸(320 ~ 480px)之间上显示,才能获得好的体验。 并不能适应 iPad 和 PC 端。
如果我们想只开发一套代码,且要求写出来网页能同时适应不同设备的屏幕尺寸,就必须用我们今天讲到响应式布局来实现。
接下来,我们会从以下几个方面来展开讲解响应式相关内容
- 媒体查询的语法
- 响应式断点和书写位置
- 媒体查询的两种适配方案
- 响应式栅格系统
- 响应式后台管理系统项目开发
# 一、媒体查询的语法
TIP
响应式设计的核心 就是通过 媒体查询 来检测屏幕视口宽,针对不同视口宽做相应 CSS 处理,来展现不同布局 和 内容。所以媒体查询是响应式设计的核心内容。
关于媒体查询,我们需要学习那些内容:
- 什么是媒体查询
- 媒体类型
- 媒体特性
- 逻辑运算符
# 1、什么是媒体查询
TIP
- 我们知道,一套 CSS 样式是很难适应不同大小的屏幕,所以我们需要针对不同的屏幕尺寸来书写不同的样式,这样我们写出来的页面就能在不同大小的屏幕上都正常显示。
- 媒体查询就是用来解决这个问题的,他能帮助我们检测不同屏幕的尺寸,然后针对不同屏幕尺寸,显示不同的样式。
我们来看一个简单的媒体查询代码:
<style>
/*
@media 是关键字:媒体查询
screen 媒体类型:屏幕设备
and 逻辑运算符:与 (多个条件同时满足)
min-width 媒体特性:设备宽>=800px
以下整个媒体查询代码的含义:网页是在屏幕设备上显示,同时屏幕设备的宽>=800px时,背景颜色变为红色。
*/
@media screen and (min-width: 800px) {
body {
background-color: red;
}
}
</style>
一个完整的媒体查询语句,包含以下四个部分:
- @media 关键字
- 媒体类型
- 逻辑运算符
- 媒体特性
@media 媒体类型 逻辑操作符 (媒体特性) {
...css样式....;
}
接下来我将针对以上 4 个部分,分别做详细的讲解
# 2、媒体类型
TIP
媒体类型(Media types) 就是用来描述 设备的一般类别,设备类别主要分为以下 4 种
媒体类型 | 说明 |
---|---|
all | (默认值)适用于所有的设备 |
screen | 适用于屏幕设备(如电脑、手机、电视机等) |
适用于在打印预览模式下在屏幕上查看的分页材料和文档 | |
speech | 适用于语音合成器 |
如果媒体查询语句,只指定媒体类型,可以简写成如下:
@media 媒体类型 { .... css样式..... };
案例演示
- all 是默认值,在媒体类型不写的情况下,默认就是 all,适用于所有设备
@media {
body {
background-color: red;
}
}
/* 上面代码等同于下面写法,但实际开发中,不会省略简写,如果是all还是加上最安全 */
@media all {
body {
background-color: red;
}
}
- screen 适用于屏幕设备
/* 在屏幕设备下,背景色为红色 */
@media screen {
body {
background-color: red;
}
}
- print 适用于打印预览模式
<style>
/* 正常情况下应用的 css样式 */
body {
background-color: skyblue;
color: red;
font-size: 20px;
}
/* 在打印模式下应用的 css样式*/
@media print {
body {
background-color: red;
color: yellow;
font-size: 50px;
}
}
</style>
<body>
我就是我不一样的花朵
</body>
正常模式下预览效果 | 打印模式下预览效果 |
---|---|
温馨提示:
要看到打印模式下效果,按以下步骤操作即可
在浏览器中右击 -> 打印(点击进入) -> 更多设置(点击)-> 背景图形(勾选上)就可以生效,看到效果了
在实际的开发中,我们用到的最多也就是 all,screen
# 3、媒体特性
TIP
- 媒体特性(Media features)描述了 user agent (用户代理-在网页中指浏览器)、输出设备或是浏览环境的具体特征。
- 它负责测试这些特性或特征是否存在、值为多少。
- 每条媒体特性表达式都必须用 括号() 括起来。
- 媒体特性表达式是完全 可选的
常用的媒体特性
媒体特性 | 说明 |
---|---|
width | 设备屏幕的宽 |
min-width | 设备屏幕的最小宽 (如min-width:400px; 表示屏幕宽>=400px ) |
max-width | 设备屏幕的最大 宽 (如max-width:1200px; 表示屏幕宽<=1200px ) |
-webkit-device-pixel-ratio | 设备像素比(dpr)的值(只有-webkit 内核的才支持) |
-webkit-max-device-pixel-ratio | 设备像素比(dpr)的最大值(只有-webkit 内核的才支持) |
-webkit-min-device-pixel-ratio | 设备像素比(dpr)的最小值(只有-webkit 内核的才支持) |
resolution | 值为2dppx 时,表示设备像素比为 2 。目前现代浏览器都支持。 |
min-resolution | 值为2dppx 时,表示设备像素比>= 2 |
max-resolution | 值为2dppx 时,表示设备像素比<= 2 |
orientation | 当前屏幕的方向,是横屏还竖屏 portrait: 表示竖屏 ( orientation : portrait; )landscape:表示横屏 ( orientation:landscape; ) |
- 如果只指定媒体特性,写法如下:
@media (媒体特性) {
...css样式...;
}
- 如果同时指定媒体类型和媒体特性,中间需要有逻辑运算符,写法如下:
@media 媒体类型 逻辑运算符 (媒体特性) {
.... css样式....;
}
- 多个媒体特性中间也要有逻辑操运算符
@media 媒体类型 逻辑操运算符 ( 媒体特性) 逻辑操作符 (媒体特性) {
.... css样式....;
}
案例演示
/* 所有设备的宽>=800px时,body的背景色为红色 */
@media (min-width: 800px) {
body {
background-color: red;
}
}
/* 屏幕设备的宽>=800px时,body的背景色为红色 */
@media screen and (min-width: 800px) {
body {
background-color: red;
}
}
/* 屏幕设备的宽>=800 同时<=1200px时,body的背景色为红色 */
@media screen and (min-width: 800px) and (max-width: 1200px) {
body {
background-color: red;
}
}
- 通过判断设备像素比 dpr,来设置对应样式
dpr = (在一个方向上)设备像素(物理像素) / 逻辑像素(CSS 像素)
/* dpr>=2时,body的背景色为红色 */
@media screen and (-webkit-min-device-pixel-ratio: 2) {
body {
background-color: red;
}
}
/* dpr>=3时,body的背景色为蓝色 */
@media screen and (-webkit-min-device-pixel-ratio: 3) {
body {
background-color: blue;
}
}
经典应用:移动端 1 像素问题,不清楚,可以看上一篇文章
resolution
用来检测当前设备的设备像素比
/*
当前设备为屏幕设备,同时设备像素比要 >=2时,才将背景色设为红色
*/
@media screen and (min-resolution: 2dppx) {
body {
background-color: red;
}
}
完整的兼容性写法
/*
-webkit-min-device-pixel-ratio 支持个版的 webkit内核浏览器
-moz-min-device-pixel-ratio 支持旧版的 firefox 浏览器
min-resolution 支持现在浏览器
*/
@media screen and (-webkit-min-device-pixel-ratio: 2),
(-moz-min-device-pixel-ratio: 2),
(min-resolution: 2dppx) {
/* 所有环境下的高DPI设备 */
}
- 通过判断用户是竖屏还是横屏观看,来设置对应样式
<style>
/* 模屏观看时的CSS样式 */
@media screen and (orientation: landscape) {
.box {
width: 100%;
height: 200px;
background-color: red;
}
}
/* 竖屏观看时的 CSS样式 */
@media screen and (orientation: portrait) {
.box {
width: 100%;
height: 700px;
background-color: blue;
}
}
</style>
<body>
<div class="box"></div>
</body>
# 4、逻辑运算符
TIP
- 逻辑运算符(logical operators)
not
,and
和only
可用于联合构造复杂的媒体查询 - 您还可以通过用 ,(逗号) 分隔多个媒体查询,将它们组合为一个规则。
逻辑运算符 | 说明 |
---|---|
and | and 操作符用于将多个媒体查询规则组合成单条媒体查询当每个查询规则都为真时则该条媒体查询为真 |
, 逗号 | 逗号用于将多个媒体查询合并为一个规则 逗号分隔列表中的每个查询都与其他查询分开处理 如果列表中的任何查询为 true,则整个 media 语句均返回 true。换句话说,列表的行为类似于逻辑 或 or 运算符 |
not | not 运算符用于否定媒体查询如果不满足这个条件则返回 true ,否则返回false not 关键字只能用于否定整个媒体查询如果使用 not 运算符,则还必须指定媒体类型。 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询(因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询) |
only | only 关键字,主要是为了兼容一些老版本的浏览器时,防止出错而加上的。 现代浏览器都完全支持了 媒体查询,所以 only 关键字可以省略不需要了。 |
# 4.1、and 运算符
TIP
and
操作符用于将多个媒体查询规则组合成单条媒体查询- 当每个查询规则都为真时,则该条媒体查询为真
/*
需要满足以下3个条件,body背景颜色才为红色
屏幕设备
屏幕的宽>=500px
竖屏观看时
*/
@media screen and (min-width: 500px) and (orientation: portrait) {
body {
background-color: red;
}
}
# 4.2、逗号逻辑运算符
TIP
- 逗号用于将多个媒体查询合并为一个规则
- 每个逗号前为一个独立的查询规则,逗号后为一个独立的查询规则
- 逗号分隔的每一个独立的查询规则中,只要有一个为
true
,则整个 media 语句返回true
。 - 换句话说 , 逗号 类似于
js
中的逻辑 或or
运算符
/*
以下查询语句,有两个独立的查规则
1、screen and (min-width:400px) 设备为屏幕设备,同时屏幕宽>=400px 时成立
2、(max-width:375px) 任何设备,设备宽<=375px时成立
以上两条规则中,只要有一条成立,整个media语句为真,body的背景颜色就会设为红色。
*/
@media screen and (min-width: 400px), (max-width: 375px) {
body {
background-color: red;
}
}
/*
当设备为屏幕设备,同时宽<=375px时 或 当设备为屏幕设备,同时横屏观看时,背景色为红色
*/
@media screen and (max-width: 375px), screen and (orientation: landscape) {
body {
background-color: red;
}
}
# 4.3、not 运算符
TIP
not
运算符会反转 单个媒体查询规则 的含义- 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询
如果不满足这个条件则返回
true
,否则返回false
如果使用
not
运算符,则还必须指定媒体类型not
只能用来否定 整个(单个媒体的整个)媒体查询,所以不能放在 screen 之后
错误写法
/* not运算符中,没有指定媒体类型 不会报错,但不推荐这样写 */
@media not (min-width: 500px) {
body {
background-color: red;
}
}
/* not 只能用来否定整个媒体查询,所以不能放在screen之后 */
@media screen not (min-width: 500px) {
body {
background-color: red;
}
}
正确写法
/*
not否定的是 screen and (min-width:500px) 整个查询,可以理解为除这个条件下不生效,其它都生效
当设备是screen 并且宽<500px 或 设备为非屏幕设备时,body的背景设为红色
*/
@media not screen and (min-width: 500px) {
body {
background-color: red;
}
}
not 出现在以逗号分隔的查询列表中
- 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询
- 因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询
/*
以下代码中的not只针对逗号前的查询规则取反
not 取反的是 screen and (min-width:1000px),
并不会对后面的screen and (orientation: landscape)
所以当
设备为屏幕设备,同时宽<1000px时 ,或
设备为非屏幕设备时,或
设备为屏幕设备,同横屏幕观看时
body的背景色为红色
*/
@media not screen and (min-width: 1000px), screen and (orientation: landscape) {
body {
background-color: red;
}
}
# 4.4、only 运算符
TIP
- only 关键字,主要是为了兼容一些老版本的浏览器时,防止出错而加上的。
- 现代浏览器都完全支持了 媒体查询,所以 only 关键字可以省略不需要了。
# 二、响应式断点和书写位置
TIP
当我们需要为不同的屏幕尺寸来设置不同的样式时,我们就需要知道在什么屏幕尺寸下需要做出响应。
那这些不同的屏幕尺寸,就称为响应式断点(阈值)。
# 1、响应式断点(阈值)的设定
TIP
在实际的开发中,响应式断点是由公司根据项目来定的。
不过行业也会有一个标准的参考断点(Breakpoint),这里我们以 Bootstrap (opens new window) 框架内部的断点来给大家做讲解
屏幕大小 | 栅格布局中 class 名区分 | 断点(阈值) |
---|---|---|
超小屏(Extra small ) | <576px | |
小屏 (Small) | -sm | 576px ~ 768px (含等于) |
中屏 (Medium) | -md | 768px ~ 992px (含等于) |
大屏 (Large) | -lg | 992px ~ 1200px(含等于) |
超大屏 (X-Large) | -xl | 1200px ~ 1400px(含等于) |
超大大屏(XX-Large) | -xxl | >1400px |
在实际开发中
断点并不是完全按上面列出的值来的。而是根据我们所写的项目,在对屏幕做调整时,如果觉得当前效果不符合我们的需求,需要通过设置新的断点来调整,就可以在此添加相应的断点。
以上断点是 Bootstrap (前端响应式框架)框架内部的断点,我们可以用来作为我们开发的标准来参考。
案例演示
根据上面提供的标准断点,设置不同断点(屏幕尺寸)下,显示不同背景色。
<style>
/* 当屏幕宽小于576px时,以下代码生效 */
body {
background-color: red;
}
/* 当屏幕宽大于等于576px,小于768px时,以下代码生效 */
@media screen and (min-width: 576px) {
body {
background-color: khaki;
}
}
/* 当屏幕宽大于等于768px,小于992px时,以下代码生效 */
@media screen and (min-width: 768px) {
body {
background-color: skyblue;
}
}
/* 当屏幕宽大于等于992px,小于1200px时,以下代码生效 */
@media screen and (min-width: 992px) {
body {
background-color: green;
}
}
/* 当屏幕宽大于等于1200px时,以下代码生效 */
@media screen and (min-width: 1200px) {
body {
background-color: turquoise;
}
}
</style>
注:
在书写断点时,要注意代码的书写位置。以上采取了min-width
属性 从小到大的顺序来书写。
- 当浏览器窗口大小为
1000px
时,min-width:992px
中的样式和min-width:768px
中的样式都会生效 - 因为 css 选择器的权重相同时,写在后面的会覆盖写在前面的。
- 所以
min-width:992px
下的样式会覆盖掉min-width:768px
下的样式,最终生效的是min-width:992px
下的样式。
# 2、媒体查询的代码书写位置
TIP
- 媒体查询的代码可以写在
style
标签中,也可以写在单独的 CSS 文件中 - 不过所有媒体查询代码都要写在所有 CSS 样式的代码之后。
- 这样才能保证断点生效时,写在媒体查询中的代码能生效,不会被正常的样式所覆盖。
写在 style 标签中
<style>
/* .....正常情况下的css样式.... */
/* .....媒体查询代码 ....; */
</style>
写在单独的 css 文件中,通过 link 标签引入
/*
media.css中写的是媒体查询的css代码
link标签的引入位置,要放在所有css样式的最后面。
*/
<link rel="stylesheet" href="../css/media.css">
不同断点代码写入不同 css 文件中(不推荐 )
- media 属性中的内容,和正常的写法一样
- 通过 link 来引用,在 media 中来设置对应断点
<link rel="stylesheet" href="a.css" media="screen and (min-width:600px)" />
<link rel="stylesheet" href="b.css" media="screen and (min-width:1000px)" />
/* a.css文件内容 */
body {
background-color: skyblue;
}
/* b.css文件内这从 */
body {
background-color: red;
}
# 三、响应式两种适配方案
在实际的响应式开发中,我们会有两种通用的适配方案
- PC 端优先(先考虑 PC 端,最后再考虑移动端)
- 移动端优先(先考虑移动端,最后再考虑 PC 端)
# 1、PC 端优先
在 @media 查询时,我们会先以 PC 端为主,适配方案代码顺序为
/* ....这里的css样式,会在屏幕宽大于1400px时生效.... */
.....css样式.....
/* 当屏幕宽度大于1200px ,但小于等于1400px时,显示如下样式 */
@media screen and (max-width: 1400px) {
}
/* 当屏幕宽度大于992px ,但小于等于1200px时,显示如下样式 */
@media screen and (max-width: 1200px) {
}
/* 当屏幕宽度大于768px ,但小于等于992px时,显示如下样式 */
@media screen and (max-width: 992px) {
}
/* 当屏幕宽度大于576px ,但小于等于768px时,显示如下样式 */
@media screen and (max-width: 768px) {
}
/* 当屏幕宽度小于等于576px时,显示如下样式 */
@media screen and (max-width: 576px) {
}
/* 如果还想匹配更小的尺寸,可以在后面写,如小于等 480px时,要显示的样式 */
/* 当屏幕宽度小于等于576px时,显示如下样式, */
@media screen and (max-width: 480px) {
}
# 1.1、实战应用:不同屏幕尺寸下,显示不同的列数
屏幕宽 | 一行显示个数 | 每列(个)的宽 |
---|---|---|
>1200px | 6 | 100% / 6 = 16.16.66666667% |
<=1200px 且 > 992px | 5 | 100% / 5 = 20% |
<=992px 且 > 768px | 4 | 100% / 4 = 25% |
<=768px 且 > 576px | 3 | 100% / 3= 33.3333334% |
<=576px 且 > 480px | 2 | 100% / 2 = 50% |
<=480px | 1 | 100% / 1 = 100% |
<style>
html,
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.item {
box-sizing: border-box;
padding: 5px;
/* 当屏幕宽度>1200px时,显示的宽 - 一排显示 */
width: 16.66666667%;
}
.item img {
width: 100%;
}
/* 当屏幕宽度大于992px ,但小于等于1200px时,显示如下样式 */
@media screen and (max-width: 1200px) {
.item {
width: 20%;
}
}
/* 当屏幕宽度大于768px ,但小于等于992px时,显示如下样式 */
@media screen and (max-width: 992px) {
.item {
width: 25%;
}
}
/* 当屏幕宽度大于576px ,但小于等于768px时,显示如下样式 */
@media screen and (max-width: 768px) {
.item {
width: 33.333333%;
}
}
/* 当屏幕宽度小于等于576px时,显示如下样式 */
@media screen and (max-width: 576px) {
.item {
width: 50%;
}
}
/* 当屏幕宽度小于等于480px时,显示如下样式 */
@media screen and (max-width: 480px) {
.item {
width: 100%;
}
}
</style>
<body>
<div class="container">
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
</div>
</body>
# 2、移动端优先
TIP
在 @media 查询时,我们会先以移端为主,适配方案代码顺序为
/* 当屏幕宽度小于480px,显示以下样式 */
...css样式....
/* 如果还要设置更小尺寸,显示的样式,则可以写在这里,如 >=480p 但小 576px 时 */
@media screen and (min-width: 480px) {
}
/* 以下为行业标准参考的断点 */
/* 当屏幕宽度大于等于576px, 同时小于768px时,显示以下样式 */
@media screen and (min-width: 576px) {
}
/* 当屏幕宽度大于等于768px, 同时小于992px时,显示以下样式 */
@media screen and (min-width: 768px) {
}
/* 当屏幕宽度大于等于992px, 同时小于1200px时,显示以下样式 */
@media screen and (min-width: 992px) {
}
/* 当屏幕宽度大于等于1200px,同时小于 1400px时,显示以下样式 */
@media screen and (min-width: 1200px) {
}
/* 当屏幕宽度>=1400px ,显示如下样式 */
@media screen and (min-width: 1400px) {
}
# 2.1、实战应用:不同屏幕尺寸下,显示不同的列数
屏幕宽 | 一行显示个数 | 每列(个)的宽 |
---|---|---|
<480px | 1 | 100% / 1= 100% |
>=480px 且 < 576px | 2 | 100% / 2= 50% |
>=576px 且 <768px | 3 | 100% / 3=33.3333334% |
>=768px 且 <992px | 4 | 100% / 4 = 25% |
>=992px 且 <1200px | 5 | 100% / 5 = 20% |
>=1200px | 6 | 100% / 6 = 16.6666667% |
<style>
html,
body {
margin: 0;
}
.container {
/* 弹性布局 */
display: flex;
/* 放不下时,换行 */
flex-wrap: wrap;
}
.item {
/* 怪异盒子模型 */
box-sizing: border-box;
padding: 5px;
/* 当屏幕宽度<481px时,显示宽度*/
width: 100%;
}
.item img {
width: 100%;
}
/* 当屏幕宽度大于等于480px, 同时小于576px时,显示以下样式 */
@media screen and (min-width: 480px) {
.item {
width: 50%;
}
}
/* 当屏幕宽度大于等于576px, 同时小于768px时,显示以下样式 */
@media screen and (min-width: 576px) {
.item {
width: 33.33333333%;
}
}
/* 当屏幕宽度大于等于768px, 同时小于992px时,显示以下样式 */
@media screen and (min-width: 768px) {
.item {
width: 25%;
}
}
/* 当屏幕宽度大于等于992px, 同时小于1200px时,显示以下样式 */
@media screen and (min-width: 992px) {
.item {
width: 20%;
}
}
/* 当屏幕宽度大于等于1200px,显示以下样式 */
@media screen and (min-width: 1200px) {
.item {
width: 16.6666667%;
}
}
</style>
<body>
<div class="container">
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
<div class="item"><img src="images/img1.png" alt="" /></div>
</div>
</body>
# 四、栅格布局
TIP
- 所谓的栅格布局,你可以简单理解为,要把一个页面 或 容器(如 div),分成多少份
- 然后设置其 页面 或 容器 中子元素占对应的份数
- 通常一个页面或容器会被分成:12 份,16 份,24 份
- 如果将网页(100%)分成 12 份,那对应不同份数所占的比例如下:
份数 | 占总份数的百分比% |
---|---|
1 | 8.33333333% |
2 | 16.6666667% |
3 | 25% |
4 | 33.33333333% |
5 | 41.66666667% |
6 | 50% |
7 | 58.33333333% |
8 | 66.6666667% |
9 | 75% |
10 | 83.33333333% |
11 | 91.66666667% |
12 | 100% |
# 1、百分比实现栅格布局
将页面分成 12 分,每份所占的比例
/* 以下 css 保存在 response.css 中*/
/* 不同份数,所占的宽 */
.col-1 {
width: 8.33333333%;
}
.col-2 {
width: 16.66666667%;
}
.col-3 {
width: 25%;
}
.col-4 {
width: 33.33333333%;
}
.col-5 {
width: 41.66666667%;
}
.col-6 {
width: 50%;
}
.col-7 {
width: 58.33333333%;
}
.col-8 {
width: 66.6666667%;
}
.col-9 {
width: 75%;
}
.col-10 {
width: 83.33333333%;
}
.col-11 {
width: 91.66666667%;
}
.col-12 {
width: 100%;
}
# 1.1、栅格布局应用
利用栅格布局,实现一行 4 列,3 列,2 列,1 列的布局
<style>
html,
body {
margin: 0;
}
.row {
width: 100%;
display: flex; /* 弹性布局 */
flex-wrap: wrap; /* 放不下时换行 */
}
.col {
box-sizing: border-box;
height: 100px;
border: 1px solid red;
margin-top: 10px;
}
</style>
<!-- 引用 栅格布局样式 -->
<link rel="stylesheet" href="./response.css" />
<body>
<div class="row">
<!-- 一行4列 -->
<div class="col col-3"></div>
<div class="col col-3"></div>
<div class="col col-3"></div>
<div class="col col-3"></div>
<!-- 一行3列 -->
<div class="col col-4"></div>
<div class="col col-4"></div>
<div class="col col-4"></div>
<!-- 一行2列 -->
<div class="col col-6"></div>
<div class="col col-6"></div>
<!-- 一行1列 -->
<div class="col col-12"></div>
</div>
</body>
# 2、grid 网格实现栅格布局
利用 grid 网格布局,将容器分成 12 分,每份所占的列数
/* 以下代码保存在 grid.css 文件中 */
.grid-12 {
/* 网格布局 */
display: grid;
/* 将容器等分成12列 */
grid-template-columns: repeat(12, 1fr);
}
.col-1 {
/* 起始行网格线 起始列网格线 结束行网格线 结束列网格线(或跨几列) */
grid-area: auto/auto/auto/span 1;
}
.col-2 {
grid-area: auto/auto/auto/span 2;
}
.col-3 {
grid-area: auto/auto/auto/span 3;
}
.col-4 {
grid-area: auto/auto/auto/span 4;
}
.col-5 {
grid-area: auto/auto/auto/span 5;
}
.col-6 {
grid-area: auto/auto/auto/span 6;
}
.col-7 {
grid-area: auto/auto/auto/span 7;
}
.col-8 {
grid-area: auto/auto/auto/span 8;
}
.col-9 {
grid-area: auto/auto/auto/span 9;
}
.col-10 {
grid-area: auto/auto/auto/span 10;
}
.col-11 {
grid-area: auto/auto/auto/span 11;
}
.col-12 {
grid-area: auto/auto/auto/span 12;
}
# 2.1、栅格布局实战应用
利用栅格布局,实现一行 4 列,3 列,2 列,1 列的布局
<style>
.container {
height: 100px;
margin: 10px 0;
}
.grid-item {
padding: 10px;
font-size: 20px;
color: red;
}
/* 奇数项背景颜色 */
.grid-item:nth-child(2n + 1) {
background-color: skyblue;
}
/* 偶数项背景颜色 */
.grid-item:nth-child(2n) {
background-color: tomato;
}
</style>
<!-- 引用 栅格布局样式 -->
<link rel="stylesheet" href="./grid.css" />
<body>
<div class="container grid-12">
<div class="grid-item col-3">1</div>
<div class="grid-item col-3">2</div>
<div class="grid-item col-3">3</div>
<div class="grid-item col-3">3</div>
</div>
<div class="container grid-12">
<div class="grid-item col-4">1</div>
<div class="grid-item col-4">2</div>
<div class="grid-item col-4">3</div>
</div>
<div class="container grid-12">
<div class="grid-item col-6">1</div>
<div class="grid-item col-6">2</div>
</div>
<div class="container grid-12">
<div class="grid-item col-6">1</div>
<div class="grid-item col-3">2</div>
<div class="grid-item col-3">2</div>
</div>
</body>
注:
可以去 Bootstrap 官网 (opens new window),下载对应的源码,查看 Bootstrap 的栅格系统,Bootstrap 底层是将页面分成 12 份。
# 五、响应式栅格系统
在实际开发中
- 要完美的实现响应式系统或网站的开发,就需要利用响应式栅格系统来帮助我们实现。
- BootStrap 框架实现响应式布局的本质就是他的响应式栅格系统。
- 响应式栅格系统是:栅格布局 + 响应断点 +响应式适配方案 3 者结合实现的一套响应式解决方案
# 1、响应式栅格系统实现步骤
TIP
我们可以按以下 4 步骤来实现响应式栅格系统
- 你打算将页面分成多少份 ?
- 确定响应断点有哪些 ?(通常参考行业标准来 )
- 确定响应式适配方案(PC 端优先 或 移动端优先)
- 在对应的响应断点下,书写对应的栅格布局样式。(这一步,实现响应式栅格系统)
# 2、你打算将页面分成多少份?
假设
我们将页面分成 12 份,那对应不同份数占总份数的比例
份数 | 占总份数的百分比% |
---|---|
1 | 8.33333333% |
2 | 16.6666667% |
3 | 25% |
4 | 33.33333333% |
5 | 41.66666667% |
6 | 50% |
7 | 58.33333333% |
8 | 66.6666667% |
9 | 75% |
10 | 83.33333333% |
11 | 91.66666667% |
12 | 100% |
# 2、确定响应断点有哪些?
假设整个响应式效果,对应的断点如下:
- < 576px
- 576px ~ 768px (含等于)
- 768px ~ 992px (含等于)
- 992px ~ 1200px(含等于)
- 1200px ~ 1400px (含等于)
- 大于 1400px
屏幕大小 | 栅格布局中 class 名区分 | 断点(阈值) |
---|---|---|
超小屏(Extra small ) | <576px | |
小屏 (Small) | -sm | 576px ~ 768px (含等于) |
中屏 (Medium) | -md | 768px ~ 992px (含等于) |
大屏 (Large) | -lg | 992px ~ 1200px(含等于) |
超大屏 (X-Large) | -xl | 1200px ~ 1400px(含等于) |
超大大屏(XX-Large) | -xxl | >1400px |
# 3、确定响应式适配方案
响应式适配方案有两种:PC 端优先 和 移动端优先
- 这里我们选择 PC 端优先
- PC 端优先适配方案与断点结合,得到如下代码 !
<style>
/* 大于1400px的样式写在这里 */
/* ....css样式.... */
/* 当屏幕宽>1200 px 同时<=1400px ,显示如下样式 */
@media screen and (max-width: 1400px) {
}
/* 屏幕宽>992px,同时<=1200px时,样式写在这里 */
@media screen and (max-width: 1200px) {
}
/* 屏幕宽>768px,同时<=992px时,样式写在这里 */
@media screen and (max-width: 992px) {
}
/* 屏幕宽>766px,同时<=768px时,样式写在这里 */
@media screen and (max-width: 768px) {
}
/* 屏幕宽<=576px样式写在这里 */
@media screen and (max-width: 576px) {
}
</style>
# 4、在对应的响应断点下,书写对应的栅格布局样式
TIP
以下 css 样式放在 media.css
中,后面引入的 media.css
就是这里的代码
以下 css 代码,我们就称之为 响应式栅格系统
点击查看完整源代码
/*
第一:我们将页面分成12分
第二:我们选择的断点是行业标准断点
第三:我们选择的适配方案,是PC端优先
*/
/* ....这里的css样式,会在屏幕宽大于1400px时生效.... */
.col-xxl-1 {
width: 8.333333%;
}
.col-xxl-2 {
width: 16.6666667%;
}
.col-xxl-3 {
width: 25%;
}
.col-xxl-4 {
width: 33.33333333%;
}
.col-xxl-5 {
width: 41.66666667%;
}
.col-xxl-6 {
width: 50%;
}
.col-xxl-7 {
width: 58.33333333%;
}
.col-xxl-8 {
width: 66.6666667%;
}
.col-xxl-9 {
width: 75%;
}
.col-xxl-10 {
width: 83.33333333%;
}
.col-xxl-11 {
width: 91.66666667%;
}
.col-xxl-12 {
width: 100%;
}
/* 当屏幕宽度大于1200px ,但小于等于1400px时,显示如下样式 */
@media screen and (max-width: 1400px) {
.col-xl-1 {
width: 8.333333%;
}
.col-xl-2 {
width: 16.6666667%;
}
.col-xl-3 {
width: 25%;
}
.col-xl-4 {
width: 33.33333333%;
}
.col-xl-5 {
width: 41.66666667%;
}
.col-xl-6 {
width: 50%;
}
.col-xl-7 {
width: 58.33333333%;
}
.col-xl-8 {
width: 66.6666667%;
}
.col-xl-9 {
width: 75%;
}
.col-xl-10 {
width: 83.33333333%;
}
.col-xl-11 {
width: 91.66666667%;
}
.col-xl-12 {
width: 100%;
}
}
/* 当屏幕宽度大于992px ,但小于等于1200px时,显示如下样式 */
@media screen and (max-width: 1200px) {
.col-lg-1 {
width: 8.333333%;
}
.col-lg-2 {
width: 16.6666667%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-8 {
width: 66.6666667%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-12 {
width: 100%;
}
}
/* 当屏幕宽度大于768px ,但小于等于992px时,显示如下样式 */
@media screen and (max-width: 992px) {
.col-md-1 {
width: 8.333333%;
}
.col-md-2 {
width: 16.6666667%;
}
.col-md-3 {
width: 25%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-6 {
width: 50%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-8 {
width: 66.6666667%;
}
.col-md-9 {
width: 75%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-12 {
width: 100%;
}
}
/* 当屏幕宽度大于576px ,但小于等于768px时,显示如下样式 */
@media screen and (max-width: 768px) {
.col-sm-1 {
width: 8.333333%;
}
.col-sm-2 {
width: 16.6666667%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-8 {
width: 66.6666667%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-12 {
width: 100%;
}
}
/* 当屏幕宽度小于等于576px时,显示如下样式 */
@media screen and (max-width: 576px) {
.col-1 {
width: 8.333333%;
}
.col-2 {
width: 16.6666667%;
}
.col-3 {
width: 25%;
}
.col-4 {
width: 33.33333333%;
}
.col-5 {
width: 41.66666667%;
}
.col-6 {
width: 50%;
}
.col-7 {
width: 58.33333333%;
}
.col-8 {
width: 66.6666667%;
}
.col-9 {
width: 75%;
}
.col-10 {
width: 83.33333333%;
}
.col-11 {
width: 91.66666667%;
}
.col-12 {
width: 100%;
}
}
# 六、实现响应式效果
TIP
利用上面写的 响应式栅格系统,来实现如下图所示的响应效果, 1 行四列,变 2 列, 变 1 列
实现步骤如下:
- 如果是以移动端优先,则对着移动端设计稿来开发,然后再确定不同断点下要实现的效果,通过适配慢慢过渡到 PC 端。
- 如果是 PC 端优先,则对着 PC 端设计稿来开发,然后再确定不同断点下要实现的效果,通过适配慢慢过渡到移动端。
以下适配采用的是 PC 端优先,从 PC 端慢慢过渡到移动端开发。对应断点和效果如下
屏幕宽 (断点) | 一行显示个数 |
---|---|
>1200px | 3 列 |
<= 1200px | 2 列 |
<= 992px | 1 列 |
<!-- 栅格系统的代码样式在media.css文件中 ,具体代码,就是步骤4种的代码 -->
<link rel="stylesheet" href="./css/media.css" />
<style>
html,
body {
margin: 0;
}
.row {
display: flex;
flex-wrap: wrap;
margin-top: 20px;
}
.col {
box-sizing: border-box;
border: 1px solid red;
margin: 10px 0;
min-height: 100px;
}
</style>
<body>
<div class="row">
<!--
大于 1200px 显示 3列
<= 1200px 显示 2列
<= 992px 显示 1列
-->
<div class="col col-xl-3 col-lg-6 col-sm-12">1</div>
<div class="col col-xl-3 col-lg-6 col-sm-12">2</div>
<div class="col col-xl-3 col-lg-6 col-sm-12">3</div>
<div class="col col-xl-3 col-lg-6 col-sm-12">4</div>
</div>
</body>
# 七、实战应用
利用响应式栅格系统实现如下所示的响应式布局
TIP
不同响应式断点下的的效果
- 当视口宽 >1200px 时,以正常效果显示
- 当视口宽 <= 1200px 时,上面一行 4 列,变成 1 行 2 列
- 当视口宽 <= 992px 时,第二和第三行的一行 2 列变 1 列,最下面的一行 3 列变成 1 行 2 列和 1 行 1 列
- 当视口宽 <= 768px 时,全部一行一列显示 ,同时上面的导航变成点击下拉菜单形式
确定适配方案以 PC 端优先,所以我们按 PC 的设计稿来开发,然后慢慢过渡到移动端
点击查看完整源代码
<style>
body {
margin: 0;
background-color: #ddd;
}
.row {
display: flex;
flex-wrap: wrap;
}
.col {
min-height: 100px;
/* width:25%; */
box-sizing: border-box;
padding: 10px;
}
.col-content {
background-color: #fff;
border-radius: 10px;
height: 100%;
}
.main {
margin: 20px;
max-width: 1400px;
margin: 0px auto;
}
</style>
<body>
<main class="main">
<div class="row">
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
</div>
<div class="row">
<div class="col col-xxl-8 col-md-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-4 col-md-12">
<div class="col-content"></div>
</div>
</div>
<div class="row">
<div class="col col-xxl-4 col-md-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-8 col-md-12">
<div class="col-content"></div>
</div>
</div>
<div class="row">
<div class="col col-xxl-4 col-md-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-4 col-md-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-4 col-md-12 col-sm-12">
<div class="col-content"></div>
</div>
</div>
</main>
</body>
# 八、项目开发准备工作
TIP
利用响应式栅格系统实现以下响应式后台管理界面开发,PSD 设计稿已上传至钉钉群,可以找助理老师获取。
# 1、整个项目的开发流程
TIP
系统了解响应式项目开发的完整流程
# 2 、搭建项目文件夹结构
TIP
- 新建文件夹 WebApp
- 在 WebApp 中新建
css
、js
、images
、iconfont
等文件夹,分别用来放 css、js、图片、阿里图标内容。 - 新建
global.css
、reset.css
、index.css
、media.css
,分别用来存放全局样式、重置样式、首页样式、通用响应式样式。 - 新建
index.html
文件,然后按以下顺序引用 CSS 文件
/* 重置样式 */
css代码...
/* 网站通用布局 */
css代码...
/* 通用模块 */
css代码...
/* 通用元件 */
css代码...
/* 通用响应式系统 */
css代码...
<link rel="stylesheet" href="./css/reset.css" />
<link rel="stylesheet" href="./css/global.css" />
<link rel="stylesheet" href="./css/index.css" />
<link rel="stylesheet" href="./css/media.css" />
# 3、确定栅格系统样式(media.css 样式)
TIP
按以下 3 个步骤,确定 media.css
样式
- 将页面分成 12 份,确定栅格布局不同份数所点比例
- 确定项目对应的断点,采用行业标准断点
屏幕大小 | 栅格布局中 class 名区分 | 断点(阈值) |
---|---|---|
超小屏(Extra small ) | <576px | |
小屏 (Small) | -sm | 576px ~ 768px (含等于) |
中屏 (Medium) | -md | 768px ~ 992px (含等于) |
大屏 (Large) | -lg | 992px ~ 1200px(含等于) |
超大屏 (X-Large) | -xl | 1200px ~ 1400px(含等于) |
超大大屏(XX-Large) | -xxl | >1400px |
- 确定适配方案,以 PC 端优先
最终确定 media.css
文件的代码如下
.row {
display: flex;
flex-wrap: wrap;
}
.col-xxl-1 {
width: 8.33333333%;
}
.col-xxl-2 {
width: 16.66666667%;
}
.col-xxl-3 {
width: 25%;
}
.col-xxl-4 {
width: 33.33333333%;
}
.col-xxl-5 {
width: 41.66666667%;
}
.col-xxl-6 {
width: 50%;
}
.col-xxl-7 {
width: 58.33333333%;
}
.col-xxl-8 {
width: 66.6666667%;
}
.col-xxl-9 {
width: 75%;
}
.col-xxl-10 {
width: 83.33333333%;
}
.col-xxl-11 {
width: 91.66666667%;
}
.col-xxl-12 {
width: 100%;
}
/* 当屏幕宽>1200 px 同时<=1400px ,显示如下样式 */
@media screen and (max-width: 1400px) {
.col-xl-1 {
width: 8.33333333%;
}
.col-xl-2 {
width: 16.66666667%;
}
.col-xl-3 {
width: 25%;
}
.col-xl-4 {
width: 33.33333333%;
}
.col-xl-5 {
width: 41.66666667%;
}
.col-xl-6 {
width: 50%;
}
.col-xl-7 {
width: 58.33333333%;
}
.col-xl-8 {
width: 66.6666667%;
}
.col-xl-9 {
width: 75%;
}
.col-xl-10 {
width: 83.33333333%;
}
.col-xl-11 {
width: 91.66666667%;
}
.col-xl-12 {
width: 100%;
}
}
/* 屏幕宽>992px,同时<=1200px时,样式写在这里 */
@media screen and (max-width: 1200px) {
.col-lg-1 {
width: 8.33333333%;
}
.col-lg-2 {
width: 16.66666667%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-8 {
width: 66.6666667%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-12 {
width: 100%;
}
}
/* 屏幕宽>768px,同时<=992px时,样式写在这里 */
@media screen and (max-width: 992px) {
.col-md-1 {
width: 8.33333333%;
}
.col-md-2 {
width: 16.66666667%;
}
.col-md-3 {
width: 25%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-6 {
width: 50%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-8 {
width: 66.6666667%;
}
.col-md-9 {
width: 75%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-12 {
width: 100%;
}
}
/* 屏幕宽>576px,同时<=768px时,样式写在这里 */
@media screen and (max-width: 768px) {
.col-sm-1 {
width: 8.33333333%;
}
.col-sm-2 {
width: 16.66666667%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-8 {
width: 66.6666667%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-12 {
width: 100%;
}
}
/* 屏幕宽<=576px样式写在这里 */
@media screen and (max-width: 576px) {
.col-1 {
width: 8.33333333%;
}
.col-2 {
width: 16.66666667%;
}
.col-3 {
width: 25%;
}
.col-4 {
width: 33.33333333%;
}
.col-5 {
width: 41.66666667%;
}
.col-6 {
width: 50%;
}
.col-7 {
width: 58.33333333%;
}
.col-8 {
width: 66.6666667%;
}
.col-9 {
width: 75%;
}
.col-10 {
width: 83.33333333%;
}
.col-11 {
width: 91.66666667%;
}
.col-12 {
width: 100%;
}
}
# 4、 正式开发流程
TIP
因为确定适配方案以 PC 端优先,所以我们先按 PC 的设计稿来开发,然后开发完再通过断点的适配,一步步过渡到移动。
# 九、实现整体响应式架构布局
完整源码
<!-- header start -->
<header class="header">
<div class="header-content"></div>
</header>
<!-- end header -->
<!-- sidebar-menu start -->
<nav class="sidebar-menu"></nav>
<!-- end sidebar-menu -->
<!-- main start -->
<main class="main"></main>
<!-- end main -->
<style>
body {
background-color: #f3f4f7;
/* height: 2000px; 这个高度后面要去掉 ,只为测试效果用的 */
}
.header {
position: fixed;
top: 0px;
left: 20px;
right: 20px;
height: 115px;
background-color: #f3f4f7;
/* border: 1px solid red; */
padding-top: 20px;
}
.header-content {
height: 75px;
background-color: #fff;
border-radius: 10px;
}
.sidebar-menu {
width: 260px;
position: fixed;
top: 115px;
bottom: 20px;
left: 20px;
background-color: #fff;
border-radius: 10px;
}
.main {
margin: 115px 20px 0px 300px;
min-height: 1500px; /*这个高度是为了看效果,后面要去掉 */
border: 2px solid red;
}
</style>
<link rel="stylesheet" href="./css/media.css" />
<style>
/* 以下代码,最后会保存到 response.css 文件中 */
@media screen and (max-width: 1400px) {
.sidebar-menu {
width: 75px;
overflow: hidden;
}
.main {
margin-left: 115px;
}
}
@media screen and (max-width: 1300px) {
.sidebar-menu {
display: none;
}
.main {
margin-left: 20px;
}
}
</style>
以下为具体实现步骤
# 1、设置背景颜色
body {
background-color: #f3f4f7;
}
# 2、头部开发
<!-- header start -->
<header class="header">
<div class="header-content"></div>
</header>
<!-- end header -->
头部采用固定定位,定位在页面最顶部
.header {
position: fixed;
top: 0px;
left: 20px;
right: 20px;
height: 115px;
background-color: #f3f4f7;
border: 1px solid red; /* 查看效果,后面去掉 */
padding-top: 20px; /* header 是怪异盒子模型,所以添加内容距,不会添加其可视区高 */
}
.header-content {
height: 75px;
background-color: #fff;
border-radius: 10px;
}
你可以,给 body 添加 一个很大的高度,用来测试有滚动条情况下,头部是否一直固定在页面最顶部
body {
height: 2000px; /* 这个高度后面要去掉 ,只为测试效果用的 */
}
# 3、左侧侧边栏菜单
左侧侧边栏菜单也是采用固定定位,一直定位在页面的最右侧
<!-- sidebar-menu start -->
<nav class="sidebar-menu"></nav>
<!-- end sidebar-menu -->
.sidebar-menu {
width: 260px;
position: fixed;
top: 115px;
bottom: 20px;
left: 20px;
background-color: #fff;
border-radius: 10px;
}
# 4、右侧主体布局
<!-- main start -->
<main class="main"></main>
<!-- end main -->
body {
/* 去掉 body 中的高度来看效果 */
/* height: 2000px; 这个高度后面要去掉 ,只为测试效果用的 */
}
.main {
margin: 115px 20px 0px 300px;
min-height: 1500px; /* 这个高度是为了看效果,后面要去掉 */
border: 2px solid red;
}
# 5、左侧侧边栏与主体 - 响应式适配
屏幕尺寸 | 左侧侧边栏效果 | 右侧主体效果 |
---|---|---|
> 1400px | 正常显示( width:260px ) | 正常显示 |
<=1400px | 宽度缩小到 75px ( width:75px ) | 主体宽占满剩余空间 ( margin-left:115px ) |
<=1300px | 侧边栏隐藏不可见 ( display:none ) | 主体宽占满剩余空间 (margin-left:20px ) |
/* 宽 <=1400px */
@media screen and (max-width: 1400px) {
.sidebar-menu {
width: 75px; /* 修改宽度 */
overflow: hidden; /* 超出部分隐藏 */
}
.main {
margin-left: 115px; /* 调整左外边距来调整主体的宽 */
}
}
/* 宽 <=1300px */
@media screen and (max-width: 1300px) {
.sidebar-menu {
display: none; /* 隐藏侧边栏 */
}
.main {
margin-left: 20px; /* 调整左外边距来调整主体的宽 */
}
}
# 十、主体内容响应式布局
TIP
本项目采用适配方案为 PC 端优先(栅格系统适配也要采用 PC 端优先)),则先考虑大屏,然后再慢慢过渡到小屏幕。
# 1、主体内容 - 第一块响应式布局
首先实现 PC 端大屏幕布局,一排显示 4 个,同时每个之间有相同的间隔,两端对齐布局。实现本效果需要采用一些技巧来实现,具体实现步骤如下:
实现步骤如下
- 创建一个与主体部分一样宽的长方形
- 在黄色长方形内,创建一个宽=100% + 20px(每列间隙的大小)
- 在蓝色长方形内创建 4 个一样大小的长方形 ( 利用栅格布局,将页面分成 12 份,每列占 3 份)
- 给每个长方形添加向右的内边距,内边距大小 = 长方形之间间隙大小
白色的长方形为红色长方形内的直接子元素,用来放具体内容的。
- 将黄色背景盒子设置
overflow:hidden
- 去掉所有相关的辅助边框线和背景色,最终效果如下
完整源码
<!-- main start -->
<main class="main">
<!-- main-part1 start -->
<section class="main-part1">
<div class="common-width row">
<div class="col col-xxl-3">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3">
<div class="col-content"></div>
</div>
</div>
</section>
<!-- end main-part1 -->
</main>
<!-- end main -->
.main-part1 {
/* min-height: 200px; 后面要去掉 */
/* background-color: khaki; */
overflow: hidden;
}
.common-width {
/* min-height: 200px; 后面要去掉 */
width: calc(100% + 20px);
/* border: 2px solid blue; */
}
.common-width .col {
/* border: 1px solid red; */
padding-right: 20px;
}
.col .col-content {
background-color: #fff;
min-height: 150px;
border-radius: 10px;
}
# 1.1、响应式适配
从大屏过渡到小屏适配
屏幕尺寸 | 一排显示列数 |
---|---|
>1200px | 4 列 (每列占 3 份 ,上面已完成) |
<=1200px | 2 列 (每列占 6 份) |
<=768px | 1 列(每列占 12 份) |
<!-- main-part1 start -->
<section class="main-part1">
<div class="common-width row">
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
<div class="col col-xxl-3 col-lg-6 col-sm-12">
<div class="col-content"></div>
</div>
</div>
</section>
<!-- end main-part1 -->
# 2、主体内容 - 第二块响应式布局+适配
屏幕尺寸 | 一排显示列数 |
---|---|
>992px | 2 列 (第一列占 8 份,第 2 列占 4 份) |
<=992px | 1 列 (每列占 12 份) |
<!-- end main-part1 -->
<section class="main-part2">
<div class="common-width row">
<div class="col col-xxl-8 col-md-12">
<div class="col-content">1</div>
</div>
<div class="col col-xxl-4 col-md-12">
<div class="col-content">2</div>
</div>
</div>
</section>
# 3、主体内容 - 第三块响应式布局+适配
屏幕尺寸 | 一排显示列数 |
---|---|
>768px | 2 列 (第一列占 4 份,第 2 列占 8 份) |
<=768px | 1 列 (每列占 12 份) |
<section class="main-part3">
<div class="common-width row">
<div class="col col-xxl-4 col-sm-12">
<div class="col-content">1</div>
</div>
<div class="col col-xxl-8 col-sm-12">
<div class="col-content">2</div>
</div>
</div>
</section>
# 4、主体内容 - 第四块响应式布局+适配
屏幕尺寸 | 一排显示列数 |
---|---|
>992 | 3 列 ( 每列占 4 份) |
<=992px | 第一排显示 2 列 (每列占 6 份) 第二排显示 1 列(占 12 份) |
<=768px | 1 列 ( 每列占 12 份 ) |
<section class="main-part4">
<div class="common-width row">
<div class="col col-xxl-4 col-md-6 col-sm-12">
<div class="col-content">1</div>
</div>
<div class="col col-xxl-4 col-md-6 col-sm-12">
<div class="col-content">2</div>
</div>
<div class="col col-xxl-4 col-md-12">
<div class="col-content">2</div>
</div>
</div>
</section>
# 十一、左侧响应式伸缩二级菜单开发
TIP
深入浅出左侧响应式伸缩二级菜单开发完整开发步骤
# 1、第一步:一级菜单布局
<nav class="sidebar-menu">
<div class="menu-item">
<div class="menu-item-title">
<span class="iconfont icon-jiaoxuepingjia"></span>
教学管理
</div>
</div>
<div class="menu-item">
<div class="menu-item-title">
<span class="iconfont icon-ren"></span>
助学管理
</div>
</div>
<div class="menu-item">
<div class="menu-item-title">
<span class="iconfont icon-yingxiao"></span>
营销管理
</div>
</div>
</nav>
.sidebar-menu {
padding: 20px;
}
.sidebar-menu .menu-item {
border: 1px solid red;
}
.sidebar-menu .menu-item .menu-item-title {
height: 40px;
display: flex;
align-items: center;
font-size: 16px;
background-image: url(./images/r-jiantou.svg);
background-repeat: no-repeat;
background-position: 200px center;
}
.sidebar-menu .menu-item .menu-item-title .iconfont {
font-size: 16px;
color: #000;
margin-right: 12px;
margin-left: 7px;
}
# 2、第二步:菜单间添加间距
.sidebar-menu .menu-item {
margin-bottom: 10px;
}
# 3、第三步:激活效果
<div class="menu-item active">
<div class="menu-item-title">
<span class="iconfont icon-jiaoxuepingjia"></span>
教学管理
</div>
</div>
/* 当前菜单项被激活 */
.sidebar-menu .menu-item.active .menu-item-title {
background-color: #f77080;
background-image: url(./images/r-jiantou2.svg);
color: #fff;
}
.sidebar-menu .menu-item.active .menu-item-title .iconfont {
color: #fff;
}
# 4、第四步:创建二级菜单
.sidebar-menu .menu-item.active .menu-item-title {
background-color: #f77080;
background-image: url(./images/r-jiantou2.svg);
color: #fff;
}
.sidebar-menu .menu-item.active .menu-item-title .iconfont {
color: #fff;
}
<div class="menu-item active">
<div class="menu-item-title">
<span class="iconfont icon-jiaoxuepingjia"></span>
教学管理
</div>
<ul>
<li><a href="#">班级管理</a></li>
<li><a href="#">直播管理</a></li>
<li><a href="#">课程管理</a></li>
<li><a href="#">题库管理</a></li>
<li><a href="#">分类标签</a></li>
</ul>
</div>
# 5、第五步:二级菜单激活与未激活样式
.sidebar-menu .menu-item {
height: 40px;
overflow: hidden;
}
.sidebar-menu .menu-item.active {
height: 280px; /* 后面通过JS来计算 */
}
# 6、第六步:将所有菜单收缩
去掉第一个 menu-item
元素身上的 class 属性值 acitve
# 7、第七步:JS 实现伸缩菜单
- 获取所有的
menu-item-title
,然后绑定点击事件 - 点击后,将其直接父元素添加
class="active"
,再点击则去掉class='active'
- 点击后,获取其兄弟元素 ul 的高度,然后来改变
menu-item
的高度,实现动画。 - 给
menu-item-title
对应添加一个属性 flag 来记录,当前菜单的状态。 值为off
为关闭,值为on
为打开 - 根据当前菜单的状态,来决定
menu-item
的高度
const menuItemTitles = document.querySelectorAll(
".sidebar-menu .menu-item-title"
);
for (let i = 0; i < menuItemTitles.length; i++) {
// 4.在当前元素身上添加一个属性,用来记录前当菜单的状态
menuItemTitles[i].flag = "off"; // 默认刚开始菜单是关闭的
menuItemTitles[i].addEventListener("click", function () {
// 1、找到直接父元素,添加 class='acitve'
this.parentNode.classList.toggle("active");
// 5.判断,根据状态来做出改变
if (this.flag == "off") {
// 2、动态获取对应兄弟元素 ul的占位高
const _height = this.nextElementSibling.offsetHeight;
// 3、动态修改当前 menu-item的高度
this.parentNode.style.height = _height + "px";
this.flag = "on";
} else {
this.parentNode.style.height = 40 + "px";
this.flag = "off";
}
});
}
# 8、第八步:实现窄屏幕响应式适配
如果在宽屏幕时,菜单是展开的,则小屏时,菜单也是要全部关闭的。
屏幕尺寸 | 效果 |
---|---|
<=1400px | 菜单只显示图标部分,并且所有菜单全部默认为收缩状态 |
需要通过 JS 来操作
- 获取当前屏幕的尺寸(视口大小),如果视口宽度 <=1300,
- 则将所有菜单
menu-item
的高度设为 30px , - 同时将
menu-item
身上的class='active'
移除 - 所有菜单的状态要记录为
off
- 则将所有菜单
// 获取当前屏幕的尺寸(视口大小),如果视口宽度 <=1300,
// 则将所有菜单 `menu-item` 的高度设为 30px ,
// 同时移除 `class='active'`
window.addEventListener("resize", function () {
const clientWidth = window.innerWidth;
if (clientWidth <= 1400) {
// 遍历所有的 menu-item,将高度设为 30px,同时移除 `class='active'`
for (let i = 0; i < menuItems.length; i++) {
menuItems[i].style.height = "40px";
menuItems[i].classList.remove("active");
// 所有菜单的状态都要是off
menuItems[i].children[0].flag = "off";
}
}
});
# 9、第九步:点击菜单图标后展开菜单效果
- 在前面
menu-item-title
的点击事件中,添加将菜单sidebar-menu
宽度设为260px
,以实现点击对应菜单,展开整个侧边栏。
for (let i = 0; i < menuItemTitles.length; i++) {
// 4.在当前元素身上添加一个属性,用来记录前当菜单的状态
menuItemTitles[i].flag = "off"; // 默认刚开始菜单是关闭的
menuItemTitles[i].addEventListener("click",
function () {
// 1、找到直接父元素,添加 class='acitve'
this.parentNode.classList.toggle("active");
// -----------------------------------
// 将6、sidebar-menu的宽度改为以260px
sidebarMenu.style.width = "260px";
// -----------------------------------
// 以下省略部分css
});
- 在
resize
事件中,当屏宽小于 1400px 时,则还需要将sidebar-menu
宽改为75px
其它情况下 宽度为260px
window.addEventListener("resize", function () {
const clientWidth = window.innerWidth;
if (clientWidth <= 1400) {
// 省略部分代码,具体见前面..........
//-------------------------------------
// 将侧边栏宽改为 75px
sidebarMenu.style.width = "75px";
} else {
//-------------------------------------
// 将侧边栏宽改为 260px
sidebarMenu.style.width = "260px";
}
});
大厂最新技术学习分享群

微信扫一扫进群,获取资料
X