目录
移动端布局
(1)布局概念
1. 静态布局
直接使用px作为单位 不推荐 不会适应屏幕
2. 流式布局
宽度使用%百分比,高度使用px作为单位
通常还会加上最大值和最小值
3. 自适应布局
创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。使用 @media媒体查询来切换多个布局
4. 响应式布局
通常是糅合了流式布局+弹性布局,再搭配媒体查询技术使用
5. 弹性布局
rem或em布局。
1、rem是相对于html元素的font-size(浏览器的html的默认值是16px)大小而言的,1rem=16px;
2、em是相对于自身的font-size大小 ,1em = font-size的值,比如浏览器默认的字体大小为16px,那么这个时候1em=16px; 如果设置font-size:20px;那么1em=20px;
如果自己没有则相对自己最近的祖先font-size大小(其实也是相对于自己的font-size,因为font-size可以被继承)
如果所有的祖先都没有设置font-size属性,那么就会相对浏览器font-size的默认值大小,大部分浏览器默认都是16px
(2)基本概念
1、物理像素
-
物理像素点指的是屏幕显示的最小颗粒,是物理真实存在的,这是厂商出厂时就设置好了,比如iPhone 678是750*1334,其实也就是我们通常所说的屏幕分辨率。
也就是说在iPhone 678 一行可以放750个像素点,一列可以放1334个像素点
-
开发时1px不一定等于一个物理像素
-
PC端,1px等于一个物理像素,因为PC端屏幕宽度和分辨率一样,但移动端就不尽相同,比如iPhone8,分辨率为750,但屏宽却是375px
-
1px能显示的物理像素点的个数成为物理像素比或屏幕像素比
比如iPhone8中 375px屏宽 意味着375px占满整屏,而横向分辨率却是750 所以1px = 2物理像素
2、设备像素比(device pixel ratio)
物理像素比 = 物理像素(屏幕分辨率) / 设备独立像素(屏幕尺寸或者开发尺寸)
在Javascript中,可以通过 window.devicePixelRatio
获取到当前设备的dpr。
3、视网膜屏幕Retina
Retina为高清设备屏幕,是一种显示技术,可以将更多的物理像素点压缩到一块屏幕里,从而提高屏幕设备屏幕分辨率,并提高屏幕显示的细腻程度。
正是因为这个视网膜技术让我们手机设备尺寸与手机屏幕分辨率存在一个比例的关系,也才会存在所谓的物理像素比
这种技术的出现也会导致一定的问题,比如提供一张50*50(css像素)的图片,放到普通PC端来看是没有任何问题的,因为此时css的1px = 1物理像素,但是在手机端 iphone中 1px = 2物理像素,这样就会导致图片模糊。理解:原本图片1px = 1物理像素,但现在,我们只有1px这么宽却要显示2物理像素这么长,没有办法,只好把原像素撑大,相当于是图片放大,可以想象成我们的背景缩放,这种对盒子或者是文字来说影响并不大
一般的解决方案是提供2倍图,先准备一张宽100 高100 的图片 然后手动将图片的宽高设置为50*50,再放到手机里,会对当前图片放到50的2倍就是100,那么图片本身就是100宽高,这样的话图片就不会再模糊了。
随着屏幕分辨率的增大,提供的图片将会更大,具体根据开发公司业务和UI设计师切图决定。
(3)视口 viewport
视口就是浏览器显示页面内容的屏幕区域,视口可分为 布局视口、视觉视口、理想视口。
1、布局视口layout viewport
一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的PC端页面在手机上显示的问题 IOS,Android基本都将这个视口分辨率设置为980px,所以PC上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页调整。
总结:在PC端上,布局视口等于浏览器窗口的宽度。而在移动端上,由于要使为PC端浏览器设计的网站能够完全显示在移动端的小屏幕里,此时的布局视口会远大于移动设备的屏幕,980px远大于320px等移动设备屏幕,所以导致元素很小,如果想要看清只能缩放,但这样就会出现横线滚动条。
2、视觉视口visual viewport
字面理解是用户正在看到的网站区域,注意:是网站的区域
我们可以通过缩放去操作视觉视口,但不影响布局视口,布局视口仍保持原来的宽度
总结:视觉视口用户正在看到的网页的区域。用户可以通过缩放来查看网站的内容。如果用户缩小网站,我们看到的网站区域将变大,此时视觉视口也变大了,同理,用户放大网站,我们能看到的网站区域将缩小,此时视觉视口也变小了。不管用户如何缩放,都不会影响到布局视口的宽度。
<!-- 拓展理解: 1、首先,移动设备上的浏览器认为自己必须能让所有的网站都正常显示,即使是那些不是为移动设备设计的网站。但如果以浏览器的可视区域作为视口的话,因为移动设备的屏幕都不是很宽,所以那些为桌面浏览器设计的网站放到移动设备上显示时,必然会因为移动设备的视口太窄,而挤作一团,甚至布局什么的都会乱掉。 2、也许有人会问,现在不是有很多手机分辨率都非常大吗,比如768x1024,或者1080x1920这样,那这样的手机用来显示为桌面浏览器设计的网站是没问题的吧?css中的1px并不是代表屏幕上的1px,你分辨率越大,css中1px代表的物理像素就会越多,devicePixelRatio的值也越大,这很好理解,因为你分辨率增大了,但屏幕尺寸并没有变大多少,必须让css中的1px代表更多的物理像素,才能让1px的东西在屏幕上的大小与那些低分辨率的设备差不多,不然就会因为太小而看不清。所以在分辨率1080x1920这样的设备上,在默认情况下,也许你只要把一个div的宽度设为300多px(视devicePixelRatio的值而定),就是满屏的宽度了。 3、回到正题上来,如果把移动设备上浏览器的可视区域设为viewport的话,某些网站就会因为viewport太窄而显示错乱,所以这些浏览器就决定默认情况下把视口设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。称这个浏览器默认的视口叫做布局视口(layout viewport),这个布局视口的宽度可以通过 document.documentElement.clientWidth来获取。 4、然而,布局视口的宽度是大于浏览器可视区域(手机屏幕)的宽度的,所以我们还需要一个视口来代表 浏览器可视区域的大小,把这个视口叫做视觉视口(visual viewport)。视觉视口的宽度可以通过window.innerWidth来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。 -->
3、理想视口ideal viewport(现在用的都是这个)
在手机屏幕能显示完整的网页,并且不需要用户手动缩放调整页面大小,文字和网页元素宽高合适。
不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。也就是第三个viewport——移动设备的理想viewport,ideal viewport 可通过window.screen.width获取。
总结:布局视口的一个理想尺寸,只有当布局视口的尺寸等于设备屏幕的尺寸时,才是理想视口。
<!-- 拓展理解: 1、在桌面浏览器上,浏览器窗口与视口的宽度一致,而视口(CSS标准文档中称为“初始包含块”)是CSS百分比宽度推算的根源,因此,浏览器窗口是约束CSS布局的视口; 2、在手机上,有两个视口,布局视口会限制CSS布局;视觉视口决定用户看到的网站内容; 3、移动端浏览器还有个理想视口,它是对特定设备上的特定浏览器的布局视口的一个理想尺寸; 4、可以把布局视口尺寸定义为理想视口。这也是响应式设计的基础。 -->
4、meta视口标签
在开发移动端页面,我们需要手动设置meta视口标签通知浏览器操作以达到使用理想视口的目的:
布局视口的宽度应该与理想视口宽度一致,简单理解就是设备有多宽,布局视口就多宽
1、完整标准视口标签写法 width=device-width: 表示视口与设备宽度一致 就是理想视口- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no"> 2、简单写法 <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width"> <meta name="viewport" content="initial-scale=1.0"> 如果没有这个视口标签,写上文字打开移动设备调试器,会发现字体很小,因为移动设备浏览器布局视口默认是按照980px,那在980px像素下字体当然会很小
属性 | 解释说明 | 标准viewport设置 |
---|---|---|
initial-scale | 初始缩放比,大于0的数字 0-1视口缩小 >1视口放大 | 视口缩放比例 |
width | 宽度设置的是viewport宽度,可以设置device-width特殊值 | 视口宽度和设备保持一致 |
maximum-scale | 最大缩放比,大于0的数字 | 最大允许的缩放比例1.0 |
minimum-scale | 最小缩放比,大于0的数字 | 最小允许的缩放比例1.0 |
user-scalable | 用户是否可以缩放,yes或no(1或0) | 不允许用户自行缩放 |
拓展: <meta name="viewport" content="initial-scale=1.0">也可以把当前的的viewport变为 ideal viewport 为什么? 首先要明白initial-scale=1.0 相对于谁来缩放的呢? 我们说<meta name="viewport" initial-scale=1.0>这样就能达到理想视口的状态,当前缩放值为1也就是100%,就是理想视口的状态,所以说这个initial-scale=1.0是相对于ideal viewport来进行缩放的,可以简单理解为device-width,因为只有相当于ideal viewport来缩放100% 才能达到ideal viewport。 如果 width 和 initial-scale=1 同时出现? <meta name="viewport" content="width=400, initial-scale=1"> width=400表示把当前viewport的宽度设为400px 但是initial-scale=1是相对于device-width也就是理想视口缩放100%,也就是表示把当前viewport的宽度设为ideal viewport的宽度,那么浏览器到底该服从哪个命令呢?是书写顺序在后面的那个吗?不是。当遇到这种情况时,浏览器会取它们两个中较大的那个值。 例如,当width=400,ideal viewport的宽度为320时,取的是400;当width=400, ideal viewport的宽度为480时,取的是ideal viewport的宽度。(ps:在uc9浏览器中,当initial-scale=1时,无论width属性的值为多少,此时viewport的宽度永远都是ideal viewport的宽度) 解决方案:如果你要将视口设置为一个固定的宽度,可以直接设置content的width 将缩放比例删掉,例如京东: <meta name="viewport" content="width=1226"> <!-- 总结:要把当前的viewport宽度设为ideal viewport的宽度,既可以设置 width=device-width,也可以设置 initial-scale=1,但这两者各有一个小缺陷,就是iphone、ipad以及IE 会横竖屏不分,通通以竖屏的ideal viewport宽度为准,所以,最完美的写法应该是,两者都写上去 --> <meta name="viewport" content="width=device-width, initial-scale=1">
(4)rem单位
-
em:以父元素的font-size来计算,如父元素的font-size: 16px ; 1em = 16px
-
rem:相对于根元素html标签的font-size来做计算,如html的font-size: 16px; 1rem = 16px
rem如何实现自适应设备
实际的元素 / 设计的元素 == 实际的页面 / 设计的页面 所谓"设计"就是我们写代码期望网页呈现出来的样子,所有元素的大小和位置都和我们预想的一摸一样。通常在电脑端呈现出来的就是和设计的是一样的,但是移动端由于屏幕比电脑端小,呈现出来的样子就会不太一样,错位时有发生,所以才需要适配。
如果上面的等式恒成立,则说明适配成功。实际的元素 == 设计的元素 * ( 实际的页面 / 设计的页面),也就是是说需要知道( 实际的页面 / 设计的页面),设为k。试想,如果css中有一个属性能知道这个比例k,那么适配问题就已经完美解决了。可惜,并没有这个属性。但是,幸运的是,rem可以充当我们和这个比例之间的桥梁,rem可以看作一个单位,它可以和根元素的文字大小关联,也就是说把html的font-size设为k,比如设备屏幕尺寸是300px,设计稿宽度是600px,则html的字体大小就是320/640 = 0.5px,没错,这个值一般都很小,但是font-size的值一般虽在10px以上,然html里的font-size肯定会被下面设置的font-size所覆盖,但是出于习惯,还是会将这个k值乘上一个系数,一般是100。
这样,我们就找到了页面上不变的东西,就可以以不变应万变。至此,页面上所有元素的大小都可以用rem,或者说比例k来表示。
为什么设置动态的font-size? 实现自适应设备
100vw是屏幕设备,不是分辨率
假设屏幕宽度为:750px,那么100vw=750px,
那么100vw/750px=1,html {font-size:cala(100vw / 750)} ,所以1rem=1px
假设屏幕宽度为:375px,那么100vw=375px,100vw / 750 = 0.5
根据不同屏幕大小计算html中的font-size大小:
<script>
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
// 布局视口宽度
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
//
if (clientWidth >= 750) {
docEl.style.fontSize = '100px';
} else {
// 动态设置html的font-size
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
//上面这段代码的大意是:如果页面的宽度超过了750px,那么页面中html的font-size恒为100px,否则,页面中html的font-size的大小为: 100 * (当前页面宽度 / 750)
<script type="text/javascript">
(function (document) {
var dcl = document.documentElement, wh;
function setRootRem() {
屏幕宽度
wh = dcl.clientWidth;
dcl.style.fontSize = 20 * (wh / 750) + 'px'; // 750为设计稿宽度
// 计算出的值为: 10px = 0.5rem
}
setRootRem();
document.addEventListener('DOMContentLoaded', setRootRem, false);
window.addEventListener('resize', setRootRem, false);
})(document);
</script>
设计稿大小为750px 1px = 1rem font-size = clac(100vw / 750)
页面中计算大小的公式: 实际大小(rem) = 测量的大小(px)/ html的font-size大小(px)
视窗单位
vw(整屏宽度) : 1vw 等于视窗宽度的1%
vh(整屏高度) : 1vh 等于视窗高度的1%
vmin : 选取 vw 和 vh 中最小的那个 700 * 900 100vmin
vmax : 选取 vw 和 vh 中最大的那个 1700 * 900 100vmax
vim使用最小那边的比例。也就是说,如果浏览器窗口的高度小于他的宽时,1vmin将等价于1vh;如果浏览器的宽度小于他的高度时,1vmin等价于1vw。
vmax则相反:它使用最大的那一边。因此当viewport的宽大于高时,1vmax等价于1vw;如果浏览器的高大于宽时,1max将等价于1vh。
vim:使用视窗宽与高中的最小的那个。 vmax:使用视窗宽与高中的最大的那个。