(适配方案总结)客户薅公司两台ipad,我还要给做适配?

3,322 阅读7分钟

大佬们好,我是江湖不渡i,专业切图仔。🦞

🌲🌲🌲 前言
    前两天产品经理突然提出一个需求,让把之前写好的十个项目(综合门户下面好多子项目)做一下ipad适配,要给领导演示。我:???用电脑不能演示?产品经理又说:领导太忙了,ipad方便。我:笔记本不方便???产品经理说:客户要求要用ipad还要买两台。额,那我懂了🙃️薅羊毛被连带了,擦💦

    哈哈,开个玩笑。言归正传,上面那个问题因为很多项目开发的时候主要就是针对pc浏览器的,所以就没有做适配方案。除了其中一个大屏,这个大屏的后面再说。因为之前的项目是不同的同学开发的,而且时间紧任务重,所以就采用了一次性的方案。页面少、简单而且用了百分比的就用媒体查询在写一套针对的样式,页面多的就用了一个对比缩放的方案:👇

window.addEventListener('resize', () => {
  fun();
});
const heightAll = ref(document.documentElement.clientHeight);
const fun = () => {
  let devicewidth = document.documentElement.clientWidth; //获取当前分辨率下的可是区域宽度
  let scale = devicewidth / 1440; // 分母——设计稿的尺寸
  heightAll.value = document.documentElement.clientHeight / scale;
  document.body.style.zoom = scale; //放大缩小相应倍数
};
fun();

    这样做的很粗糙,但好在react和vue都能快速使用,算是解决了这个需求。但是这也只是暂时的,所以闲下来就好好整理了一下适配的方案,给各位大佬分享一下,希望对大佬们有所帮助。

为什么要做屏幕适配?

    适配适配,那我们为什么要做屏幕适配了?当然这也是一个常识性问题:一方面是因为现在的设备五花八门,屏幕大小以及分辨率都是不一样的,总结来说为了用户体验,让用户看到的页面都是正常的,所以要做适配。还有就是现在是移动互联网时代,移动端的适配也是重中之重。同样的dp,在不同手机的显示上面还是有差别(这也是经典的移动端1px问题产生的原因),所以适配还是必须要做的。

响应式和自适应

    要做适配,那我们肯定避免不了选择响应式还是自适应的方案。梳理一下响应式和自适应的概念我们再继续往下说。
    首先两种方案解决问题的方法是不一样的:
    响应式:让同一张网页自动适应不同大小的屏幕,根据屏幕宽度,自动调整网页内容大小和布局。
    自适应:在不同大小的设备上让用户看到布局相同的网页。
看了两种方案的概念,那么他们的优缺点相信各位大佬也心里有数。自适应方案用户在不同设备上面看到的页面时一样的,只不过在小的屏幕上看到的就会很拥挤。响应式方案在不同的设备上面布局和展示的内容会不一样。当然选择哪种方案我们也要根据具体的业务场景去合理选择。

适配方案汇总

    先汇总一下PC端适配的一些方案,让我们的页面在不同大小的电脑上面也能完美显示。(Tipes:ipad算什么?😂)

PC之可视化大屏

    可视化大屏通常是不允许有滚动条的出现,常用的方案就是通过缩放保证比例不发生变化,整体缩放两边留白的方案。当然我们也可以在项目开始的时候封装一个公用组件,对每一个组件进行单独缩放,这样就能避免留白导致不好看(领导不满意的情况)。
🍬🍬rem🍬🍬
🍬🍬scale🍬🍬

PC之普通适配

    其实普通的页面直接px配合弹性布局直接梭哈就行,不过页面内容比较多或者布局复杂的时候我们还是要做适当的适配,提高用户体验度。
🍬🍬动态加载css🍬🍬
🍬🍬媒体查询🍬🍬
🍬🍬百分比🍬🍬
🍬🍬rem🍬🍬
🍬🍬vw🍬🍬

移动端适配

    移动端就不用多说了,适配是重中之重。
🍬🍬rem🍬🍬
🍬🍬vw🍬🍬

适配方案分析

    上面总结了常用的一些适配方案,下面大概说一下说每个方案的使用。

动态加载css和媒体查询

    动态加载css和媒体查询有些类似,只不过动态加载css是通过js来获取屏幕宽度,进而在不同的尺寸下加载不同的css文件,来实现适配。媒体查询是通过使用@media来写对应尺寸下面的样式。     动态加载css:

if(window.screen.width >= 1680){\
    document.write('<link rel="stylesheet" href="css/index_1920.css">');\
}

    媒体查询:

@media screen and (max-width: 960px){ 
    app{ 
        background-color:#FF6699 
    } 
}

Tipes: 这两种适配方案最大的缺点就是要写很多的代码

百分比

    百分比就很字面意思了,当在不同尺寸的机型上浏览的时候,通过百分比单位,通过百分比单位可以使得浏览器中的组件的宽和高随着浏览的时候窗口的宽高变化,从而实现适配。
    百分比:

.app {
    width: 100%;
    height: 100%;
}

Tipes: 百分比这种适配方案,我们在设置宽高的时候要对应设计稿进行计算,太麻烦了。而且元素的属性对应的父级元素的属性是不固定的。比如:子元素的marginpadding 的参考对象为父元素的 width,而border-radiusbackground-sizetransform: translate()transform-origin 这些属性参考的是自身宽高。

scale

    使用css的transform: scale(),原理也就是动态计算屏幕和设计稿的比例来对页面进行整体的缩放对比。

import { computed, ref } from 'vue'

const height = 1080
const width = 1920
let scaleMode = 'widthFill'
let scale = null;
let scaleX = null;
let scaleY = null;
let transform = null;

const getScale = function () {
   let h = window.innerHeight / height;
   let w = window.innerWidth / width;
   if (h < w) {
      return { scale: h, h, w }
   } else {
      return { scale: w, h, w }
   }
}

export default function () {
   scale = ref(getScale().scale);
   scaleX = ref(getScale().w);
   scaleY = ref(getScale().h);

   transform = computed(() => {
      if (scaleMode == 'auto') {
         if (scaleX.value > scaleY.value) {
            let mvx = width * (scaleX.value - scaleY.value) / 2 / scale.value;
            return "scale(" + scale.value + ")  translateX(" + mvx + "px)"
         } else {
            let mvy = height * (scaleY.value - scaleX.value) / 2 / scale.value;
            return "scale(" + scale.value + ")  translateY(" + mvy + "px)"
         }
      } else if (scaleMode == 'widthFill') {
         return "scale(" + scaleX.value + ") "
      } else if (scaleMode == 'fill') {
         return "scale(" + scaleX.value + "," + scaleY.value + ")"
      }
   })

   window.addEventListener('resize', () => {
      scale.value = getScale().scale;
      scaleX.value = getScale().w;
      scaleY.value = getScale().h;
   })
   return transform
}

rem

     rem布局已经是老相识了,原理就是通过动态设置根节点font-size来改变1rem的大小。动态获取屏幕的宽度然后/设计稿的宽度来设置根节点的font-size,或者说将我们的设计图分为10份,先计算rem的基准值,然后把设计图上所有元素的长,宽,位置,字体大小等原来的 px 单位全部转换成 rem, 网页加载后,用 js 去计算当前浏览器的宽度,并设置 html 的 font-size 为 (当前浏览器窗口宽度 / 10),这样的话10rem就刚好等于浏览器窗口的宽度。也就可以保证100%宽度,等比例缩放设计稿的页面了。
     不过现在已经有成熟的插件帮我们实现这个转换。比如:postcss-pxtorem和amfe-flexible,具体怎么使用,大佬们自行百度。
Tipes: 但是rem布局的缺点就是我屏幕越大的手机看到的不是更多的内容,而是更大的字,这样就不是很合适了。而且要引入一定的js代码导致css样式和js代码有一定的耦合性。

vw

    vw/vh是css3新引入的单位,与视图窗口有关。vw表示相对于视图窗口的宽度,视图窗口宽度是100vw。和rem一样,具体的换算也有成熟的插件postcss-px-to-viewport,具体怎么使用,大佬们自行百度。
Tipes: 他的缺点就是无法修改 vw/vh 的值,在大屏设备(Pad)中元素会放大,且无法通过 js 干预。

🎉🎉🎉结语
    从上面也可以看出来每种方案都有优缺点,我们只使用其中的某一种是无法达到完美适配的,在工作中要结合具体的业务场景,结合不同的方法去做才是最优解。比如说,我在做移动端适配的时候就喜欢用vw+flex+px,各位大佬也可以结合自己的个人习惯去选择最适合的方案
最后祝各位大佬学习进步,事业有成!🎆🎆🎆