下面所要说的这个响应式解决方案,是我对比不同的方法再糅合整理成自己习惯的一套方案,一直都在使用,觉得还可以,不一定适合大家,也不可能适合所有的需要响应式的网站,但应付一些官网性质、展示性的静态网站还是游刃有余,总体说一下思路:rem + sass + media query。

响应式的网页设计稿最起码得提供一个PC版和移动版,这个对射妓师也是有一定的要求的:设计的元素能从PC端平滑过渡到移动端,例如一个图的排版在PC和移动端可以是不一样的,但是最好是同一张图片资源,对切图仔来说,就是在不改变DOM代码的情况只通过改变css样式达到改变排版布局。当然,从PC到移动端的过渡中,可以有多种不同视窗宽度范围的排版,只是设计师的前端media query的工作变多变繁琐了。

通常一个PC排版和一个移动端排版是最理想的,合理安排元素布局,互利共赢呀。

1、设置viewport

1
2
<!-- index.html -->
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1, user-scalable=no"/>

2、在head中js动态修改根节点html的字号

1
2
3
4
5
6
7
8
9
10
11
<!-- index.html -->
<script>
//重置html字体大小
var _resize = function(){
var html = document.documentElement,
w = html.clientWidth/1920, w =100*w;
html.setAttribute('style', 'font-size:' + w + 'px');
}
_resize();
window.addEventListener('resize', _resize);
</script>

通常先做PC端页面,因为PC端内容一般更加丰富,移动端有可能删减。上面代码中,PC端的设计稿是1920,以100px字体为基准,避免出现字号小于浏览器最小字号。

3、编写sass,引用编译出的css

1
2
3
4
5
6
7
8
9
10
/* index.scss */
$fontSize: 100px;
@function rem($px){
@return $px / $fontSize * 1rem;
}

.banner{
width: rem(1920px);
height: rem(500px);
}

先定义一个px转化为rem单位的函数rem(),我们就可以像平常按照设计稿的尺寸那样写px,把单位转化工作交给工具。我习惯了用koala来编译压缩,你也可以用grunt/gulp/webpack等前端自动化工具来编译。

至此,按照这样一发不可收拾、毫无顾忌地用固定布局的方式写出自适应的页面,在某个视窗宽度以上都视为PC端界面。而ipad使用PC端页面还是移动端页面,看视觉稿的实际情况,通常使用PC端页面的布局。

4、开始移动端媒体查询

1
2
3
4
5
6
7
8
9
10
11
12
/* index.scss */
@media screen and (max-device-width: 736px) {
$fontSize: 100px;
@function rem($px){
@return $px / $fontSize * 1rem * 1920 / 640;
}

.banner{
width: rem(640px);
height: rem(1280px);
}
}

上面就是以移动端640宽度视觉稿写的移动端样式,设备最大宽度是736px认为是移动端界面。因为head里面是以PC端1920宽度的设计稿来设置html根节点字号的,单位转化函数就要做一些改变了,乘以一个比例1920/640。这样子,又可以按照像平常那样按照640宽度来写px啦。

假如又多一个视窗宽度范围的视觉稿,做法一样,再写多一个媒体查询就好了,这样pc和移动端平滑过渡,响应式搞定。

这种方案的优缺点就很明显了:优点是,傻瓜式无痛coding,可以有效降低需要兼顾的视窗范围,可以简化成两种排版(PC和移动)或者只有一种。缺点是,在多种视窗排版的情况下,代码雍余的问题比较突出;所有单独背景图片资源需要设置background-size:100% 100%,雪碧图不好弄,定位也需要百分比,可以借助一下工具http://responsive-css.spritegen.com/