一、概述
1.1移动端的三大操作系统
1.Android
2.IOS
3.windows phone
其中安卓和IOS系统占的比重较大
1.2移动端的浏览器内核
手机是更高级的计算机,有些能力不必计算机差
五大主流浏览器:
iE 火狐 谷歌 苹果 欧朋
浏览器内核:浏览器内核又可以分成两部分:渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。它负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。
四大浏览器内核
1.Trident内核 代表IE浏览器
2.Gcko内核 代表火狐浏览器
3.Webkit内核 代表苹果浏览器和旧版谷歌浏览器
4.link内核 代表谷歌浏览器和欧朋浏览器
移动端最常用的内核还是Webkit。
二、视口
2.1视口
分辨率:分辨率就是屏幕的像素数量,比如1920*1080,指的是横向有1920个像素点,纵向有1080个像素点。所谓像素点就是物理元件的最小发光点。
先在PC端看一下分辨率对浏览器显示的影响:
网页的版心都是固定的,都是1000px,如果电脑分辨率越大,会导致横向像素的呈递数量越多,网页占据的真实宽度就越小,字也会越小。
再来讨论移动端的分辨率
手机的分辨率一般比pc端的分辨率大,但是我们手机屏幕比电脑小很多,如果手机真的用自己的分辨率去呈递网页的话,就会非常密集,自会非常的小。
在很久之前,乔布斯提出了,可以用手机呈现网页,但是由于当时大多数的网页都是以980px为版心的形式,所以,可以将手机设置一个宽度为980px,这样就可以实现对网页的一个兼容显示,此时我们手机就刚刚好能够卡住版心区域。
*****************************************
对前面知识的复习:
用getElementById("Id")获取到的是一个单标签而用getElementsByTagName或者getElementsByClassName获取到的都是数组。
querySelectorAll获取到的是一个数组,而querySelector()获取到的是单个标签。
而且在用getElementsByTagName("div")[n];这种写法是正确的,相当于只获取了第n+1个div标签,下面写样式的时候就不用写成数组元素形式,直接写数组名。
而且在getElementById("Id")中括号中的Id不需要加#,而在querySelector("#Id")中括号中的Id需要加#。
用下面的语句显示手机的宽度,发现是980。所有的手机浏览器显示的都是980。
<script>
var nH1 = document.getElementsByTagName("h1")[0];
nH1.innerHTML = document.documentElement.clientWidth;
</script>
但是实际上手机的像素并不是980,而比980大。
无论我们测试什么手机设备都会得到这个结果,980是所有设备的viewport(初始视口宽度),浏览器会以980来显示页面。
因为分辨率越大手机上显示的字就越小,实际上980px相对于手机页面还是很大,因此乔布斯又提出了一个想法,让开发者自定义移动设备的视口宽度。
<!-- 配置移动端的视口 -->
<meta name="viewport" content="width=300px">
通过上述一行代码可以让开发者自定义视口宽度,当我们设置了浏览器的宽度是300px时,浏览器就会认为自己的宽度就是300px,此时就会按照300px在显示页面。
我们发现,不同的视口大小,呈递相同的页面,给人的感觉是不一样的。尤其是看文字,h1默认的文字是32px,如果你设置的视口宽度是980px,此时会发现字特别的小,如果是320左右,此时感觉视觉效果能接受
2.2视网膜屏幕概念
当前我们浏览器现实的像素比并不是真正的手机像素比,所以在开发的时候并不用关心某一个型号手机的分辨率。
乔布斯提出了“设备像素比”的概念,我们可以通过dpr(device pixel radio)来获取或者设置当前的设备像素比。
获取设备像素比:
nH2.innerHTML = window.DevidePixelRadio;
我们知道了设备像素比,然后也知道了视口是可以自定义的,但是我们工作中都是用设备的宽度进行设置
我们可以设置下面的代码,为设备的宽度,此时会计算出当前设备的视口宽度
<meta name="viewport" content="width=device-width, initial-scale=1.0">
content的属性值介绍:
- width=device-width 约束视口的宽度
- initial-scale=1.0 初始视口的宽度是1倍
- minmum-scale=1.0 用于设置最小缩放比例取值取值1.0-10.0
- maximum-scale=1.0 用于设置最大缩放比例取值1.0-10.0
- user-scalable=no 是否允许用户缩放,默认是yes
常见的浏览器调试手机型号的视口宽度
- iphone8plus: 414px
- iphone6: 372px
- 三星Galaxy S5: 360px
如果将视口宽度和显示区域的宽度设置一致,那么页面就会全部显示。
三、百分比布局
此时设备都有了一个自己的宽度,大概是320-450之间,设备和设备是不一样的。
我们希望页面是没有版心,这是应为:
- 手机已经很小了,如果再有版心,会很难看。比如iphone宽度是414,如果版心360,此时页面左右会各占27px的白边
- 手机app都是撑满屏幕,用户总是希望看到网页的时候,也是撑满屏幕的效果
我们会发现每一个手机 的约束视口的宽度是不一样的,比如我们的iphone8plus是414,而iphone8是375,此时我们的版心该如何设置?答案是不能设置固定像素,可以设置弹性盒子
3.1、百分比布局
百分比布局又叫流式布局,单位是%。
如果width和height属性设置百分比,则参考的是父盒子的width或者height(client区的宽);如果没有父元素,则参考的就是body标签。
如果padding属性设置百分比,参考的是祖先元素的宽度的百分比。(无论哪个方向的padding参考的都是父盒子的宽度)。
如果margin属性设置百分比,参考的也是祖先元素的宽度的百分比。(无论哪个方向的margin参考的也是父盒子的宽度)。
border属性不支持百分比布局。
绝对定位元素如果设置百分比,此时width、height、padding设置百分比参考的是距离自己最近的有相对定位的父元素。定位会脱标,浮动也可以。
3.2box-sizing属性
作用是设置如何计算盒子的实际占有宽高。
实际占有宽高=width + padding + border
上面我们对盒模型的认知是盒子是外扩的,也就是如果我们在width和height 有值的基础上设置padding或者border,盒子会变大
box-sizing有三个属性值,一个是border-box,代表的是盒模型内缩,现在的width = 盒子本身的width - 左右padding - 左右border;第二个属性值是content-box(默认值),这个与外扩式盒子的宽高相同;第三个属性值是inherit,代表继承父盒子的box-sizing的值。
padding:10px 20px 30px 40px; 分别是上右下左顺时针方向。
Android4之前的需要加-webkit-
IOS4.3之前需要加-webkit-
3.3calc()属性
固比固描述:上图中左边是固定的200px,右边是固定的200px,中间是根据整个页面剩余宽度进行的适配,所以中间是不能设置固定宽度,整个就是比例宽度,所以,这种设计叫做固比固。
如何实现固比固?
第一种方法,通过box-sizing和绝对定位实现的
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 100px;
}
.left{
width: 200px;
background: red;
position: absolute;
left: 0;
top: 0;
}
.center{
width: 100%;
padding: 0 200px;
background: black;
box-sizing: border-box;
}
.right{
width: 200px;
background: blue;
position: absolute;
right: 0;
top: 0;
}
</style>
相当于box-sizing内缩把左右padding让出了200px,然后通过绝对定位即可实现固比固。
第二种方法,利用计算属性calc()属性。
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 100px;
float: left;
}
.left{
width: 200px;
background: red;
}
.center{
width: calc(100% - 400px);
background: black;
}
.right{
width: 200px;
background: blue;
}
</style>
</head>
calc()有计算功能
比如width:calc(200px - 100px);需要注意的是,两个数字之间需要用空格隔开,否则不会识别。
第三种方法,用flex布局实现
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 100px;
}
.box{
display: flex;
}
.left{
width: 200px;
background: red;
}
.center{
background: black;
flex:1;
}
.right{
width: 200px;
background: blue;
}
</style>
给容器设置display:flex;属性,把两边盒子的宽度定死,然后对中间的盒子设置flex:1;让他自动占满容器剩余的空间。
3.4、min-和max-属性
我们可以通过min-width或者min-height实现最小的宽度和最小高度的设置,也可以通过max-width或者max-height实现最大的宽度和最大高度的设置
div {
min-width: 500px;
max-width: 800px;
min-height: 200px;
max-height: 300px;
background: orange;
}
上面的div盒子的最大宽度是800px,最小宽度是500px,在500-800px之间是有弹性空间
最大高度是300px,最小高度是200px,在200-300px之间是有弹性空间
在不知道元素具体区域宽高的时候,使用这些属性能很好让网站实现自适应效果。如果min>max,则按min来设置宽高
当我们通过拉动网页来改变盒子显示大小的时候,在小于min-width时就不能再缩小了。
当一个设置了弹性空间的div盒子里嵌套子元素,子元素的宽高必须在min-和max-之间,如果超出的话,父盒子会按max-显示自己的宽高,而子盒子会超出父盒子显示。
四、flex布局
参考博客:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为 Flex 布局。
比如我们给一个盒子设置display:flex属性,此时这个盒子的内部拥有了flex布局能力
**************************************************************************************************
选择器的权重一定要给够,不能怕麻烦。
- 内联样式,如: style="...",权值为
1000
。 - ID选择器,如:#content,权值为
0100
。 - 类,伪类、属性选择器,如.content,权值为
0010
。 - 类型选择器、伪元素选择器,如div p,权值为
0001
。 - 通配符、子选择器、相邻选择器等。如
* > +
,权值为0000
。 - 继承的样式没有权值
Webkit 内核的浏览器,必须加上-webkit前缀。
.box{
display:-webkit-;//Safari
display:flex;
}
1.父盒子设置display:flex;
<style>
*{
margin: 0;
padding: 0;
}
.box{
height: 100px;
display: flex;
background: red;
}
.box .item1{
width: 100px;
background: cyan;
}
.box .item2{
width: 100px;
background: yellow;
}
.box .item3{
width: 100px;
background: green;
}
</style>
如上述代码所示,在给父盒子设置了display:flex;后,三个子盒子自动在一行,不用再给每个兄弟盒子设置浮动。
2.父盒子设置display:inline-flex;
如果父盒子设置了inline-flex,此时父盒子的宽度不是撑满父盒子的宽度,而是被子元素撑满。如果每个子盒子的宽度太大超过了屏幕显示范围则会显示出进度条而不是像flex状态下直接设置最大宽度。
<style>
*{
margin: 0;
padding: 0;
}
.box{
height: 100px;
display: inline-flex;
background: red;
}
.box .item1{
width: 100px;
background: cyan;
}
.box .item2{
width: 100px;
background: yellow;
}
.box .item3{
width: 100px;
background: green;
}
</style>
flex布局其实就是分为容器和项目,容器就是指的是当前的父盒子的状态,项目就是内部的子元素的状态
<div class="box"> →display:flex
<div class="item1 item"></div>→width:100px
<div class="item2 item"></div>→width:100px
<div class="item3 item"></div>→width:100px
</div>
.box是容器,.item是项目
4.1容器的属性
******************************************************************************
用line-height设置文字在盒子中垂直居中,让line-height的值等于外层盒子的高度即可
1、flex-direction属性
一共有四个属性值
- row:水平排列起点在左端
- column: 垂直排列起点在顶端(在flex及inline-flex状态下可以不用满足高度之和)
- row-reverse: 水平排列起点在右端
- column-reverse: 垂直排列起点在低端(这种情况下父盒子的高度一定要满足子盒子高度之和)
2.flex-wrap属性
flex布局如果默认的情况是水平一条线的,如果需要换行,要设置flex-warp属性
在flex布局下,如果一行的宽度之和大于这一行的宽度,不会换行显示,会按当前最大显示宽度平均分给这几个盒子作为宽度。
如果需要换行并且让这几个盒子按照我们设置的宽度来加载,则需要设置flex-wrap属性。
<style>
*{
margin: 0;
padding: 0;
}
.box{
height: 100px;
display:flex;
flex-direction: row;
background: red;
font-size: 30px;
color:#FFF;
text-align: center;
line-height: 100px;
flex-wrap:wrap;
}
.item{
width: 300px;
}
.box .item1{
background: cyan;
}
.box .item2{
background: yellow;
}
.box .item3{
background: green;
}
.box .item4{
background: blue;
}
.box .item5{
background: black;
}
.box .item6{
background: orange;
}
</style>
wrap:表示超出宽度换行
nowrap:表示不换行(默认的)
wrap-reserse:第一行在下面显示并且超出部分换行,如下所示。(在inline-flex下父盒子高度需要给够,不然不会显示。)
3.flex-flow属性
将flex-direction和flex-wrap结合起来的效果,其实就是一个复合写法。
flex-flow:<flex-direction> <flex-wrap>;
比如我们需要让项目倒序并且换行排列,就可以按下述代码进行描写:
flex-flow:column-reverse wrap-reverse;
4.justify-content属性
当前项目的对齐方式
属性值有:
- flex-start:(默认值)左对齐
- flex-end: 右对齐
- center: 居中
- space-between: 两端对齐,项目中间剩余空间等分
- space-around:每个项目之间左右距离等分
5.align-items属性
作用:设置项目垂直方向的对齐方式。
flex-start:垂直顶点
flex-end: 垂直底点
center:垂直居中
baseline: 项目的第一行文字基线对齐(当每个项目的文字行高不一样时会比较容易看出)
stretch: (默认值)如果该项目没有设置高度,或者是auto,会撑满父盒子的高度
6.align-content属性
作用是设置多行项目垂直方式的对齐方式。
6个属性值:
- flex-start:垂直方向顶端对齐
- flex-end:垂直方向低端对齐
- center:垂直方向居中对齐
- space-between: 垂直方向两端对齐,剩余空间平分
- space-around: 垂直方向平分,项目的垂直方向间隔相等
- stretch:(默认值)平分垂直方向的距离,如果项目不设置高度,则等于被平分的高度
4.2项目的属性
下面讲的都是以宽度为例子,设置的是flex-direction:row;
如果要谈高度的话,只需要将设置改为flex-direction:column;即可
1.order属性
设置项目的排列顺序。
order的属性值为数字,如果都不设置order属性的话默认为0,order属性值是越小代表的项目排名越靠前,可以为负数
.item{
width: 100px;
height: 100px;
order:0;
}
.box .item3{
background: green;
order:-1;
}
2.flex-grow属性
定义项目的放大比例(父盒子剩余空间)
如果都默认为0,代表为项目本身定义的宽度。
如果其他的都默认为0,有一个值大于0,则这个项目独占所有父盒子剩下的宽度
如果其他的都默认为0,有一个值小于0,则不起作用,每个项目还是本身定义的宽度
如果所有项目都为一个相同的数(该数小于0),则不起作用,每个项目还是本身定义的宽度
如果所有项目都为一个相同的数(该数大于0),则所有项目平分父盒子剩下的宽度
如果所有项目的flex-grow:1;的话代表所有项目平分父盒子剩下的宽度,若此时有一个项目的flex-grow:2;代表父盒子剩下的宽度按2:1:1:1去分。(把父盒子宽度定死会好理解一些)
总结来看,当值小于0的时候不起作用,当值大于0的时候是一个简单的比例分配问题。
.item{
width: 100px;
height: 100px;
/* order:0; */
flex-grow:1;
}
.box .item1{
background: cyan;
flex-grow:2;
}
3.flex-shrink属性
作用是指缩小该项目的比例
注意:如果当前容器的宽度足以放下所有项目,则设置该属性不起作用,该属性的应用范围适当所有项目宽度之和大于容器宽度的时候。
如果没有项目缩小,则flex-shrink的默认值为1
如果某一个项目的flex-shrink为0,则表示自己不缩放,让其他的项目缩放。
如果某一个项目的属性值大于1,则代表当前所有项目的宽度超出了容器的宽度,当前设置属性的这个项目宽度缩小后加到剩余的项目宽度上。
.item{
width: 300px;
height: 100px;
/* order:0; */
/* flex-grow:-1; */
flex-shrink: 0;
}
.box .item1{
background: cyan;
/* flex-grow:-1; */
flex-shrink: 1;
}
比如说一个容器中有四个项目,容器宽度为1000px,四个项目宽度都为300px,此时超了200px,若此时将所有项目的flex-shrink都设置为0,只有一个项目的值为1,则缩小这个项目200px然后将缩小的平分给其他三个项目
若此时所有项目的值为1,而有一个项目的值为2,则此时相当于每个人都按比例缩小一点,来满足宽度不会超出容器。
同样的,flex-shrink同样不支持负数。
4.flex-basis属性
设置项目占有空间的大小(如果项目先前设置了宽度,则会被覆盖掉)
属性值为数字+px或者百分比(按照父盒子的宽度来计算)
.item{
width: 100px;
height: 100px;
/* order:0; */
/* flex-grow:-1; */
/* flex-shrink: 1; */
flex-basis:20%;
}
5.flex属性
flex属性是flex-grow、flex-shrink、flex-basis三个属性的综合写法。默认值为0 1 auto。
还有两个快捷属性值,一个是auto(1 1 auto) 一个是none(0 0 auto)
当设置了flex-basis以后,就设定了弹性元素的(相当于width的)尺寸。width跟flex-basis的区别是,flex-basis的优先级更高。如果设置的flex-basis的值不为auto,那么width设置什么值都无效,以flex-basis的值为准。当flex-basis的值为auto的时候,弹性元素才会是width设定的值。
如果flex属性只写了一个值,代表将容器剩余空间进行分配,比如所有的项目都为1,大家的宽度都是100px,父盒子的宽度是1000px,此时单独给item2设置了flex:2;则该项目的实际宽度为400px,是1000px*2/5。
flex单位还可以设置为百分比
比如flex:20%,比如所有的项目都为1,大家的宽度都是100px,父盒子的宽度是1000px,此时单独给item2设置了flex:20%,则该项目的实际宽度是400px,是250px+750px*20%。
6.align-self属性
align-self
属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
当容器的align-items:center;的时候给某一个项目添加align-self:flex-end;就会出现下列效果。
五、rem单位
5.1、em单位
em是单位,表示的是父元素字号的倍数,比如2em指的就是当前的字号是父元素字号的2倍
<div> → font-size: 20px;
我是div元素
<p>→ font-size: 2em;实际显示字号大小是40px
我是p元素
<span>font-size: 2em;实际显示字号大小是80px
我是span元素
</span>
</p>
</div>
5.2、rem单位
rem是CSS3新增的单位,指的是html元素的font-size倍数,我们叫做根元素的倍数,也就是说所有的rem看得不是父元素font-size状态,而是html这个根元素font-size字号的状态
<style>
html{
font-size: 20px;
}
div{
font-size: 2rem;
}
p{
font-size: 2rem;
}
span{
display:block;//让span标签转块,让它独占一行。
font-size: 2rem;
}
</style>
</head>
<body>
<div>123
<p>123
<span>123</span>
</p>
</div>
</body>
现在所有元素的字号大小都是40px,即html标签字号大小的2倍。
我们就发现了一个特性,所有的元素,不区分后代,都有了统一性,有了统一性就方便管理,我们可以用rem单位来搭建弹性布局
六、高度等比例变化(rem弹性布局)
我们之前学习弹性盒子,指的盒子的宽度是弹性的,高度我们目前没有接触可以设置弹性的属性
在上图中两个盒子的宽度是弹性的,根据浏览器的宽度有比例的缩放,但是高度此时我们是设置的200px,现在我们的需求来了,我们想让高度随着宽度进行等比例缩放。
6.1插入图片来实现
**********************************************************************************
vertical-align:middle;
用来消除图片和盒子下部有3px空隙。
<div class="left"> → float:left;width:50%;
<img src="./images/star/0.jpg" alt=""> →width:100%;
</div>
<div class="right">→ float:left;width:50%;
<img src="./images/star/1.jpg" alt=""> →width:100%;
</div>
利用图片只设置宽度或者高度,另一个属性会等比例缩放的特点进行设置。
6.2使用padding属性去呈递背景
我们知道的是height属性的百分比设置是参考父盒子的height属性,如果我们需要让盒子的高度等比例缩放,此时的比例要和width相同,所以我们需要找到一个可以参考width属性的其他属性,比如我们给padding属性设置百分比,此时这个padding属性参考的就是width属性的宽度,通俗讲,padding属性的缩放比例就和width属性的缩放比例相同
我们想让一个盒子的状态是
width和height的比例是50%*40%
但是我们不能设置height:40%,因为height属性的百分比比例参考点和width是不同的,所以我们设置padding-top为百分之四十。
<div class="left"></div> → float:left;width:50%;padding-top: 40%;
<div class="right"></div> → float:left;width:50%;padding-top: 40%;
上图中的盒子会随着浏览器的宽度变化等比例缩小和放大,宽度和高度都会等比例缩放
6.3、用rem实现弹性布局
当我们给html设置了字号为20px后,将div的高度设置为10rem,即为200px,此时是固定的,当我们浏览器界面的clientWidth发生改变的时候,html的字号也随之改变的话,我们设置的height=10rem也就会随之动态变换。
因此现在要解决的问题就是让html的font-size随着clientWidth的改变而改变。
<!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>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html{
font-size: 20px;
}
div{
width: 50%;
height:10rem;
float: left;
}
.left{
background: red;
}
.right{
background: yellow;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
<script>
// 这个函数是当浏览器窗口发生变化时就会调用。
window.onresize = function(){
// 得到当前窗口的宽度
var windowWidth = document.documentElement.clientWidth;
//新的比例状态
var fz = windowWidth / (500 / 20);
document.documentElement.style.fontSize = fz + "px";
};
</script>
我们的根字号是20px,然后我们的参考依据是一个500px的页面,所以我们换算后的比例是500/20
所以当前页面发生变化的时候,字号就会根据这个比例发生变化