web移动端屏幕适配方案

因为手机屏幕的分辨率大小不一 ,如果使用传统的静态布局,把每个元素的宽高样式写死,在不同的屏幕中就有各种各样的显示效果。这显然不是我们想要的结果。我们需要的是根据屏幕分辨率的不同,来适配不同的样式大小。使不同的手机分辨率下都有相同的样式布局

1.rem适配

1rem就是html标签font-size的大小,在rem适配方案中,我们以rem作为基值来设定元素的大小。1rem单位越大,元素的大小也就越大,1rem单位越小,元素的大小也就越小(1em是当前元素的文字大小)

实现方法:通过js获取屏幕的分辨率来动态设置1rem的大小,即屏幕分辨率越大 => 1rem越大 => 元素也越大,这样来适配不同分辨率的屏幕

缺点:需要手动转换rem和px

注意:需要设置完美视口。另外1rem的值虽然可以自定义,但是谷歌浏览器有最小字体为12px,所以设置rem的时候要保证最小屏幕下的1rem不能小于12px

<!-- 设置完美视口 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

方法一:设置html元素的内联样式

<script>
    var html = document.querySelector('html')
    // 照这种设置 375分辨率 (苹果6)的1rem = 20px
    html.style.fontSize = document.documentElement.clientWidth/18.75 + 'px'
</script>

方法二:添加style标签,为html标签设定样式,这种方法可以将样式权重提升为最高

<script>
    var head = document.querySelector('head')
    // 在iphone6中 1rem=20px 移动端浏览器字体最小12px
    var w = document.documentElement.clientWidth/18.75
    // 创建style标签
    var styleNode = document.createElement('style')
    // 在style标签中写入内容
    styleNode.innerHTML = "html{font-size:"+ w +"px !important}"
    // 将style节点插入到head中
    head.appendChild(styleNode)
</script>

方法三:使用css的calc()动态设置html的字体大小

html{
    font-size:calc(100vw / 18.75);
}

2.viewport适配

rem适配是通过动态修改页面大小来匹配不同的屏幕宽度,而viewport适配则相反,他通过修改视口宽度来自适应要给固定大小的页面。
如果视口宽度大于页面设计的宽度,则会有多余的空间剩余,如果视口宽度小于页面设计的宽度,则默认无法装下这个页面,会出现左右方向滚动条,需要用户滑动左右滚动条才能查看两侧的内容,当然用户可以手动对页面进行缩放,缩小到与屏幕宽度一致即可,问题是用户每次都要手动操作显然不现实,而viewport适配其实就是自动帮你做这件事的,他通过initial-scale对视口进行缩放,将视口调整到页面的宽度,这样一来屏幕不会有剩余空间,也不会出现左右滚动条。

优点:只需按设计图1:1的大小来设定元素的大小即可,无需考虑数值转换

要求:设计图大小与设备屏幕宽度不能相差太大,不然过度缩放会导致失真。

在meta标签中,scale=1.0就相当于设定width=设备独立像素的大小
以设计图为640px为例,假设我们的手机屏幕宽度是375px,在scale=1时就会出现这种效果:

此时我们手动对页面进行缩放,不用左右滚动也能查看整个页面。但是这种事我们要交给程序来处理,让他们帮我们进行缩放。
通过破坏完美视口,修改scale的值来适配不同屏幕,将视口宽度缩放到页面大小,这样就不会再出现滚动条(375/640=0.5859375)

<meta name="viewport" content="initial-scale=0.5859375" />

实际开发中,手机的屏幕大小有很多种,并不是固定的。页面也是一样,并不是固定的640,所以需要 用js来动态设置scale的值

<script>
    // 设置设计图的尺寸640 / 750 都行
    var targetW = 640
    // 设定缩放比例
    var scale = window.screen.width / targetW
    // 创建meta标签
    var meta = document.createElement('meta')
    // 为meta标签设定属性值
    meta.name = "viewport"
    meta.content = "initial-scale="+scale+", minimum-scale="+scale+", maximum-scale="+scale+",user-scalable=no"
    // 将meta标签插入到head标签中
    document.head.appendChild(meta)
</script>

3.vw和vh

vw和vh是相对于视口的宽度/高度,即:
100vw = 视口的宽度
100vh = 视口的高度

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"> 
<style>
    #box{
        width: 50vw;
        height: 50vh;
        background-color: red;
    }
</style>
<body>
    <div id="box"></div>
</body>

效果:

不同的设备对vh和vw的解析可能不一致,因为浏览器还包括状态栏,所以vh和vw不能完全对应设备的屏幕大小,而且每个浏览器的状态栏地址栏的大小不一致,解析下来有可能执行结果不一致

* {
	padding: 0;
	margin: 0;
}

html,body {
	width: 100%;
	height: 100%;
}
<body>
    <div style="height:100vh;">
        <p></p>
        <p></p>
    </div>
</body>
<script>
    window.onload = function(){
        var div = document.querySelector('div')
        var p = document.querySelectorAll('p')
        p[0].innerHTML = 'body的高度 = '   + document.body.clientHeight
        p[1].innerHTML = '100vh的高度 = '   + div.clientHeight
    }
</script>

iphone6s plus中(375*735),chrome执行效果为(div高度大于body,所以会出现滚动条)

body的高度 = 622
100vh的高度 = 696

火狐浏览器执行效果

body的高度 = 614
100vh的高度 = 614

Edge执行效果

body的高度 = 622
100vh的高度 = 622
posted @ 2019-10-02 23:27  ---空白---  阅读(1703)  评论(0编辑  收藏  举报