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

方案一:使用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. MarkDown富文本编辑器怎么加载模板文件

    我们只需要一段加载代码就可以搞定MarkDown加载模板文件. $("#md-demo").bind('click', function () { $.get("/Lib ...

  2. Python中7个不一样的代码写法

    打印index 对于一个列表,或者说一个序列我们经常需要打印它的index,一般传统的做法或者说比较low的写法: 更优雅的写法是多用enumerate 两个序列的循环 我们会经常对两个序列进行计算或 ...

  3. llinux/重启/用户切换/注销

    一.指令 shutdown命令 shutdown -h now //立即关机 shutdown -h 2 //分钟后关机 shutdown -r now //立即重启 shutdown -r 1 // ...

  4. OAuth2、OpenID Connect简介

    当我们在登录一些网站的时候,需要第三方的登录.比如,现在我们要登录简书https://www.jianshu.com/sign_in,我们使用微博登录,点击下方的一个微博的小按钮,就会出现这么一个地址 ...

  5. 使用vue在开发中的一些小问题--使用vue-cli起的服务器无法在局域网访问

    2.使用vue-cli起的服务器无法在局域网访问 这个很简单,在package.json文件中的js启动项配置中增加--host 0.0.0.0 注意是--host而不是-host,此时如果有--op ...

  6. T-SQL语句操作数据库——基本操作

    一.创建删除数据数据库 1.T-SQL语句创建数据库语法如下: CREATE DATABASE 数据库名 ON [PRINARY] ( <文件参数>[,...n] [<文件组参数&g ...

  7. Cesium专栏-气象卫星云图动图(附源码下载)

    Cesium Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精 ...

  8. Django后台应用管理名称修改

    目标修改位置: 相应需要修改代码位置 然后在APP目录下的这里添加此行  再重启Django 即可得到

  9. springboot架构下运用shiro后在configuration,通过@Value获取不到值,总是为null

    通过网上查找资料,是因为shiro的bean @Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return ...

  10. Oracle 11g DATAGUARD 同步延时监控脚本

    转自 https://blog.51cto.com/8858975/1401988监控脚本(注:这里没用Sendmail工具发送邮件,如果用的话需要修改)$cat check_oracle_dg_de ...