移动端基础
移动端主流浏览器,主要对Webkit内核进行兼容
针对手机端开发,用Chrome dev模拟手机界面以及调试
视口
浏览器显示页面内容的屏幕区域,视口可以分为布局视口,视觉视口和理想视口
移动布局想要做到的是理想视口:手机屏幕有多宽,布局视口就多宽
想要理想视口,需要给移动端页面添加meta视口标签
-
布局视口layout viewport
-
视觉视口 visual viewport
-
理想视口 idea viewport
meta视口标签
<meta name="viewport" content="width=device-width, user-scalable=no,
initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

meta标签中常设置user-scalable=no也就是禁止用户缩放,那用户缩放到底会造成什么影响呢? 其实也就是显示上的变化。缩放一倍,CSS像素(逻辑像素,开发像素)所代表的物理像素也就缩放了一倍,即设备物理像素和设备独立像素的比例增大(减小)了一倍。
二倍图
-
物理像素&物理像素比
物理像素:就是分辨率,iphone的物理像素是750
在iphone8里,1px开发像素 = 2个物理像素
UI设计师要求的1px是指设备的物理像素1px,而CSS里记录的像素是逻辑像素(开发像素),它们之间存在一个比例关系,可以用javascript中的window.devicePixelRatio来获取,也可以用媒体查询的-webkit-min-device-pixel-ratio来获取。当然,比例是多少与设备相关。 -
二倍图
比如需要一个50*50像素(css像素)的图片,直接放到iphone里面会放大2倍 100*100
所以放一个100*100的图片,手动把这个图片缩小为50*50(css像素)
准备的图片 比实际需要的 大2倍,这种方式就是2倍图
多倍图切图cutterman -
背景缩放
background-size属性规定背景图像的尺寸:宽度,高度
单位: 长度 |百分比 |cover |contains
- 长度:只写宽度或只写高度,会等比例缩放
- 百分比是相对于父盒子缩放
- cover把背景图像扩展至足够大,以使背景图像完全覆盖背景区域(宽度和高度等比例拉伸,要完全覆盖盒子,可能有部分背景图片显示不全)
- contains把图像扩展至最大尺寸,使其宽度和高度完全适应内容区域(宽度和高度等比例拉伸,当宽度或高度到达盒子,就不再进行拉伸了,可能有空白区域)
例子:有一个50*50盒子需要背景图片,图片要准备2倍的,100*100
手动把图片缩放一半,也就是50*50
div:background-size:50px,50px
移动端项目需要注意的4个问题
1)meta中设置viewport
在 index.html中添加meta元素,设置viewport。
<meta name="viewport" content="width=device-width,initial-scale=1.0,
minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
阻止用户手滑放大或缩小页面:user-scalable=no
2)CSS样式统一问题
我们需要重置页面样式,因为在不同的手机浏览器上,默认的css样式不是统一的。
解决方法:使用reset.css重置所有元素的默认样式
3)一像素边框问题
viewport的设置和屏幕物理分辨率是按比例而不是相同的. 移动端window对象有个devicePixelRatio属性, 它表示设备物理像素和css像素的比例, 在retina屏的iphone手机上, 这个值为2或3, css里写的1px长度映射到物理像素上就有2px或3px那么长。
有的手机分辨率比较高,是2倍屏或3倍屏,手机上的浏览器就会把CSS中的1像素值展示为2个或3个物理宽度
在手机上border无法达到我们想要的效果,这是因为devicePixelRatio特性导致,iPhone的devicePixelRatio==2,而border-width: 1px描述的是设备独立像素,所以,border被放大到物理像素2px显示,在iPhone上就显得较粗。
解决方法:
- 添加一个border.css库,将利用scroll缩放的原理将边框重置。当我们需要使用一像素边框时只需要在标签上添加对应类名,如设置底部一像素边框就在标签上加入"border-bottom"的class名
- transform: scale(0.5) 方案 - 推荐: 很灵活
一般做法:将1px缩小为0.5px来展示,然而0.5px并不是所有的设备或浏览器都支持,就考虑用媒体查询或viewport将其缩放比例。
其实1像素问题的产生基本发生在设置边框或分割线的时候,场景并不覆盖全局样式,因此,直接缩放需要设置的元素,才是我们真正需要的。tranform就能实现这个需求。
/*设置height: 1px,根据媒体查询结合transform缩放为相应尺寸。*/
div {
height:1px;
background:#000;
-webkit-transform: scaleY(0.5);
-webkit-transform-origin:0 0;
overflow: hidden;
}
/*2.用::after和::befor,设置border-bottom:1px solid #000,然后在缩放-webkit-transform: scaleY(0.5);可以实现两根边线的需求*/
div::after{
content:'';width:100%;
border-bottom:1px solid #000;
transform: scaleY(0.5);
}
/*3.用::after设置border:1px solid #000; width:200%; height:200%,然后再缩放scaleY(0.5); 优点可以实现圆角,京东就是这么实现的,缺点是按钮添加active比较麻烦。*/
.div::after {
content: '';
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}
4) 300毫秒点击延迟问题
移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击。
FastClick.js
移动端浏览器
移动端浏览器基本以webkit内核为主,因此开发时考虑webkit兼容性问题
可以放心使用H5标签和CSS3样式
浏览器的私有前缀只需要考虑添加webkit即可
(浏览器私有前缀,是浏览器对于新CSS属性的一个提前支持,-webkit-是webkit内核,-moz-是Firefox Gecko内核,moz代表的是Firefox的开发商Mozilla。)
CSS初始化 normalize.css
修复了浏览器的Bug
保护了有价值的默认值
是模块化的,文档详细
CSS3盒子模型
传统模式宽度计算(box-sizing: content - box): 盒子宽度 = CSS中设置的width + border + padding
CSS3盒子模型(box-sizing:border-box):盒子宽度 = CSS中设置的宽度width
此时盒子设置多大就是多大,再设置padding和border也不会撑大盒子了
- 移动端可以全部CSS3盒子模型
- PC端如果需要完全兼容,使用传统;如果不考虑兼容性,使用CSS3盒子模型
移动端特殊样式
移动开发选择
- 单独移动端页面(主流) 网址域名前加m(mobile)可以打开移动端 m.jd.com 通过判断设备,如果是移动设备打开,则来到移动端页面
- 流式布局(百分比布局)
- flex弹性布局(推荐)
- less + rem + 媒体查询布局
- 混合布局
- 响应式兼容PC移动端 通过判断屏幕宽度来改变样式,以适应不同终端
- 媒体查询
- bootstrap
单独移动端页面
流式布局
就是百分比布局,也称非固定像素布局(常见)
通过把盒子的宽度设置成百分比,根据屏幕的宽度进行伸缩。不受固定像素的限制,内容向两侧填充
max-width 最大宽度(max-height)超过这个值就不缩放了
min-width最小宽度(min-height)
flex布局

布局原理
flexible Box 弹性布局,为盒状模型提供最大的灵活度,任何一个容器都可以指定为flex布局。
通过给父盒子添加flex属性,来控制子盒子的位置和排列方式
- 当为父盒子设为flex布局以后,子元素的float,clear和vertical-align属性将失效
- 伸缩布局 = 弹性布局 = 伸缩盒布局 = 弹性盒布局 = flex布局
- 采用Flex布局的元素,称为Flex容器(flex container)。它的所有子元素自动成为容器成员,称为Flex 项目(flex item)
常见父项属性
- flex-direction:设置主轴的方向(即项目的排列方向)
row (默认是从左到右) | row-reverse | column | column-reverse;
主轴和侧轴是会变化的,就看flex-direaction设置谁为主轴,另一个就是侧轴。
而我们的子元素是跟着主轴来排列的 - justify-content:设置
主轴
上子元素的排列方式(使用这个属性之前,先确定好主轴是哪个)
flex-start (默认是左对齐)| flex-end右对齐 | center居中 |space-between先两端贴边,再平分剩余空间
| space-around平分剩余空间,每个项目的margin-left,margin-right都相等 - flex-wrap:设置子元素是否换行
nowrap(默认是不换行) | wrap | wrap-reverse;
flex布局中,子元素默认是不换行。如果装不下,会自动缩小子元素的宽度,放在父元素里面 - align-items:设置
侧轴
上的子元素排列方式(单行)
flex-start(默认是从上到下) | flex-end | center(挤在一起居中,垂直居中) | baseline | stretch(拉伸,但子元素不要给高度); - align-content:设置
侧轴
上的子元素的排列方式(多行)子项出现换行的情况下
flex-start(默认在侧轴的头部开始排列) | flex-end | center(在侧轴中间) | space-between(子项在侧轴平分剩余空间) | space-around (子项在侧轴先分布在两头,再平分剩余空间)| stretch(子项元素高度是平分父元素高度的); - flex-flow:复合属性,相当于同时设置了flex-direction和flex-wrap
< flex-direction > || < flex-wrap >;
常见子项属性
- flex:子项目分配剩余空间所占的
份数
flex:< number >,默认0 - align-self:控制子项自己在侧轴上的排列方式(可覆盖align-items属性,如果没有父元素,则等同于stretch)
auto(默认继承父元素的align-items属性) | flex-start | flex-end | center | baseline | stretch; - order:定义项目的排列顺序
数值越小越靠前(和z-index相反),默认0
Grid网格布局
- 传统布局方式:利用position + display + float属性 (兼容性好,但麻烦)
- Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是
一维布局
(效率高,兼容性强) - Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是
二维布局
(目前兼容性不如flex,但Grid 布局远比 Flex 布局强大)
(待续)
rem适配布局
rem单位
- em是父元素字体大小
- rem(root em)是一个相对单位,基准是
相对于html元素
的字体大小
比如根元素(html)设置font-size=12px,非根元素设置width:2rem,则换算成px就是24px
rem的优点:可以通过修改html{}里面的文字大小,来改变页面中元素的大小,实现整体控制
媒体查询
Media Query是CSS3新语法
- 使用@meida查询,可以针对不同的媒体类型,定义不同的样式
@media可以针对不同的屏幕尺寸设置不同的样式
- 当重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面
- 为了防止混乱,媒体查询要按照从小到大(推荐)或从大到小的顺序来写,存在CSS重叠
语法规范
@media mediatype and | not | only (media feature) {
CSS-Code;
}
<style>
/*在屏幕上,并且最大宽度是800像素(<=800px),设置样式*/
@media screen and (max-width: 800px){}
</style>
- mediatype 查询类型
将不同的终端设备划分成不同的类型
all 用于所有设备;print用于打印机和打印预览;screen用于电脑屏幕,平板电脑,智能手机 - 关键字
将媒体类型或多个媒体特性连接到一起,作为媒体查询的条件
and 将多个媒体特性连接到一起 “且”
not 排除某个媒体类型 “非”
noly 指定某个特定的媒体类型 - 媒体特性
width
min-width
max-width
引入资源
当样式比较繁多的时候,可以针对不同的屏幕尺寸,使用不同的样式表
原理:直接在link中判断设备的尺寸,引用不同的css文件
<link rel="stylesheet" href="mystylesheet.css" media="mediatype and|not|only (media feature)" >
less基础
CSS是一门非程序式语言,没有变量,函数,作用域
Less(Leaner Style Sheets)是一门CSS扩展语言,也称CSS预处理器
npm install -g less
lessc -v 查看版本
- myless.less
- @变量名:值; 适用于颜色和数值
- 把less文件编译成css文件,html才能使用
- less嵌套:不用选择器
.header{
a{ //1. 子元素的样式直接写到父元素的样式里面
color: red;
&:hover{ //2.如果有伪类选择器,伪元素选择器,交集选择器,内层选择器的前面需要加&,a:hover{ }
color: blue;
}
}
}
- Less运算
任何数字,颜色或变量都可以参与运算
运算符中间左右有个空格隔开:1px + 5
对于不同单位的值之间的运算,运算结果取第一个值的单位
如果两个值之间只有一个值有单位,运算结果就取该单位
rem适配方案
- 让一些不能等比自适应的元素,达到当设备尺寸改变的时候,等比例适配当前设备
- 使用媒体查询,根据不同设备按比例设置html的字体大小;然后页面元素使用rem做尺寸单位,当html字体大小变化,元素尺寸也会发生变化,从而达到等比缩放的适配
可以按照设计稿与设备宽度的比例,动态计算并设置html根标签的font-size大小(媒体查询)
CSS中,设计稿元素的宽高,相对位置等取值,按照同等比例换算以rem为单位的值
- less + 媒体查询 + rem
- flexible.js + rem
响应式开发
需要一个父级作为布局容器,来配合子元素实现效果
原理:在不同屏幕下,通过媒体查询来改变这个布局容器的大小,再改变里面子元素的排列方式和大小
,从而实现在不同屏幕下,看到不同的页面布局和样式变化,做到适配不同的设备
Bootstrap前端开发框架
http://bootstrap.css88.com/,推荐3.x.x
控制权在框架本身,使用者要按照框架所规定的某种规范进行开发
布局容器
Bootstrap需要为页面内容和栅格系统包裹一个.container容器
,.contain是Bootstrap预先定义好的类
- container类
响应式布局的容器 ,固定宽度(不同屏幕尺寸下使用不同宽度,不用使用媒体查询了
)
大屏(>=120px)宽度定为1170px
中屏(>=992px)宽度定为970px
小屏(>=768px)宽度定为750px
超小屏(100%) - container-fluid类
流式布局容器,百分百宽度
占据全部视口(viewport)的容器
适合单独做移动端开发
栅格系统
grid systems 将页面布局划分为等宽的列,通过列数的定义来模块化页面的布局
Bootstrap提供了一套响应式,移动设备优先的流式栅格系统,随着屏幕或视口尺寸的增加,系统会自动分为最多12列
Bootstrap里面container宽度是固定的,但在不同屏幕下,container宽度不同,我们再把container划分为12等份
已经包含了Normalize.css
栅格选项参数
如果孩子的份数相加
等于12,则孩子能占满整个的 container的宽度
小于12,则孩子占不满整个的 container的宽度,会有空白
大于12,则多余的那一列会另起一行显示
列嵌套
再把一个列看成12等份
不能加margin值,内部实现是width平分,float=left
列偏移
操作右侧元素
偏移的份数= 12 - 两个盒子的份数
当只有一个盒子,想做居中效果,那就偏移12 - 盒子份数 / 2
列排序
把右侧盒子往左边拉pull,把左侧盒子往右边推push
响应式工具
visible-xs,visible-sm,visible-lg是显示某个页面内容