大家好,我是梅巴哥er
。 本次看的是腾讯官网的布局(点击此处查看)。 他的官网,是典型响应式布局。下面就来细说一下,响应式的原理和具体实现方法,以及相应的代码案例。
在了解响应式之前,先了解一下传统做法。
一般来说,在写代码时,web端和手机端会分开。 web端一套代码,手机端一套代码,因为尺寸不同,排版方式也会有差别。
这样做的好处很明显,就是写代码时,都是根据web和手机各自用户群体的特点来写的,针对性比较强。
修改代码时,只修改某一个端的代码即可。
其实,这种做法也是很常用的。
什么是响应式布局
同一套代码,在不同的页面中,显示出不同的布局。(你把腾讯官网缩小宽度,看看布局是不是变了?)
他跟传统做法就有很明显的区别,主要在于 只写一套代码,然后做适当调整即可。
这次说的腾讯首页,就是这种做法。
当然,这种做法,并不常见。
最常见的是,不同型号的手机,都有不同的尺寸,为了适配这些尺寸,也不影响页面布局,就会使用响应式布局。
怎么实现响应式
分为5个步骤来讲。(如果只是想查看最终代码,可以直接跳到文章末尾代码区)
- 老式的单位:px
- 新式的单位:rem
- rem的调整
- 实现响应式
- 根据设备选择是否做响应式
下面我们就用代码来说明这5个步骤。
假设,我们有这样一个web端布局:
盒子1固定宽度水平居中, 盒子2和3都是1中的盒子。 2和3上下相隔10px 。
代码可如下:
<!-- demo.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>responsive mode</title>
<link rel="stylesheet" href="./demo.css" />
</head>
<body>
<div class="app">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
/*demo.css*/
* {
padding: 0;
margin: 0;
}
.app {
width: 1500px;
height: 300px;
background-color: pink;
margin: auto;
}
.box1 {
width: 200px;
height: 200px;
background-color: aqua;
}
.box2 {
width: 200px;
height: 200px;
background-color: blueviolet;
margin-top: 10px;
}
但是,这里出现了一个问题: 当我们一直缩小页面或者F12里切换成手机时,左右两侧的空白区就消失了。如果在web端,这没有问题。但是在手机端,就相当于这个居中效果消失了。就像这样:
这样很影响手机用户的观感。
那么,怎么让盒子1同样在手机端也实现居中样式呢?
很容易想到的一点就是,当屏幕尺寸变小时,居中的盒子1的尺寸也跟着变小,不就实现了吗?
为了达到这个目的, 我们要引入rem这个概念。
rem是css3的一个长度单位。 rem是相对于html的fontSize来讲的。举个例子:
html {
font-size: 100px;
}
此时,1rem = 100px
。
盒子1的宽度1500px就可以写为:width: 15rem;
如果我们改一下html的font-size尺寸,比如:
html {
font-size: 50px;
}
此时,1rem = 50px
。
盒子1的宽度仍然写为width: 15rem;
,那么 盒子1的宽度此时就变成了750px。他就缩小了。
也就是说,盒子的尺寸采用rem的写法,当设备屏幕的尺寸变化时,我们只需要跟着改动html的fontSize就能达到同步缩小盒子尺寸的目的
。这就是我们实现响应式布局的原理。
为了方便理解,再举个例子:
我们在web端写代码时,屏幕的宽度尺寸是1920px, 这时,我们把html的fontSize设置为100px。盒子1的宽度为1500px,也就是15rem。
当用户在iphoneX上查看页面时,iphoneX的屏幕宽度是375px。这时的fontSize应该设置为多少呢?
这里计算可以得出,我们只需要把新的fontSize设置为19.53px即可。
这时的盒子1的宽度15rem,就是293px,仍然实现了居中布局。
这里又出现了一个问题, 每个网站都有很多用户,我们不可能在每个用户浏览页面时,去给他们的不同设备去手动配置相应的html的fontSize, 所以,我们要想办法去自动配置。
自动配置有很多种方法,我这里介绍一种相对灵活的、用js 的方式来实现。
//改变font-size(做响应式)
(function(doc,win){
var docEI = doc.documentElement,
resizeEvt = 'orientationchange' in window?'orientataionchange':'resize',
recalc = function(){
var clientWidth = docEI.clientWidth;
if(!clientWidth) return;
//100是字体大小,1920是开发时浏览器窗口的宽度,等比计算
docEI.style.fontSize = 100*(clientWidth/1920)+'px';
}
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document,window);
/*
说明:
doc.documentElement是html
doc.documentElement.clientWidth是可视窗口的宽度
doc.documentElement.style.fontSize是当前html的fontSize属性
里面的1920是我当前写代码时的浏览器尺寸
如果UI给你的尺寸是别的,比如750, 那么这里可以改成750
这块代码需要放在head标签里
给html设置了fontSize后,
要在body里设置正常的font-size,
把font-size调整回来。 因为rem只和html的fontSize有关系。
这样就不会影响页面的文字排版了。
*/
此时,我们就实现了盒子1在手机端也出现的居中布局:
这里又㕛叒出现了亿个问题: 我们的web端也跟着变成了响应式。也就是说,当web浏览器页面缩小时,盒子1仍然保持居中布局,假如盒子1里面放的是活动内容,此时内容会随着浏览器页面的缩小而被压缩,这样会影响活动内容的展示。 这不是我们想要看到的结果。 我们希望在电脑端的页面不去做响应式。 应该怎么做呢?
监测用户的访问设备。 对用户访问时使用的设备进行判断,如果是电脑端,就不去做响应式。 如果是手机端,就去做响应式布局即可。
检测方法:
var sUserAgent = navigator.userAgent.toLowerCase();
if (/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent)) {
//如果是手机端
console.log('app')
} else {
//如果是电脑端
console.log('web')
}
到目前为止,我们做了响应式,也做了设备检测。 只需要把响应式内容加入到手机端的判断条件里即可。如果是PC端,就把fontSize固定即可。
以下是完整代码:
<!-- demo.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>responsive mode</title>
<link rel="stylesheet" href="./demo.css" />
<script>
var sUserAgent = navigator.userAgent.toLowerCase();
if (/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent)) {
// 如果是手机端
//改变font-size(做响应式)
(function(doc,win){
var docEI = doc.documentElement,
resizeEvt = 'orientationchange' in window?'orientataionchange':'resize',
recalc = function(){
var clientWidth = docEI.clientWidth;
if(!clientWidth) return;
//100是字体大小,1920是开发时浏览器窗口的宽度,等比计算
docEI.style.fontSize = 100*(clientWidth/1920)+'px';
}
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document,window);
} else {
//如果是pc端(固定fontSize)
document.documentElement.style.fontSize = '100px'
}
</script>
</head>
<body>
<div class="app">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
/*demo.css*/
* {
padding: 0;
margin: 0;
}
html {
font-size: 100px;
}
body {
font-size: 14px;
}
.app {
width: 15rem;
height: 3rem;
background-color: pink;
margin: auto;
}
.box1 {
width: 2rem;
height: 2rem;
background-color: aqua;
}
.box2 {
width: 2rem;
height: 2rem;
background-color: blueviolet;
margin-top: 0.1rem;
}
*注:响应式布局有很多方法,我在这里只讲了其中一种,也是公司做页面比较常用的一种方法。如果想了解更多,可以百度或在掘金里搜索更多响应式内容介绍。
以上。