1、思考
在移动端愈来愈重要的背景下,每位web开发者对移动适配都有本身的想法。是移动优先,仍是PC优先,仍是二者兼得?在实际开发中这个问题是和项目产品定位有关的,也涉及到UI的设计,不是开发者能决定。但无论产品如何定位,做为开发者老是要提供最优的解决方案,是用一套样式仍是多套样式?网上一搜,有静态布局、流式布局,响应式布局,自适应布局,弹性布局等一堆,云里雾里,到底要怎么选呢?看完这篇文章相信心中就有数了。css
2、viewport的使用
一、最多见的设置,大多数的框架(如bootstrap)和知名的站点基本是这个配置html
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
二、这个配置重点在width=device-width,就是让视窗口等于设配宽度,也就是咱们开发中能用document的宽度,其它几个“初始缩放大小”“最大缩放大小”“最小缩放大小”和“是否容许用户缩放”能够理解为用来“固定”这个设置不被破坏的。
三、这个设置很简单,但同时也会带来一些须要解决的问题。
a、如今的手机都是两倍三倍的Retina高清屏,1px实际的效果是不止一个像素的,对不一样的设备设置不一样
的initial-scale能够有比较好的效果,好比在2倍Retina的iphone6(6s,7,8)中设置为0.5。一旦
动态设置这个,也就意味这视窗口不一样了,须要不一样样式适配。这也是分配样式的一套基准,如何分配样式
后面会有更详细的讲解。
b、在PC端若是有最小宽度的限制,一样须要配置不一样的width值。android
3、单位的使用
一、css中单位不少,这里只介绍最经常使用的几种:
(1) px:这个能够理解为“基准”单位,就是无论在什么设备中其值是不会变的,就像cm,kg这些同样
(2) em:这个是相对父容器的单位,通常用在字体font-size中比较好。如父容器font-size为16px,则
1em=16px
(3) rem:相对于根元素html的单位,如html的font-size为16px,则1rem=16px
(4) vw/vh: 视口宽高为100vw/100vh,这个和百分比相似,只是百分比是相对于父容器,其相对于视口
二、移动适配最经常使用的应该是rem,不少框架和淘宝的flexible适配都是基于这个单位,而本身作的话,通常
在首页加载时全局js设置html的font-size便可,代码以下:ios
(function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; if (!clientWidth) return; //这里根据设计稿为750,设置1rem=100px, docEl.style.fontSize = 100 * (clientWidth / 375) + 'px'; }; // Abort if browser does not support addEventListener if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); })(document, window);
3.若是用了sass/less等预编译语言能够更灵活的配置的,在上面方法内配置(设计稿为750的状况下):
docEl.style.fontSize = 40 * (clientWidth / 750) + 'px';
在编译函数中配置:
@function px2rem($px, $base-font-size: 20px) {
@return ($px / $base-font-size) * 1rem;
}
这样咱们就能够直接使用设计稿的尺寸,如:px2rem(100px),省去了本身计算,若是没用预编译语言(推
荐使用),编辑器也有插件支持单位转化。
4.上面是基于屏幕宽度来设置根元素font-size,若是设置不一样的initial-scale,咱们须要基于设备像素比设置,经过window.devicePixelRatio获取。css3
4、页面布局方式
1.理解html的文档流方式,其实就是流式布局,即横向须要咱们设置,纵向自动叠加。这个和移动端的设计体验方式是比较像的。在宽度中就要用自适应的方式,如百分比,有设置相对单位的,可用相对单位,灵活使用,css3的display:flex也是很好的选择,现代浏览器和移动设备基本都支持了。
2.刚才说到体验,很明显移动端和pc端的体验真的很不一样,因此光有上面的自适应是远远不够,是否是须要对这两个彻底不一样的体验方式响应不一样的布局和样式。web
5、媒体查询
1.咱们除了能够用js来判断不一样的设备,设置相对单位所用的根元素。另外一个强大的方式是能够经过css3强大的媒体查询来指定不一样的样式。
2.媒体查询的规则bootstrap
@media all and ([min-width|max-width|orientation|min-device-width|...]) { ... }
中括号[]中表示须要添加的条件,可匹配宽高/横竖屏/设备类型等,好比min-width:750px,表示最小宽度为750px,{}是在匹配模式下的样式。也有逻辑判断and/or/not链接不一样的规则浏览器
3.要是引入整个文件,能够在link标签中使用sass
<link rel="stylesheet" media="screen and (min-width:900px)" href="big.css" type="text/css" />
表示:当屏幕大于或等于900px时,将采用big.css样式来渲染Web页面。app
4.Bootstrap响应式设计这类栅格布局采用的就是这套方式。
6、1px像素边框问题
1.除了上面说到在viewport中设置缩放外,直接设置一个空元素缩放也是能够的
p{ width: 100px; height: 1px; background: red; display: block; transform: scaleY(.5); }
不足:圆角没法实现,实现4条边框比较麻烦,而且只能单独实现,若是嵌套,会对包含的效果产生不想要的效果,因此此方案配合:after和before独立使用较多
2.利用CSS对阴影处理的方式实现0.5px的效果
box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);
不足:颜色很差处理, 黑色 rgba(0,0,0,1) 最深的状况了。有阴影出现,很差用大量使用box-shadow可能会致使性能瓶颈。四条边框实现效果不理想。
3.图片实现,使用 background-image 实现1px有两种方式: 渐变 linear-gradient 或直接使用图片(base64)。渐变 linear-gradient (50%有颜色,50%透明)
div{ height: 1px; background-image:-webkit-linear-gradient(top,transparent 50%,#000 50%); background-position: top left; background-repeat: no-repeat; background-size: 100% 1px; }
不足:大量使用渐变可能致使性能瓶颈,代码量大,多背景图片有兼容性问题
7、图片高清化
1.可使用srcset属性设置,使用看https://www.zhangxinxu.com/wordpress/2014/10/responsive-images-srcset-size-w-descriptor/
2.背景图高清
a.使用上面介绍的媒体查询,如:
/* 普通显示屏(设备像素比例小于等于1)使用1倍的图 */ .css{ background-image: url(img_1x.png); } /* 高清显示屏(设备像素比例大于等于2)使用2倍图 */ @media only screen and (-webkit-min-device-pixel-ratio:2){ .css{ background-image: url(img_2x.png); } } /* 高清显示屏(设备像素比例大于等于3)使用3倍图 */ @media only screen and (-webkit-min-device-pixel-ratio:3){ .css{ background-image: url(img_3x.png); } }
b.image-set 实现高清化
.css { background-image: url(1x.png); /*不支持image-set的状况下显示*/ background: -webkit-image-set( url(1x.png) 1x,/* 支持image-set的浏览器的[普通屏幕]下 */ url(2x.png) 2x,/* 支持image-set的浏览器的[2倍Retina屏幕] */ url(3x.png) 3x/* 支持image-set的浏览器的[3倍Retina屏幕] */ ); }
c.不少网页端对图片的要求仍是没那么高的,不像app那样,图片通常用一张2倍高清图就行,最新的设备对以上属性的支持仍是能够的,对于要求高的应用使用
8、移动端click屏幕产生300ms的延时响应
1.缘由:在浏览器须要如何判断快速点击上,当用户在屏幕上单击某一个元素时候,例如跳转连接<a href="#"></a>,此处浏览器会先捕获该次单击,但浏览器不能决定用户是单纯要点击连接仍是要双击该部分区域进行缩放操做,因此,捕获第一次单击后,浏览器会先Hold一段时间t,若是在t时间区间里用户未进行下一次点击,则浏览器会作单击跳转连接的处理,若是t时间里用户进行了第二次单击操做,则浏览器会禁止跳转,转而进行对该部分区域页面的缩放操做。那么这个时间区间t有多少呢?在IOS safari下,大概为300毫秒。这就是延迟的由来。形成的后果用户纯粹单击页面,页面须要过一段时间才响应,给用户慢体验感受,对于web开发者来讲是,页面js捕获click事件的回调函数处理,须要300ms后才生效,也就间接致使影响其余业务逻辑的处理。
2.解决方案:
(1)使用fastclick.js,只要全局加入该文件并设置以下:
FastClick.attach(document.body);
(2) zepto的touch模块,tap事件也是为了解决在click的延迟问题
9、更改默认样式
//使用appearance改变webkit浏览器的默认外观 input,select { -webkit-appearance:none; appearance: none; } //winphone下,使用伪元素改变表单元素默认外观 //1.禁用select默认箭头,::-ms-expand修改表单控件下拉箭头,设置隐藏并使用背景图片来修饰 select::-ms-expand { display:none; } //2.禁用radio和checkbox默认样式,::-ms-check修改表单复选框或单选框默认图标,设置隐藏并使用背景图片来修饰 input[type=radio]::-ms-check, input[type=checkbox]::-ms-check { display:none; } //3.禁用pc端表单输入框默认清除按钮,::-ms-clear修改清除按钮,设置隐藏并使用背景图片来修饰 input[type=text]::-ms-clear, input[type=tel]::-ms-clear, input[type=number]::-ms-clear { display:none; } // 禁止长按连接与图片弹出菜单 a,img { -webkit-touch-callout: none } // 禁止ios和android用户选中文字 html,body {-webkit-user-select:none; user-select: none; } // 改变输入框placeholder的颜色值 ::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #999; } ::-moz-placeholder { /* Mozilla Firefox 19+ */ color: #999; } :-ms-input-placeholder { /* Internet Explorer 10+ */ color: #999; } input:focus::-webkit-input-placeholder{ color:#999; } // android上去掉语音输入按钮 input::-webkit-input-speech-button {display: none}
10、总结1.网站适配的终端能够用js或媒体查询的方式获取,分配对应的样式。2.布局上采用相对单位,百分比和flex的弹性方式。3.对移动端的特殊性进行适配,如1px问题,默认样式等。