浅谈响应式

前言

由于移动设备的增多,携带便利,人们在移动设备上浏览网页的时间不断增加,甚至要超过PC端。但是PC端的网页放到移动端,就会出现各种问题,如字体太小、图片不清晰等。浏览体验变得很差。于是,就有了响应式网页的诞生。在多种设备的不同尺寸的屏幕上,精巧设计和制作出最佳视觉体验的网页。

下面,就跟大家分享一下如何做一个响应式的网页。

我学习响应式时做的网页:理财网站

一、如何做响应式

  1. 网页元素的尺寸和字体大小在不同尺寸的屏幕显示不同大小,以达到最舒适的效果;

  2. 网页内容的信息内容在大尺寸屏幕中被全部显示出来,尽可能充实页面,而在小尺寸屏幕里则部分隐藏起来,通过用户的触控再把被隐藏的信息呈现出来;

  3. 网页信息在大屏幕中以多列形式展现,小屏幕中逐渐减少列数,直到变为满屏;

  4. 网页图片在不同屏幕下不失真,保持比例和清晰度

二、设置viewport以及各种兼容设置

2.1 设置 viewport

页面宽度设置为设备宽度,初始缩放比例为100%

1
<meta name="viewport" content="width=device-width,initial-scale=1">

页面宽度设置为设备宽度,初始缩放比例为100%,最大、最小缩放为100%,用户不允许缩放,只能滚动

1
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">

一般设置第一种,还有其他情况应该根据需要设置

2.2 对IE浏览器的优化和兼容性

告诉IE浏览器以尽可能高的仿真版本显示该网页,建议使用

1
2
<meta
http-equiv="X-UA-Compatible" content="IE=edge">

下面两个插件用于在IE8以及以下版本浏览器支持HTML5元素和媒体查询,如果不需要用可以移除

1
2
3
4
5
6
<!--[if lt IE9]>
<script
src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script
src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

由于响应式网页面向的更多是移动设备,大多数不会使用低版本IE等浏览器,可以直接忽略这部分需求,不兼容IE低版本。设置一个条件注释,以提醒低版本用户。

1
2
3
<!--[if lte IE 8]>
    <p class="browserupgrade">您的浏览器版本老的可笑,请到<a href="http://browsehappy.com/">这里</a>更新以获取最佳体验<p>
<![endif]-->

三、使用相对单位

3.1 em

rem 出现之前,很多人都使用 em 来实现响应式。但是 em 单位是相对父元素的字体大小而改变的,小的改动可能引起其所有子元素的样式改变,需要考虑的因素增多,难易把控。

主要应用于与字体大小有一定关联的样式中,例如 button 按钮的内填充等,这样就可以只通过改变字体大小就得到不失真的按钮,可维护性增强

3.2 rem

rem 的出现被很多人称为最好的相对单位。

基础设置

首先设置html的字体大小为 62.5%,在chrome浏览器下有最小字体限制,1rem = 12px,其他都为 10px。这样就很容易使用 rem 作为单位,不需要考虑太多的父子关系等。

一般情况下,font-size 不使用 rem 单位,还有一些固定大小的元素,适合使用 px

注意:rem 存在兼容性问题,也就是说,使用 rem 作为单位的话,就不再考虑向下兼容了。

通过 js 控制根字体大小

一般情况在项目的最前面加载一段 js 来修改 html 的 font-size,针对不同分辨率计算 font-size,监听浏览器更改 html 的 font-size(根据实际情况通过设计稿与当前可视区的大小做一个比例关系,通过这个比例进行缩放处理)。

1
docEl.style.fontSize = 20 * (docEl.clientWidth / 320) + 'px';

给html设置fontSize大小,其实就是在DOMContentLoaded或者resize变化后调整fontSize的大小,从而调整rem的比值关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var docEl = document.documentElement,
//当设备的方向变化(设备横向持或纵向持)此事件被触发。绑定此事件时,
//注意现在当浏览器不支持orientationChange事件的时候我们绑定了resize 事件。
//总的来说就是监听当前窗口的变化,一旦有变化就需要重新设置根字体的值

resizeEvt = 'orientationchange' in window ? 'orientationchange' :'resize',

recalc = function() {
//设置根字体大小
docEl.style.fontSize = 20 * (docEl.clientWidth / 320) + 'px';   
};

//绑定浏览器缩放与加载时间
window.addEventListener(resizeEvt, recalc,
false);
document.addEventListener('DOMContentLoaded',
recalc, false);

3.3 百分比

百分比是响应式布局中最常使用的一个单位之一。因为它是通过比例来控制大小的,能够自适应屏幕宽度,在布局中最常使用,但不适合用于具体元素的大小

总之,这些单位应该灵活的应用,而不是死板的只是用 rem 或者百分比等

四、媒体查询

媒体查询是响应式网页的核心。媒体查询是一个将很多响应式概念和工具连接在一起的粘合剂。这些查询语句都是简单但是功能很强大的,它们允许我们检测设备属性,定义规则,并根据规则等的不同加载不同的CSS属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//宽度大于等于 60em
@media only screen and (min-width: 60em) {
aside {
width: 33%;
}
}
//宽度小于等于 680px
@media only screen and (max-width: 60em) {
aside {
display: none;
}
}
//横屏下
@media only screen and (orientation: landscape) {
body {
background-color: lightblue;
}
}

使用emrem为单位都是一样的,但是rem有兼容问题,所以用em最为合适

其主要作用在于改变布局,以及字体大小、元素大小,部分元素的显示隐藏等

注意
即使响应式网页可以轻松的由媒体查询实现,但是我们在应用中,也应该尽可能的实现元素自身的响应式,以减少媒体查询的使用,来减少代码,提高性能。

参考
CSS3 @media 查询
为响应式web设计创建媒体查询

五、弹性图片

5.1 基本设置

1
2
3
img{
   max-width:100%;
}

当有几张图片并排时,同样设置百分比

当你需要设置px间距时,使用calc()函数计算来合并相对单位和絶対単位以达到响应式

5.2 背景图片

背景图片可以响应调整大小或缩放。以下是三个不同的方法:

  1. background-size 属性设置为 contain, 背景图片将按比例自适应内容区域。图片保持比例不变

  2. background-size 属性设置为 100% 100% ,背景图片将延展覆盖整个区域

  3. background-size 属性设置为 cover,则会把背景图像扩展至足够大,以使背景图像完全覆盖背景区域。注意该属性保持了图片的比例因此 背景图像的某些部分无法显示在背景定位区域中

  4. 设置媒体查询,在不同的屏幕大小使用不同分辨率的图片做背景

5.3 响应式图片

针对不同的分辨率屏幕加载不同分辨率的图片

1. javascript 或者 服务端的处理

命令式的实现,通过对屏幕的宽度的判断,来改变图片的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function(){
  function makeImageResponsive(){
var width = $(window).width();
var img = $('.content img');
if (width <= 480) {
img.attr('src','img/480.png');
 }
else if (width <= 800) {
      img.attr('src', 'img/800.png');
}
else {
    img.attr('src', 'img/1600.png');
}
}
$(window).on('resize load',makeImageResponsive);
});

2. srcset 配合sizes

说明式的实现,把几个图片(缩放的图片)的地址声明在img标签中,让浏览器来决定如何加载

srcset属性

1
格式:srcset = “图片地址 图片宽度,图片地址 图片宽度”

图片地址与图片宽度以空格隔开,图片宽度格式:480w即宽度480。把所有的图片地址都设置在srcset中。

注意

在dpr为1的设备中,在小屏幕下,逐渐增大屏幕宽度,会加载出不同的图片,但是在加载了大分辨率的图片后,缩小屏幕不会改变图片,仍然使用大分辨率的图片 因为浏览器已经加载了大的图片在缓存中,再加载大的图片不再有网络消耗,浏览器会自行选择最优的处理.

在dpr为2的设备中,按原理应该在设定宽度除以2的地方加载不同的图片,但是浏览器会在比的临界值高一点的地方加载图片,浏览器会综合考虑来选择图片

设置 srcset,在图片容器变小时出现 bug,所以要设置 sizes

sizes属性
告诉浏览器以什么样的比例来显示图片

1
格式:sizes = “(min-width:800px)800px,100vw”

  • 单位可以是pxvwvhvw表示视口宽度,vh表示视口高度,100表示百分比

  • 前面的表示媒体查询,没有添加媒体查询的表示其他情况,空格隔开后的是在这种情况下图片的预估宽度

  • 图片宽度经常使用计算的形式:calc(100vw – 3em),100vw是默认值,需要根据图片容器的宽度进行设置

3. picture标签

夺回部分浏览器自行选择图片的控制权。
在需要在小屏幕加载裁剪图片,而在大屏幕中加载宽的图片
记住要加入picture.js插件填平兼容性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<picture>
<!-- 针对媒体查询设置不同大小的图片 -->
<source media="(max-width:36em)" srcset="img/tiananmen-s.jpg 768w">

<!-- 横屏的设置 -->      
<source srcset="img/tiananmen-s.jpg 768w" media="(orientation:landscape)"> 
<source srcset="img/tiananmen.jpg 1800w"> 

<!-- 针对媒体查询设置多组不同格式的图片 -->
<source type="image/svg+xml" srcset="logo.svg 480w,logo.svg 800w,logo.svg 1600w">
<source type="image/webp" srcset="logo.webp 480w,logo-m.webp 800w,logo-l.webp 1600w">

<!--在不兼容 picture 时加载的图片-->
![](img/tiananmen.jpg)
</picture>

浏览器会遍历 picture 里面的 source,找到满足当前环境的 media,把适合的
source 里面的 srcset 匹配到 img 里面的 src

4. svg图片

svg是可缩放的矢量图形,基于可扩展标记语言来生成,可以用任何的文本编辑器来创建。Svg图片怎么缩放都不会失真,因为它不是基于像素的,是基于一定的绘制规则

六、网格系统

6.1 什么是网格系统?

基于网格设计,按列来布局。使用网格视图有助于我们设计网页。这让我们向网页添加元素变的更简单。

响应式网格视图通常是 12 列,宽度为100%,在浏览器窗口大小调整时会自动伸缩。

6.2 创建响应式网格视图

首先确保所有的 HTML 元素 box-sizing 设置为 border-box,确保边距和边框包含在元素的宽度和高度间。

1
2
3
* {
box-sizing: border-box;
}

计算每列的百分比: 100% / 12 列 = 8.33%。
在每列中指定class="col-" ,用于定义每列所占的比例 :

1
2
3
4
5
6
7
8
9
10
11
12
.col-1 {width: 8.33%;}
.col-2 {width: 16.66%;}
.col-3 {width: 25%;}
.col-4 {width: 33.33%;}
.col-5 {width: 41.66%;}
.col-6 {width: 50%;}
.col-7 {width: 58.33%;}
.col-8 {width: 66.66%;}
.col-9 {width: 75%;}
.col-10 {width: 83.33%;}
.col-11 {width: 91.66%;}
.col-12 {width: 100%;}

所有的列向左浮动,间距(padding) 为 15px:

1
2
3
4
5
[class*="col-"] {
float: left;
padding: 15px;
border: 1px solid red;
}

添加清除浮动:

1
2
3
4
5
.row:after {
content: "";
clear: both;
display: block;
}

添加媒体查询,使其在不同尺寸的屏幕下,响应式安排列数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@media only screen and (min-width: 600px) {
/* For tablets: */
.col-m-1 {width: 8.33%;}
.col-m-2 {width: 16.66%;}
.col-m-3 {width: 25%;}
.col-m-4 {width: 33.33%;}
.col-m-5 {width: 41.66%;}
.col-m-6 {width: 50%;}
.col-m-7 {width: 58.33%;}
.col-m-8 {width: 66.66%;}
.col-m-9 {width: 75%;}
.col-m-10 {width: 83.33%;}
.col-m-11 {width: 91.66%;}
.col-m-12 {width: 100%;}
}

使用

1
2
3
4
<div class="row">
<div class="col-3 col-m-12">...</div>
<div class="col-9 col-m-12">...</div>
</div>

七、Flex弹性布局

Flex布局是W3C在2009年提出的新方案,可以简便、完整、响应式地实现各种页面布局。已经得到所有浏览器的支持。

语法介绍请查看:关于Flex布局
使用flex实现的简单网格系统

参考

移动端 h5开发相关内容总结
为响应式web设计创建媒体查询
自适应网页设计

生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%