1、移动端布局
1)手机的基本概念
(1)屏幕分辨率
iPhone5的屏幕分辨率为1136×640,指手机的竖排有1136个像素,横排有640个像素。即屏幕像素为72.7万。
并不是屏幕的分辨率越高屏幕越大,屏幕的大小由屏幕的尺寸决定,屏幕的尺寸指屏幕对角线的长度,一般单位为英寸。
(2)物理像素与CSS像素
上面提到的iPhone5的屏幕分辨率指的是物理像素。物理像素的单位为dp(点),属于设备无关像素值,设备能控制显示的最小单位,可以把这些像素看成显示器上一个个的点。
CSS像素也叫逻辑像素,是浏览器使用的抽象单位,iPhone5的CSS像素为568×320。CSS像素的单位为px,是指通常做网页时用到的CSS像素。在PC设备上1个物理像素等于1个CSS像素,但在移动端iPhone5上4个物理像素等于1个CSS像素。
屏幕分辨率是指物理像素,而实际屏幕大小对应的是CSS像素。物理像素进行压缩处理,使4个物理像素对应1个CSS像素,目的是为了显示高清的效果,这种技术叫做Retina高清视网膜屏。
(3)PPI
PPI全称是pixel per inch,即每英寸内有多少个像素点,其像素点指的是物理像素,可表示像素密度。PPI的值越高,画质越好,即越细腻。通过以下公式换算。
PPI值越高说明屏幕越清晰,一般把PPI值大于320的设备,都可以看作是Retina高清视网膜屏。
(4)DPR
DPR全称是devicePixelRatio,中文叫作“像素比”。DPR值是物理像素与CSS像素的比值,可以是横排像素比,也可以是竖排像素比。在iPhone5下无论是横排还是竖排,DPR值都为2。DPR可通过JavaScript语法window.devicePixelRatio语法来获取,DPR值对于布局是有帮助的,可以通过DPR值进行换算处理。
2)viewport
移动端布局中会涉及到一个viewport的概念。在移动端viewport有两个,visual viewport即视口viewport和layout viewport即布局viewport。
视口viewport在布局viewport上方,且视口viewport大小固定不变,而布局viewport大小可随时改变。
视口viewport的大小是固定的,这样会导致布局viewport值越大viewport窗口就缩小越多,同时显示的内容也就越多。虽然能看到整个页面,但看不清页面的细节。需要通过双指进行滑动放大处理,这样会给用户带来使用不便的体验。
通过<meta>标签可以对viewport属性进行重新设置。
<meta name="viewport" content="属性1=值1,属性2=值2">
name属性用来指定viewport方式,而content属性用来对viewport进行具体值的设置,可选设置有width、initial-scale、minimum-scale、maximum-scale和user-scalable五种选择。
(1)width
width用于设置布局viewport的特定值,可以设定一个具体的数值,如320、450等。移动端设备的尺寸差异很大,因此一般不设置固定值。width属性有device-width值,可以根据屏幕的宽自动调整,始终与屏幕的宽保持相同,从而达到适配不同设备的目的。
<meta name="viewport" content="width=device-width">
(2)initial-scale
initial-scale用于设置页面的初始缩放比例,一般不会对页面进行缩放处理,因此也就不用设置最小或最大缩放,一般取值为1或1.0。
<meta name="viewport" content="initial-scale=1.0">
(3)minimum-scale
minimum-scale用于设置最小缩放,一般不会让用户进行缩放处理,因此也就不用设置最小或最大缩放,一般取值为1或1.0。
<meta name="viewport" content="minimum-scale=1.0">
(4)maximum-scale
maximum-scale用于设置最大缩放,取值与minimum-scale相同。
(5)user-scalable
user-scalable表示用户能否进行缩放处理,可选值为yes和no。一般情况下,不需要对页面进行缩放处理,因此取值为no。
<meta name="viewport" content="user-scalable=no">
常见的viewport设置如下所示,但不代表所有的页面都采用同一个viewport设置。
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
2、弹性盒模型
为了解决传统布局的不足,CSS3增加了新型的弹性盒模型。通过弹性盒模型,可以轻松地创建自适应浏览器窗口的流动布局。
1)flex方式
CSS3通过display属性的flex值来实现弹性盒模型。对于两个未知宽高的父子元素,左右居中比较容易实现,而上下居中不太容易实现,使用flex弹性盒模型可以很容易实现两个未知宽高的父子元素,子元素在父元素中上下居中显示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main {
width: 150px;
height: 150px;
border: 1px black solid;
display: flex;
}
#box {
width: 50px;
height: 50px;
background: red;
margin: auto;
}
</style>
</head>
<body>
<div id="main">
<div id="box"></div>
</div>
<script>
</script>
</body>
</html>
2)排列与对齐
在CSS3弹性盒模型中,可以使用flex-direction属性定义弹性盒子内部子元素的排列方向,也就是盒子内部的子元素的排列方向。
属性值 | 子元素排列方向 |
---|---|
row(默认值) | 默认的排列方向为水平排列 |
row-reverse | 反向水平排列,靠右侧进行展示,注意第一项子元素在最右侧 |
column | 垂直排列 |
column-reverse | 反向垂直排列,靠下方进行排列展示,注意第一项子元素在最下方 |
反向水平排列和反向垂直排列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main1 {
width: 200px;
height: 200px;
border: 1px black solid;
display: flex;
flex-direction: row-reverse;
}
#main2 {
width: 200px;
height: 200px;
border: 1px black solid;
display: flex;
flex-direction: column-reverse;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div id="main1">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main2">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<script>
</script>
</body>
</html>
假设flex-direction属性取值为row时,水平排列,因此把水平方向看作“主轴”。主轴有对应的主轴对齐方式。主轴对齐方式通过justify-content属性进行设置。
属性值 | 主轴对齐方式 |
---|---|
flex-start(默认值) | 左对齐 |
flex-end | 右对齐 |
center | 居中对齐 |
space-between | 两端对齐,元素之间的间隔都相等 |
space-around | 每个元素两侧的间隔相等。元素之间的间隔比元素与边框的间隔大一倍 |
justify-content属性值及主轴对齐方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main1 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
#main2 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
#main3 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: center;
}
#main4 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: space-between;
}
#main5 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div id="main1">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main2">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main3">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main4">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main5">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<script>
</script>
</body>
</html>
注意,当flex-direction属性取值为column时,垂直方向变成了“主轴”,因此以上排列方向均变成垂直方向上的对齐操作。
除了主轴外,弹性盒模型还提供了侧轴的概念,侧轴表示与主轴相反的方向。align-items属性表示侧轴对齐方式。
属性值 | 侧轴对齐方式 |
---|---|
flex-start | 起始位置对齐 |
center | 居中位置对齐 |
flex-end | 结束位置对齐 |
align-items属性的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main1 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: flex-start;
}
#main2 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
#main3 {
width: 200px;
height: 100px;
border: 1px black solid;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: flex-end;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div id="main1">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main2">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<div id="main3">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<script>
</script>
</body>
</html>
3)换行与对齐
在默认情况下,元素都排在一条轴线上。当内容太多,使元素在一条轴线排不下时,则需要用到flex-wrap属性。
属性值 | 换行方式 |
---|---|
nowrap(默认值) | 元素不进行换行处理 |
wrap | 换行处理,第一行在上方 |
wrap-reverse | 反向换行处理,第一行在下方 |
flex-wrap属性的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main1 {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
#main2 {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#main3 {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div id="main1">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<div id="main2">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<div id="main3">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<script>
</script>
</body>
</html>
align-content属性表示多行之间的对齐方式。
属性值 | 多行对齐方式 |
---|---|
flex-start | 多行的起点对齐 |
flex-end | 多行的终点对齐 |
center | 多行的居中对齐 |
space-between | 多行的两端对齐,轴线之间的间隔平均分布 |
space-around | 每根轴线两侧的间隔都相等。因此轴线之间的间隔比轴线与边框的间隔大一倍 |
align-content取值为space-between和space-around时的对齐方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main1 {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: space-between;
}
#main2 {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: space-around;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div id="main1">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<div id="main2">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<script>
</script>
</body>
</html>
4)子元素属性
(1)order属性
order属性定义元素的排列顺序。数值越小,排列越靠前,默认为0。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: space-around;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
.box:nth-of-type(1) {
order: 1;
}
.box:nth-of-type(2) {
order: 2;
}
</style>
</head>
<body>
<div id="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<script>
</script>
</body>
</html>
(2)align-self属性
align-self属性允许单个元素有与其他元素不一样的对齐方式,可以设置值为flex-start、flex-end、center等。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main {
width: 200px;
height: 150px;
border: 1px black solid;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: space-around;
}
.box {
width: 50px;
height: 50px;
background: red;
color: white;
line-height: 50px;
text-align: center;
}
.box:nth-of-type(1) {
align-self: center;
}
.box:nth-of-type(2) {
height: 80px;
line-height: 80px;
}
</style>
</head>
<body>
<div id="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<script>
</script>
</body>
</html>
(3)flex属性
flex属性设置元素之间占据的空间大小,值为比例值,也可以设置固定的像素值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main {
width: 200px;
height: 50px;
border: 1px black solid;
display: flex;
}
.box {
color: white;
line-height: 50px;
text-align: center;
}
.box:nth-of-type(1) {
background: red;
flex: 1;
}
.box:nth-of-type(2) {
background: blue;
flex: 2;
}
.box:nth-of-type(3) {
background: green;
flex: 3;
}
</style>
</head>
<body>
<div id="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<script>
</script>
</body>
</html>
当设置其中一列为固定值时,可实现一列固定两列自适应的布局方案。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>弹性盒模型</title>
<style>
#main {
width: 200px;
height: 50px;
border: 1px black solid;
display: flex;
}
.box {
color: white;
line-height: 50px;
text-align: center;
}
.box:nth-of-type(1) {
background: red;
flex: 1;
}
.box:nth-of-type(2) {
background: blue;
flex: 100px;
}
.box:nth-of-type(3) {
background: green;
flex: 1;
}
</style>
</head>
<body>
<div id="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<script>
</script>
</body>
</html>
3、响应式开发
1)媒体查询
响应式开发是利用CSS3当中的媒体查询功能来实现的,即@media方式。使用@media查询,可以针对不同的媒体类型和屏幕尺寸来定义不同的样式操作。
@media 媒体类型 and 媒体条件 {}
取值 | 含义 |
---|---|
all | 用于所有设备 |
用于打印机和打印预览 | |
screen | 用于电脑屏幕、平板电脑、智能手机等 |
speech | 应用于屏幕阅读器等发声设备 |
取值 | 含义 |
---|---|
max-width | 定义输出设备中的页面最大可见区域宽度 |
min-width | 定义输出设备中的页面最小可见区域宽度 |
max-height | 定义输出设备中的页面最大可见区域高度 |
min-height | 定义输出设备中的页面最小可见区域高度 |
orientation | 定义输出设备中的页面为portrait竖屏还是landscape横屏 |
下面定义媒体查询当屏幕满足最小宽度值为500px时,执行此CSS样式;当屏幕小于500px时,则不执行此CSS样式。
<style>
@media all and (min-width:500px) {
#box {
width: 100px;
height: 100px;
background: red;
}
}
</style>
<body>
<div id="box"></div>
</body>
多条件查询,当屏幕满足最小宽度值为500px,并且同时满足最大宽度值为700px时,执行此CSS样式;当屏幕小于500px或是大于700px时,都不执行此CSS样式。
<style>
@media all and (min-width: 500px) and (max-width: 700px) {
#box {
width: 100px;
height: 100px;
background: red;
}
}
</style>
当页面在横屏时,执行此CSS样式;当页面在竖屏时,不执行此CSS样式。
<style>
@media all and (orientation: landscape) {
#box {
width: 100px;
height: 100px;
background: red;
}
}
</style>
关键词“not”是用来排除某种制定的媒体类型,即用来排除符合表达式的设备。换句话说,not关键词表示对其后的表达式执行取反操作。下面代码表示竖屏时,执行此CSS样式。
<style>
@media not all and (orientation: landscape) {
#box {
width: 100px;
height: 100px;
background: red;
}
}
</style>
除了可以直接在CSS样式中添加媒体查询外,还可以通过<link>的方式添加媒体查询的操作。
<link rel="stylesheet" href="media.css" media="all and (min-width: 500px) and (max-width: 700px)">
2)查询顺序
响应式开发遵循一定的查询原则,下面介绍两个查询的原则。
(1)通用样式写在前面,响应式样式写在后面。因为后面的样式会覆盖前面的样式,因此响应式的目的就是替换之前的样式效果。
(2)当出现多个媒体查询时,先去响应式大屏幕再去响应式小屏幕,达到一种分辨率递减的适配方式。
3)修改样式
一般情况下,响应式的常见修改样式有以下几种。
(1)display属性由block改为none,或是由none转成block,因为移动端页面和PC端页面的尺寸相差很大,可能有些元素在不同的屏幕大小下会显示或者会被隐藏。
(2)width属性从百分比转成具体像素值,或是从具体像素值转成百分比,因为移动端页面的宽度一般需要自适应屏幕的大小,而PC端页面的宽度一般为固定尺寸。
(3)text-align属性从文字端点对齐转成文字居中对齐,或是从文字居中对齐转成端点对齐,因为移动端的文字一般需要居中显示,而PC端的文字一般需要左对齐显示。
(4)float属性从浮动转成不浮动,或是从不浮动转成浮动,因为移动端的布局一般为上下结构,而PC端的布局一般为左右结构。