移动端适配,目前自己常用的两种 方案,参考以下两篇好文

方案一:使用lib-flexible包

https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html

使用flexible包方式,安装 lib-flexible 包和 px2rem-loader包

npm install --save-dev lib-flexible px2rem-loader

在需要的js文件中头部引入,如果是vue项目就引入到main.js中:

import 'lib-flexible'

webpack配置loader,注意顺序很重要,顺序不对会出错

{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{loader: 'px2rem-loader', options: {
remUni: 75,
remPrecision: 8,
}},
{loader: 'postcss-loader', options: {plugins: [require("autoprefixer")("last 100 versions")]}}
]
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader?importLoaders=1',
{loader: 'px2rem-loader', options: {
remUni: 75,
remPrecision: 8,
}},
{loader: 'postcss-loader', options: {plugins: [require("autoprefixer")("last 100 versions")]}},
'less-loader',
]
},

这里有个问题,在安卓下flexible.js源码是全部按dpr=1来适配的,那自然是不行的,我们修改一下源码,改为按devicePixelRatio显示

if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = devicePixelRatio; //这里将原来=1改为devicePixelRatio
}

然后写针对不同dpr下字体大小的视频,这里用less实现:

.font-dpr(@font-size) {
font-size: @font-size;
[data-dpr="1"] & {
font-size: @font-size;
}
[data-dpr="2"] & {
font-size: @font-size * 2;
}
// for mx3
[data-dpr="2.5"] & {
font-size: @font-size * 2;
}
//for 小米note,for 小米mix
[data-dpr="2.75"] & {
font-size: @font-size * 2.2;
}
[data-dpr="3"] & {
font-size: @font-size * 2.2;
}
// for 三星note4 ,三星s6
[data-dpr="4"] & {
font-size: @font-size * 2;
}
}

使用的时候直接.font-dpr(20) 这样婶儿就可以了。

方案二:使用less或者sass等CSS 预处理语言写适配方案

https://juejin.im/post/5caaa230e51d452b672f9703#heading-7

基准按照设计图尺寸,但是缺点是不通用,不同页面可能设计图基准尺寸不同,导致在页面自己的less文件中重置基准值也不生效,这里想到了一个兼容的办法,就是在本页面的less中将传入宽度或字体的数字进行换算。

这里贴出我的mixin.less

// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
@baseSize: 37.5; // 默认根元素大小基准值375,即设计图尺寸为宽375px,不同页面设计图尺寸不同,在页面css头部重新初始化并重新定义html根元素的font-size
@baseDesign: 375; .font-size(@px) {
font-size: (@px/@baseSize/2)*1rem;
} .margin(@px) {
margin: (@px/@baseSize/2)*1rem;
}
.margin-all(@a,@b,@c,@d) {
margin: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem;
} .padding(@px) {
padding: (@px/@baseSize/2)*1rem;
}
.padding-all(@a,@b,@c,@d) {
padding: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem;
}
.width(@px) {
width: (@px/@baseSize/2)*1rem;
}
.height(@px) {
height: (@px/@baseSize/2)*1rem;
}
.min-width(@px) {
min-width: (@px/@baseSize/2)*1rem;
}
.max-width(@px) {
max-width: (@px/@baseSize/2)*1rem;
}
.line-height(@px) {
line-height: (@px/@baseSize/2)*1rem;
}
.margin-right(@px) {
margin-right: (@px/@baseSize/2)*1rem;
} .padding-right(@px) {
padding-right: (@px/@baseSize/2)*1rem;
}
.margin-left(@px) {
margin-left: (@px/@baseSize/2)*1rem;
} .padding-left(@px) {
padding-left: (@px/@baseSize/2)*1rem;
}
.margin-top(@px) {
//margin: @px /(@baseDesign/2) * 100vw;
margin-top: (@px/@baseSize/2)*1rem;
} .padding-top(@px) {
padding-top: (@px/@baseSize/2)*1rem;
}
.margin-bottom(@px) {
margin-bottom: (@px/@baseSize/2)*1rem;
} .padding-bottom(@px) {
padding-bottom: (@px/@baseSize/2)*1rem;
}
.border(@px,@color) {
position: relative;
&::before{
content: "";
position: absolute;
left:;
top:;
width: 200%;
border:1px solid @color;
color: @color;
height: 200%;
-webkit-transform-origin: left top;
transform-origin: left top;
-webkit-transform: scale(0.5);
transform: scale(0.5);
pointer-events: none; /* 防止点击触发 */
box-sizing: border-box;
@media screen and (min-device-pixel-ratio:3),(-webkit-min-device-pixel-ratio:3){
width: 300%;
height: 300%;
-webkit-transform: scale(0.33);
transform: scale(0.33);
}
}
} .border-radius(@px) {
border-radius: (@px/@baseSize/2)*1rem;
} .border-width(@a,@b,@c,@d) {
border-width: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem;
} .top(@px){
top: (@px/@baseSize/2)*1rem;
} .left(@px){
left: (@px/@baseSize/2)*1rem;
} .right(@px){
right: (@px/@baseSize/2)*1rem;
} .bottom(@px){
bottom: (@px/@baseSize/2)*1rem;
} @imgPath: "../../assets/images/"; // 根元素大小使用 vw 单位
html {
font-size: (@baseSize/(@baseDesign / 2)) * 100vw; @media screen and (orientation: landscape) {
font-size: (@baseSize/(@baseDesign / 2)) * 100vh;
} // 同时,通过Media Queries 限制根元素最大最小值
@media screen and (max-width: 320px) {
font-size: 64px;
}
//横屏下ipad等平板font-size最大限制
/* @media screen and (min-width: 813px) {
font-size: 108px;
}*/
}

如果使用该mixin的页面设计图宽度为其他尺寸,比如320,则进行换算:

@base: 320;
@convert: 375/@base; .info{
.width(56*@convert);
.height(30*@convert);
}

这样进行转换之后可以保证页面中显示的尺寸是完全跟图片中的尺寸一致。

如果设计图页面是一个banner类型,这样相当于是页面横屏,且高度很低,建议重置mixin中的html根元素字体设置,由vh改为vw,形如:

html{
width:100vw;
height:100vh;
@media screen and (orientation: landscape) {
font-size: (@baseSize/(@baseDesign / 2)) * 100vw;
}
}

比较好用的移动端适配的两种方案及flexible和px2rem-loader在webpack下的配置的更多相关文章

  1. XFire构建服务端Service的两种方式(转)

    XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...

  2. XFire构建服务端Service的两种方式

    1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...

  3. 移动端Web适配的两种做法思路总结

    看了几篇文章,理一下网易跟淘宝移动端适配的思路,主要是参考 从网易与淘宝的font-size思考前端设计稿与工作流 像素相关概念 物理像素(physical pixel) 一个物理像素是显示器(手机屏 ...

  4. vue移动端h5页面根据屏幕适配的四种方案

    最近做了两个关于h5页面对接公众号的项目,不得不提打开微信浏览器内置地图导航的功能确实有点恶心.下次想起来了的话,进行总结分享一下如何处理.在vue移动端h5页面当中,其中适配是经常会遇到的问题,这块 ...

  5. Android为TV端助力 Service 两种启动方式的区别

    服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务.这两个方法都 可以启动Service,但是它们的使用场合有所不同.使 ...

  6. 移动端 取消0.3ms的延迟 两种方案解决

    在index.html中添加一下代码 <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fas ...

  7. Web移动端适配总结

    移动端适配的相关概念以及几种方案总结 适配相关概念 布局视口(layout viewport):html元素的上一级容器即顶级容器,用于解决页面在手机上显示的问题.大部分移动设备都将这个视口分辨率设置 ...

  8. viewport移动端适配,读文笔记

    文章地址: viewport移动端适配 笔记: 移动端适配目的: 希望在屏幕尺寸大小不同的手机上进行访问页面时,页面显示的效果能合理的展示,我们期望的是在手机屏幕较大时显示的内容比较大一些,手机屏幕小 ...

  9. web开发中移动端适配

    这个话题有些复杂,说起来有些琐碎,因为和移动端适配相关的问题太多了. 1. 概念 1.1 设备像素 设备像素被称为物理像素,它是显示设备中一个最小的物理部件.每个像素可以根据操作系统设置自己的颜色和亮 ...

随机推荐

  1. Vue-element-admin实现菜单根据用户权限动态加载

    之前有一些网友对我那个IT部门信息管理系统(http://caijt.com/it)的前端感兴趣,我已经开源到github(https://github.com/Caijt/itsys-ui) 上面有 ...

  2. SSH框架之Struts2第三篇

    1.3相关知识点 : 1.3.1 OGNL的表达式 : 1.3.1.1 什么是OGNL OGNL是Object-Graph Navigation Language的编写,它是一种功能强大的表达式语言, ...

  3. openstack 搭建

    #所有节点修改ip,主机名和hosts解析 controller 10.0.0.11 controller compute1 10.0.0.31 compute1 #所有节点准备本地repo源 rm ...

  4. JVM从入门开始深入每一个底层细节

    1 官网 1.1 寻找JDK文档过程 www.oracle.com -> 右下角Product Documentation -> 往下拉选择Java -> Java SE docum ...

  5. 关于mybtis 使用过程中发生There is no getter for property named 'id' in class 'java.lang.String' 错误

    今天在修改一个关于mybtis语句时,偶然发现的一个错误  There is no getter for property named 'id' in class 'java.lang.String' ...

  6. 一则sql优化实现接口耗时降低30倍的优化案例

    业务场景: 也测的业务,如上图,通过捕获业务的涉及的接口如下: 查询接口耗时大于7s,已经是非常的慢 经验提示: 一般接口响应时间慢的问题,最简单的方式就是监控接口相关的sql是否存在问题 开启mys ...

  7. 使用npm link 加速调试

    我们在把包发布到npm上时,如果需要对本地的包进行修改,我们需要改变一个版本,重新发布.然后测试时需要更新这个包进行测试.这样的话,每一次的调试都特别麻烦.我们可以使用npm link来加速这个调试过 ...

  8. Jenkins自动化部署入门详细教程

    大纲 1.背景 在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试: 或者前后端分离后,经常会修改接口,然后重新部署 ...

  9. Linux开发环境搭建三 使用mount -t cifs 挂载windows共享目录方法与问题解决

    转载链接:https://blog.csdn.net/fuyuande/article/details/82915800 嵌入式开发通常是在linux环境下编译,windows下开发,这就需要在lin ...

  10. sched_yield()和nanosleep()对进程调度的影响

    关键词:sched_yield().nanosleep()等等. sched_yield()主动放弃CPU执行权,nanosleep()是睡眠一段时间后再唤醒. 1. sched_yield()实现 ...