一、背景
目前我们的运营活动,都是基于宽度的等比适配,通过一些 px2rem 之类的手段,做到从设计稿量多少就是多少,如果页面允许纵向滚动,那么这是一个相对完美的方案~ 但是,常常出现这样的需求,设计按照长屏出稿,并且要求在各种长短不一的屏幕上不允许滚动的情况下完整展示内容,这个时候如果没有一些适配手段,就出问题了,所以给大家分析一下这种需求情况下可以用哪些适配方法解决。
二、裁剪法
1、上下裁剪
原理:
将背景图片预留足够长,在不同高度的视口中进行上下裁剪
关键点:
需要UI设计要把主要内容放到中间的安全区域
优缺点:
- 优点:对于开发来说方便简单
- 缺点:需要UI设计配合,内容区域要在短屏可完全展现,带来的问题就是长屏可能出现上下留白,影响美观的情况。
2、左右裁剪
原理:
将背景宽度预留足够长(UI设计师配合),高度等于视口100%,这样实现背景的自适应裁剪
关键点:
因为背景图片使用的是高度等比而不是宽度等比,所以内容区域的布局不能再直接使用 px 转 rem ,而要基于与背景图片大小相同的盒子为父级,使用百分比进行布局。方法步骤如下:
- 将内容区域的父亲设置为与背景大小相同的盒子
- 内容区域宽高使用百分百(基于背景图盒子)
- 内容区域定位用 position
- top 和 left 也用百分百 (基于背景图盒子)
这样一波操作下来,内容区域的大小会随着背景图的缩放比例而缩放,同时基于一定的留白可以实现自适应适配
优缺点:
- 优点:也比较方便,一劳永逸
- 缺点:需要UI设计师配合,同时短屏手机可能出现内容被挤压在中间(背景图裁剪少),长屏可能出现左右无留白(背景图裁剪多)
代码实现:
1、背景图片的宽度自适应扩大:
和 UI 设计师协商将背景图片宽度放大,然后通过和 background-position 和 background-size 等属性将背景图片盒子居于视口正中间
.root { /*项目视口根节点*/
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
}
.backgroundBox { /*背景图片盒子*/
display: block;
width: 100%;
height: 100vh;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%); /*背景绝对定位居中*/
background-position: center;
background-repeat: no-repeat;
background-size: auto 100%; /*高度等于容器高度,宽度自适应,故设计稿要将宽度变宽*/
background-image: url('../src/assets/background.jpg');
}
这样有个问题就是背景盒子的宽度还是等于视口的宽度,而不是背景图片的宽度,所以要动态计算出背景图片盒子的宽度:
2、计算出背景图片盒子的宽度
JS实现:
//计算按高度适配对应的宽度
export function getAdapterSize() {
const clientHight = document.documentElement.clientHeight;
const clientWidth = document.documentElement.clientWidth;
let width = clientWidth;
let height = clientHight;
width = 878 * clientHight / 1396; //按照背景图宽高比,计算出不同高度情况下容器的宽度
return {
width: width + 'px',
height: height + 'px'
}
}
CSS实现:
.backgroundBox {
width: 62.9vh; /* 即为 878/1396*100vh 根据背景图片的宽高比例动态计算 */
}
3、内容区域部分
然后再在该容器里面设置内容,内容用相对定位,然后top,left等的值用百分百
.content {
position: absolute;
width: 76%;
height: 80%;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
二、内容间隙伸缩法
原理:
内容区域之间的间隙采用JS、CSS或者媒体查询的方式实现自由伸缩
代码实现:
1、JS实现
export function px2rem(px) {
if (!px) return 0
return px / 72 + 'rem'
}
const normScale = 1396/720;
export function adapterSize( value, distance = 30,minValue ){ //value间距值,distance变化幅度,minValue设置最小值
const clientHight = document.documentElement.clientHeight;
const clientWidth = document.documentElement.clientWidth;
const currentScale = clientHight/clientWidth;
let targetValue = value + (currentScale - normScale) * 10 * distance
if(targetValue < minValue){
targetValue = minValue
}
return px2rem(targetValue)
}
关键点:
根据屏幕比例计算出间隙需要增缩的距离,并且距离变化幅度(distance)可以动态设定,同时可以设置间距的最小值(minValue)
优缺点:
- 优点:动态变化,页面十分美观,代码十分优雅
- 缺点:需要手动调用JS计算
2、CSS实现
<div></div>
<div></div>
<div></div>
div{
width:100%;
height:100px;
margin-bottom:10vh /*间距百分百缩放*/
}
关键点:
内容盒子大小不变,外边距或内边距使用百分比 vh 实现自适应变化
优缺点:
- 优点:简单易懂
- 缺点:可控性很低
3、媒体查询
媒体查询用法:
@media mediatype and|not|only (media feature) {
CSS-Code;
}
@media screen and (max-width: 300px) {
body {
background-color:lightblue;
}
}
媒体类型
| 值 | 描述 |
|---|---|
| screen | 用于电脑屏幕,平板电脑,智能手机等。 |
| all | 用于所有设备 |
媒体功能
| 值 | 描述 |
|---|---|
| max-width | 定义输出设备中的页面最大可见区域宽度。 |
| min-height | 定义输出设备中的页面最小可见区域高度。 |
| max-aspect-ratio | 定义输出设备中的页面可见区域宽度与高度的最大比率。 |
| min-aspect-ratio | 定义输出设备中的页面可见区域宽度与高度的最小比率。 |
| ....... | ....... |
@media all and (max-aspect-ratio: 375/710) {
//对于适配比例
}
@media all and (max-aspect-ratio: 375/680) {
//对于适配比例
}
@media all and (max-aspect-ratio: 375/580) {
//对于适配比例
}
关键点:
对屏幕的各个边界情况,设置对应不同的适配方案
优缺点:
- 优点:灵活性强,能够快捷解决多设备显示适用问题
- 缺点:不是连续的,在某一屏幕比例区间的适配样式是没有变化的。效率较低,兼容各设备工作量大。