1.移动端基础
1.1 浏览器现状
PC端浏览器
360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器(停止服务)、搜狗浏览器、IE浏览器
移动端浏览器
UC、QQ浏览器、欧朋浏览器、百度手机浏览器、360、搜狗、猎豹、谷歌等其他手机自带的浏览器
国内尚无自主研发的浏览器内核,就像国内的手机操作系统都是基于android 修改开发一样
总结:兼容移动端主流浏览器,处理webkit 内核浏览器即可
1.2 手机屏幕现状
- 移动端屏幕尺寸非常多、碎片化严重
- Android设备有多种分辨率,480X800、480X854、540X960、720x1280、1080x1920,还有2K、4K屏
- 近年来 iphone 的碎片化也加剧了,其设备主要分辨率有 640x960、640x1136、750x1334、1242x2208
- 作为前端开发人员无需关注这些分辨率,因为我们常用尺寸为 px(逻辑像素)
1.3 常见移动端屏幕尺寸
参考
https://www.material.io/resources/devices/
作为前端开发,不要去纠结 dp、dpi、pt、ppi 等单位,因为我们不是做原生开发的
1.4 调试方法
- chrome DevTools 模拟手机
- 搭建本地web服务,手机和服务器在一个局域网内,通过手机访问服务器
- 使用外网服务器,直接IP或者域名访问
2. 视口
布局视口
视觉视口
理想视口
2.1 为什么使用视口
移动开发兴起后,出现的概念
也就是说,如果我们开发的页面只需要适应PC端,则不用考虑视口的概念
看下面的代码,并没有对视口进行配置
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.box{width: 300px;}</style>
</head><body>
<img class="box" src="./3.jpg" alt="">
</body></html>
在PC端的表现和在手机端的表现分别如下
原因在于,我们在手机端浏览中渲染此页面时,手机设置了视口为980,而我们手机屏幕的宽度为 375,默认情况下PC上的内容是无法在手机端显示完整的,会出现横向滚动条
手机上的浏览器一般不会允许出现这个横向滚动条,所以都会对内容进行缩放,也就是原来需要在980px 上显示的内容,缩放到375px 上就能够展示,你们页面中的所有元素就都要进行等比例的缩放
所以,在我们看来,图片变小了
2.2 设置视口宽度
解决方法:设置视口
设置固定宽度
作用是覆盖默认980的设置,而是自己设置
<meta name="viewport" content="width=375">
再看一下手机端的表现
此时图片大小与PC端就一致了
原因在于设置了视口宽度与设备宽度一致,也就是1:1 的关系,则页面内容不会缩放,图片也就按照原来设置的尺寸展示
试实设置视口为750px 看看什么效果,说说为什么?
使用设备宽度
不同设备的宽度不一样,为了更好的适配不同的设备,可以使用下面的设置
<meta name="viewport" content="width=device-width">
2.3 设置缩放比
删除上面的代码,实时下面的代码
<meta name="viewport" content="initial-scale=1">
效果相当于
<meta name="viewport" content="width=device-width">
initial-scale 的值也可以设置为其他倍数
2.4 用户缩放
上面的 initial-scale 和 width ,都是开发人员设置的页面初始化的缩放设置
下面是对用户对页面缩放的控制
很多时候,我们不希望用户缩放页面,进而导致将我们的布局搞乱,可以使用下面的配置
user-scalable=no
完整配置
<meta name="viewport" content="initial-scale=1,user-scalable=no">
此时,用户就无法在浏览中进行页面的缩放
当然,也可以使用下面的配置替代 user-scalabel
<meta name="viewport" content="initial-scale=1,minimum-scale=1, maximum-scale=1">
为了兼容性,规范的写法是都写上
2.5 完整写法
结合前面所讲的所有只是,viewport 的完整写法如下
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimum-scale=1, maximum-scale=1">
2.6 通过 js 获取视口尺寸
可以通过下面的几种方法,获取视口的宽度,注意这里获取的是逻辑像素
console.log(window.innerWidth)
console.log(document.documentElement.clientWidth)
console.log(document.documentElement.getBoundingClientRect().width)
为了更好的兼容性,更推荐下面的写法
var clientWidth=window.innerWidth||document.documentElement.clientWidth||document.documentElement.getBoundingClientRect().width
可以通过下面的代码获取物理像素
console.log(screen.width)
可以通过如下方法获取像素比(dpr)
console.log(window.devicePixelRatio)
可以通过开发者工具显示出dpr
3. 像素
本节涉及的知识点:
分辨率、物理像素、CSS 像素、设备像素比(dpr)、标清屏和高清屏、缩放、PPI/DPI
3.1 物理像素
手机屏幕横向有828个点
手机屏幕纵向上有1792个点
同等大小屏幕下,点越多、图像显示越精细
上面所说屏幕上一个个点就是物理像素(physical pixel)
物理像素也叫设备像素(dp:device pixel)
可见,每个像素就是一个点,每个点由红绿蓝三原色组成,只需要控制每个点每种颜色的明暗,就可以显示不同的颜色
实际开发中使用物理像素吗
看下面的例子
同等屏幕大小的两个手机
一个横向有2个物理像素,一个有4个物理像素
如果使用物理像素,则很明显展示的效果不一样,在高清屏幕下,可能图片会显示的很小,设置都会看看不清楚
也就是说,在实际开发中,我们使用设备的物理像素
3.2 CSS 像素
CSS 像素,也叫逻辑像素(logical pixel)
也成为 设备独立像素(dip:divice independent pixel)
我们在开发当中使用的就是CSS像素
.box {
width: 1000px;
height: 500px;
}
CSS像素与物理像素的关系
mark
在标清屏下,1个css像素使用1个物理像素展示
在高清屏下,1个css像素使用4个物理像素表示
注意:高清屏下,4个点相当于标清屏下1个点的大小,所以说在高清屏下1个css像素使用4个物理像素表示
点越多,展示的越精细,想想灯带。。。。
浏览器会根据当前设备屏幕,自动换算出1个CSS像素使用多少个物理像素表示
3.3 设备像素比
设备像素比(dpr:device pixel ratio)
dpr=设备像素/CSS 像素(缩放比是1的情况下)
所以上面两种屏幕下的 dpr 分别为
mark
dpr=2 表示的1个css 像素使用 2X2 个设备像素绘制
注意:计算时指的是1个方向上,横向或者纵向
所以 dpr>1 的我们都可以认为是高清屏
3.3.1 二倍图
对于一张50px * 50px(css像素)的图片,在手机 Retina 屏中打开,按照上面介绍的物理像素比会放大倍数,这样会造成图片模糊
在标准的viewport 设置中,使用倍图来提高图片质量,解决在高清屏设备中的模糊问题
通常使用二倍图,因为在 iphone6\7\8 的影响,但是现在还存在3倍图、4倍图的情况,这个看实际开发公司需求
背景图片注意缩放问题
具体解决方案
准备一张100 * 100 的图片,但是通过css 将其设置成50 * 50,在高清屏上,会将其放大2被,变成 100 * 100,因为图片背身就是100 * 100,所以不会失真
需要注意的是,一定将其设置成50 * 50,否则会将其放大成200 * 200,仍然会失真
如何快速起初2倍图、3倍图,别忘了我们PS中的切图神器
3.4 缩放
缩放改变的是CSS像素,毕竟我们没有法力
放大:
mark
缩小:
3.5 PPI
每英寸的物理像素点,见图1
ppi:pixels per inch,可以根据勾股定律进行英寸
注意,因为手机不是正方形的,所以 6.1英寸只是大约值,实际计算时,可以使用 6.06
dpi:dots per inch
- 移动端开发选择
4.1 主流方案
单独制作移动端页面(主流):一般在域名前面加上 m,可以打开移动端,如果是移动设备,能够自动判断,也就是说同各国检测时PC设备还是移动设备,响应不同的页面
响应式页面兼容移动端(其次):根据屏幕的宽度来改变样式。缺点:制作麻烦、需要花很大精力去调兼容性问题 - 移动端技术解决方案
5.1 移动端浏览器
移动端浏览器基本以 webkit 内核为主,因此只需要考虑 webkit 兼容性即可
可以放心使用 H5 和 CSS3 的新特性
同时浏览器的私有前缀只需要添加 webkit 即可
mark
5.2 CSS 初始化
normalize.css
保护了有价值的默认样式
修复了浏览器的bug
模块化的
拥有详细的文档
http://necolas.github.io/normalize.css/
5.3 CSS3 盒子模型 box-sizing
设置盒子的尺寸以内容为准还是边框为准
传统模式宽度计算:盒子宽度= CSS 中设置的 border+width+padding
CSS3 盒子模型:盒子宽度=CSS 中设置的width 里面包含了 border 和 padding
也即是说 CSS3 盒子模型中,padding 和 border 的设置不会撑大盒子了
注意:移动端可以全部使用CSS3盒子模型,PC端如果需要兼容,使用传统模式,不考虑兼容,使用CSS3 盒子模型
点击超链接时,会有背景高亮效果,建议去除
按钮会有默认样式,建议去除
图片、超链接等长按会弹出菜单,建议去除(兼容性很不好)
a {
/* 去除超链接点击时的背景高亮效果 /
-webkit-tap-highlight-color: transparent;
}
/ 禁用长按显示菜单 */
img,
a {
-webkit-touch-callout: none;
}
/去除按钮的默认样式,然后才可以为按钮自定义样式/
button,
input {
-webkit-appearance: none;
}
6. 移动端常见布局
6.1 移动端技术选型
首先从下面两种方案中选择一种
单独制作移动端页面(主流)
流式布局(百分比布局)
flex弹性布局(强烈推荐)
less+rem+媒体查询布局
混合布局
响应式页面兼容移动端
媒体查询
bootstrap
6.2 流式布局
流式布局,就是百分比布局,也称作非固定像素布局
通过盒子的宽度设置城百分比来根据屏幕的宽度进行伸缩,不受固定像素的限制,内容向两侧填充
流式布局时移动web开发使用的比较常见的布局方式
6.3.2 初始化主页
引入 normalize.css
引入 index.css
编写视口
参考京东移动端代码
mark
6.3.4 头部布局
mark
京东头部可以分为4个部分
通过查看京东官网发现,百分比分别为 8%、10%、57%、25%
第4部分的颜色与其他部分的背景颜色不一致
html中添加头部
- 8
- 10
- 57
- 25
在 index.css 中编写样式
/* 头部样式 */
.app{
width: 100%;
height: 45px;
}
.app ul{
margin: 0;
padding: 0;
list-style-type: none;
}
.app li{
float: left;
height: 45px;
background-color: #333333;
}
.app li:nth-child(1){
width: 8%;
}
.app li:nth-child(2){
width: 10%;
}
.app li:nth-child(3){
width: 57%;
}
.app li:nth-child(4){
width: 25%;
background-color: #f63515;
}
填充内容
第一部分是一个关闭图标,尺寸为1010
第二部分为网站Logo,尺寸为3030
第三部分和第四部分文字为白色
头部所有文字和图片都是水平居中且垂直居中对齐
注意图片无法通过设置行高等于高度的方式居中对齐
修改 index.html 中的 header 中的代码
mark
修改 index.css 中的代码
mark
mark
6.3.5 搜索制作
通过观察京东,发现如下几点
搜索分为三部分
左侧展开折叠按钮尺寸固定,不要使用百分比
右侧登录按钮尺寸固定,不要使用百分比
中间搜索框会随着屏幕大小的调节而进行缩放
技术实现
搜索区域高度为44px
左右两侧按钮宽高都为40*44,且分别做固定在左边和固定在右边,需要使用绝对定位
中间搜索区域白色背景,圆角,高度为30px,margin-left 和 margin-right 分别为50px
布局
在 index.html 中加入如下代码
mark
制作左侧和右侧
左侧和右侧相对简单,所以先制作这两部分
html 代码
mark
css 代码
mark
制作放大镜
京东上使用的是二倍精灵图,所以使用起来要遵循下面步骤
将精灵图等比例缩小一半
之后根据大小测量坐标
注意代码里面background-size也要写成精灵图原来的一半
html 代码
mark
css 代码
mark
制作输入框
html 代码
mark
css 代码
mark
6.3.6 焦点图
html 代码
mark
css 代码
mark
不要忘了,将 search-box 盒子的定位修改为 固定定位,且 宽度设置为 100%
mark
6.3.7 活动区域
html 代码
mark
css 代码
mark
6.6.8 类别区域
html 代码
mark
- flex 布局
7.1 传统布局与flex布局
传统布局:
兼容性好
布局繁琐
局限性,对移动端的支持不好
flex 唐兴布局
操作方便,布局极为简单,移动端应用广泛
PC段浏览器支持情况较差
IE11或更低版本,不支持或仅部分支持
建议:
PC端页面,使用传统布局
移动端页面或者不考虑兼容性问题的PC段页面布局,使用flex 弹性布局
7.2 爱的初体验
html 代码
mark
加入flex
为 div 加入如下 css 样式
mark
运行结果
mark
总结
在为div设置 display:flex 之前,span元素的 display=inline
在为div设置 display:flex 之后,span 元素的display=block,所以高度生效,但是因为宽度没有设置,故为内容宽度
可见,通过为父元素设置 display:flex 子元素无论原来是什么元素,都会变成 block,但是宽度并不会占据父元素的100%,而且也不会独占1行
设置固定宽度
可以为span元素设置宽度
span{
width: 100px;
height: 100px;
background-color: #fff;
}
设置后,宽度会生效,但是,当调整浏览器宽度,默认情况下,span的宽度仍然会压缩
设置对齐方式
在 div 中加入如下代码
mark
运行结果
mark
设置平分
也可以不设置固定宽度,而是使用如下代码
span {
/* width: 100px; */
flex: 1;
height: 100px;
background-color: #fff;
}
此种设置三个span元素将会评分父元素的宽度
mark
7.3 布局原理
flex:flex box 的缩写
意为 弹性布局,用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex,但是我们不会变态到将 i 标签指定为 flex
当我们将父盒子设置为flex后,子元素的float、clear、vertical-align 属性失效
采用Flex布局的元素,成为Flex容器(flex container),简称“容器”,它的所有子元素自动成为容器成员,成为Flex项目(flex item),简称“项目”
子元素可以横向排列,也可以纵向排列
mark
布局原理总结
通过给父盒子添加flex属性,来控制子盒子的位置和排列方式
7.4 容器常用属性
一下属性用于设置容器,也就是父盒子
felx-direction:设置主轴的方向,也就是项目横向排列还是纵向排列
justify-content:设置主轴上的子元素的排列方式
flex-wrap:设置子元素是否换行
align-content:设置侧轴上子元素的排列方式(多行)
align-items:设置侧轴上的子元素排列方式(单行)
flex-flow:复合属性,相当于同时设置了flex-directon 和 flex-wrap
7.4.1 flex-direction
在flex布局中,分为主轴和侧轴
默认情况下,水平方向为主轴,水平向右,垂直方向为侧轴,垂直向下
mark
flex-direction 属性可以改变默认的主轴设置
设置行为主轴
设置水平方向为主轴,项目从左向右排列
body {
background-color: #ccc;
}
div {
display:flex;
/设置容器的主轴为X轴,也就是行为主轴,此值为默认值/
flex-direction: row;
width: 800px;
height: 400px;
background-color: #000;
}
span {
width: 100px;
height: 100px;
background-color: #fff;
border: 1px solid black;
}
设置主轴反转
反转主轴
设置水平方向为主轴,项目从右向左排列
只需要将如下代码
flex-direction: row;
修改为
flex-direction: row-reverse;
设置列为主轴
设置主轴为垂直方向,项目从上到下排列
设置 flex-direction 的值 column
flex-direction: column;
将上面的代码改为
flex-direction: column-reverse;
项目从下到上排列
总结
主轴不是固定的
项目永远沿主轴排列,所以设置主轴为水平方向,项目1行排列;设置主轴为垂直方向,项目1列排
7.4.2 justify-content
设置主轴上项目的排列方式
使用此属性之前,要确定主轴是哪一个,主轴不一样,设置的值也不一样
flex-start 默认值,从头部开始,如果主轴是x轴,则从左到右
flex-end 从尾部开始排列,如果主轴是y轴,则从又到左
center 在主轴居中对齐,如果主轴是x轴,则水平居中
spance-around 评分剩余空间
spance-between 先两边贴边,再评分剩余空间
7.4.2.1 X轴为主轴时
flex-start
body {
background-color: #ccc;
}
div {
display:flex;
/设置容器的主轴为X轴,也就是行为主轴,此值为默认值/
flex-direction: row;
/* 设置项目从左到右排列 */
justify-content: flex-start;
width: 800px;
height: 400px;
background-color: #000;
}
span {
width: 100px;
height: 100px;
background-color: #fff;
border: 1px solid black;
}
mark
这与没设置 justify-content:flex-start 没有区别
修改 justiry-content 的值为 flex-end
flex-end
/* 设置项目从左到右排列 */
justify-content: flex-end;
mark
注意,这里仅仅是改变了项目的起始方向,并没有改变项目的排列顺序,而我们上面说的 flex-direction 的翻转会改变项目的排列顺序
将 justify-content 的值设置为 center,所有元素居中显示,两边编剧一致
center
justify-content:center;
mark
spance-around
justify-content:space-around;
问题:为什么明明是评分剩余空间,项目的中间距离,看起来是左侧两侧边距的2倍?
mark
注意:
容器-所有项目宽度之和,就是主轴上剩余的空间,这里的平分是指项目之间的距离平分这些空间
如果设置项目的flex:1,而不是设置项目的固定宽度,那么无论 justify-content 的值设置为什么,都没有效果,因为项目会自动占满整个容器宽度
space-between
justify-content:space-between;
mark
7.4.2.2 Y 轴为主轴
省略
7.4.3 flex-wrap
传统布局中,设置子盒子浮动后,如果1行占不下,会自动另起一行
但是在 flex 布局中,则不然
html 代码
body {
background-color: #ccc;
}
div {
display:flex;
/设置容器的主轴为X轴,也就是行为主轴,此值为默认值/
flex-direction: row;
/* 设置项目从左到右排列 */
justify-content:flex-start;
width: 500px;
height: 400px;
background-color: #000;
}
span {
width: 150px;
height: 100px;
background-color: #fff;
border: 1px solid black;
}
我们发现,当1行站不下所有项目时,会自动缩小项目的宽度
如果不希望改变宽度,而是另起一行,只需要在容器中据加入如下设置即可
flex-wrap: wrap;
mark
问题:为什么两行之间的垂直间距这么大?
扩展
如果主轴为Y轴,则效果如下
mark
7.4.4 align-items
设置项目在侧轴上的排列方式
但是此属性适合项目为单行时
侧轴默认是Y轴,当然可以改变
flex-start 默认值,从上到下
flex-end 从下到上
center 挤在一起居中
stretch 拉伸
7.4.4.1 解决的问题
当前只能通过 justify-content 设置项目在主轴上的位置
div {
display:flex;
/设置容器的主轴为X轴,也就是行为主轴,此值为默认值/
flex-direction: row;
/* 设置项目从左到右排列 */
justify-content:center;
width: 500px;
height: 400px;
background-color: #000;
}
mark
无法设置项目在侧轴上居中,对于当前来说,侧轴是y轴,那么也就是设置垂直居中
有人可能想到做如下修改
flex-direction: column;
但这样只是修改了主轴为y轴
mark
当前属性就是用来解决这个问题的
7.4.4.2 设置侧轴居中
只需要在容器中加入
mark
效果
mark
问题:如果主轴为y轴呢?
mark
效果
mark
当然此属性的只也可以设置为其他几个
其他几个值都比较简单,稍微需要注意的是 stretch ,意思是拉伸,如果主轴是x轴,那么就会拉伸项目的高度与父元素一样高,但是项目不能设置固定高度,否则无效
7.4.5 align-content
设置侧轴上的子元素的排列方式
这与 align-items 相似,区别在于,此属性用来设置多行项目(也就是项目换行)时的排列方式,在单行项目下时没有效果的
flex-start 默认值,在侧轴的头部开始排列
flex-end 在侧轴的尾部开始排列
center 在侧轴的中间显示
space-around 子项在侧轴评分剩余空间
space=between 子项在侧轴先分布在两头,再平分剩余空间
stretch 设置子项元素高度平分父元素
flex-start
mark
思考,主轴为y轴时如何排列
flex-end
mark
center
mark
space-around
mark
space-between
mark
**align-items 和 align-content 对比
align-items 适用于单行情况下,只有上对齐,下对齐,居中和拉伸
align-content 适用于多行,单行下无效,可以设置对上对齐、下对齐、居中、拉伸一级平分剩余空间等
7.4.6 flex-flow
flex-direction 和 flex-wrap 的复合属性
flex-flow: column nowrap;
7.5 项目常见属性
flex 项目占的份数
align-self 控制子项自己在侧轴的排列方式,前面的align-items 和 align-content 是对所有子项应用相同的排列方式,而这个属性是对单个子项应用个性化的排列方式
order 定义项目的排列顺序(前后顺序)
7.5.1 flex
定义子项目分配剩余空间,用 flex 属性表示占多少分
分配的容器的剩余空间会增加到元素的宽度上
项目一旦设置固定宽度,就不会参与分配剩余空间
flex 的默认值为0,0就表示不参与分配剩余空间
项目一旦设置了flex,就不能再设置固定宽度
如果flex 的值为其他数字,则表示在分配剩余空间时所占的分数
圣杯效果
7.6.2 初始化主页
mark
7.6.3 编写body样式
body {
max-width: 540px;
min-width: 320px;
margin: 0 auto;
background: #fafafc;
/* 去除横向滚动条 /
overflow-x: hidden;
/ 去除移动端中超链接点击时的背景高亮效果 */
-webkit-tap-highlight-color: transparent;
}
7.6.4 布局分析
很多元素的高度都是固定的,不会随着窗口的变化而变化
7.6.5 搜索区域
固定定位
宽度设置为100%,因为设置为固定定位后,盒子成为inline-block
设置最大宽度、最小宽度,因为固定定位的元素的父元素是窗口,不是body,所以在body中设置的最大宽度、最小宽度、以及宽度,搜索盒子都不会继承,必须单独设置
水平居中的两种方式
CSS3属性的兼容性写法
html 代码
mark
index.css 中设置搜索框内部元素样式
mark