移动端常见适配方案

article/2025/9/18 19:39:50

基础

网上已经有非常多的基础知识总结,不再赘诉,详情可以见

《关于移动端适配,你必须要知道的》

《不要再问我移动适配的问题了》

其中容易搞混的概念是视口

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,viewport-fit=cover">
复制代码

meta标签中的viewport属性,就是视图的含义

视口分为

  • 布局视口
  • 视觉视口
  • 理想视口

布局视口

也就是<meta name="viewport" content="width=device-width">width属性的含义

我们在css中写的所有样式,就是相对于布局视口进行布局的

默认情况下,移动端的布局视口并不是屏幕宽度,而是一般在768px ~ 1024px间(大部分情况下980px)

可以通过document.documentElement.clientWidth获取 (根据widthinitial-scale来确定)

视觉视口

视觉视口是指用户通过设备屏幕看到的区域,默认等于当前浏览器的窗口大小(当initial-scale为1)

当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变觉视口的大小

可以通过window.innerWidth获取 (会随着缩放进行改变)

放大页面,此时window.innerWidth反而减小 (页面放大,你看到的东西也变少了)

理想视口

理想视口是指网站在移动设备中的理想大小,这个大小就是设备的屏幕大小

也就是<meta name="viewport" content="width=device-width">device-width的含义

可以通过screen.width获取 (常量,不会改变)

initial-scale

<meta name="viewport" content="width=device-width, initial-scale=0.5">

根据公式initial-scale = 理想视口宽度 / 视觉视口宽度

假设理想视口宽度为414px(device-width),此时设置initial-scale为0.5,那么视觉视口宽度就是414 / 0.5 = 818

如果这时你获取document.documentElement.clientWidth(布局视口)的值,会发现不是414px而是818px

结论: 布局视口宽度取的是width和视觉视口宽度的最大值

思考题:

<meta name="viewport" content="width=600, initial-scale=2">

假设理想视口宽度为414px(device-width),此时document.documentElement.clientWidth(布局视口)的值是多少?

视觉视口 = 414 / 2 = 207
布局视口 = Math.max(207, 600)
布局视口 = 600
复制代码

总结

  • document.documentElement.clientWidth: 布局视口,css中一般写成width=device-width
  • window.innerWidth: 视觉视口,页面缩放都会实时改变该值
  • screen.width: 理想视口,页面屏幕大小(设备独立像素),也就是css中的device-width

常见适配方案

简单一句话概括:移动端适配就是在进行屏幕宽度等比例缩放

平时我们开发中,拿到的移动端设计稿一般是750 * 1334 尺寸大小( iPhone6 的设备像素为标准的设计图)。那如果在750px设计稿上量出的元素宽度为100px,那么在375px宽度的屏幕下,这个元素宽度就应该等比例缩放成50px

所以适配的难点是:如果实现页面的等比例缩放?

Rem 方案

该方案的核心就是:所有需要动态布局的元素,不再使用px固定尺寸,而是采用rem相对尺寸

rem的大小是相对于根元素html的字体大小:如果htmlfont-size为100px,那么1rem就等于100px

现在我们假定:

750px 屏幕下 htmlfont-size为100px,也就是1rem为100px,那么200px宽度的.box元素,就应该写成2rem

.box {/* 750px屏幕下,200px */width: 2rem;
}
复制代码

那么现在:

375px 屏幕下,我们需要.box元素渲染成100px

.box {width: 2rem;
}
复制代码

由于.box 的宽度仍然是2rem,因此,这时候我们就需要1rem为50px,也就是说,此时htmlfont-size为50px

于是此时,我们可以得出一个公式:

(750) / (100) = (当前屏幕尺寸) / (当前屏幕1rem)

把这个公式进行一次数学转换就能得到:

(当前屏幕1rem) = 100 * (当前屏幕尺寸) / 750

翻译成js语言就是

document.documentElement.style.fontSize = 100 * (document.documentElement.clientWidth) / 750 + 'px';
复制代码

将代码优化一下

const PAGE_WIDTH = 750; // 设计稿的宽度 
const PAGE_FONT_SIZE = 100;// 设计稿1rem的大小const setView = () => {//设置html标签的fontSizedocument.documentElement.style.fontSize = PAGE_FONT_SIZE * (document.documentElement.clientWidth) / PAGE_WIDTH + 'px';
}
window.onresize = setView; // 如果窗口大小发生改变,就触发 setView 事件
setView()
复制代码

考虑到Andorid端字体渲染的问题以及页面大小变化的监听,最终的代码如下:

(function () {var timer = null;var PAGE_WIDTH = 750; // 设计稿的宽度 var PAGE_FONT_SIZE = 100;// 设计稿1rem的大小function onResize() {var e = PAGE_FONT_SIZE * document.documentElement.clientWidth / PAGE_WIDTH;document.documentElement.style.fontSize = e + 'px';// 二次计算缩放像素,解决移动端webkit字体缩放bugvar realitySize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);if (e !== realitySize) {e = e * e / realitySize;document.documentElement.style.fontSize = e + 'px';}}window.addEventListener('resize', function () {if (timer) clearTimeout(timer);timer = setTimeout(onResize, 100);});onResize();
})();
复制代码

注意的是:我们取 100px 作为设计稿的1rem,是因为方便计算,比如设计稿上量出250px,我们就可以很容易的计算出为2.5rem

我们当然也可以把 50px 作为设计稿的1rem,这时设计稿上的250px,就要写成5rem

其实我们也可以借助于postcss-pxtorem或者SCSS函数来帮我们自动转换单位

@function px2rem($px) {// 根元素字体为100px@return $px / 100 * 1rem;
}.box {width: px2rem(200);
}
复制代码

通过Rem方案,需要动态缩放的元素,我们使用rem相对单位,不需要缩放的元素,我们仍然可以使用px固定单位。

不过在大屏设备下(例如ipad或者pc端),由于我们的页面是等比例缩放,这时候页面的元素会被放大很多(屏幕宽度大,导致根元素字体1rem也变大)。但是在大屏下,我们真正希望的是用户看到更多的内容,这时候我们可以使用媒体查询的方式来限制根元素的字体,从而防止在大屏下元素过大的问题。

@media screen and (min-width: 450px) {html {font-size: 50px !important;}
}
复制代码

或者修改js脚本的逻辑

const PAGE_WIDTH = 750; // 设计稿的宽度 
let PAGE_FONT_SIZE = 100;// 设计稿1rem的大小const setView = () => {if (document.documentElement.clientWidth > 450) {// 大屏下减小根元素字体PAGE_FONT_SIZE = 50;}document.documentElement.style.fontSize = PAGE_FONT_SIZE * (document.documentElement.clientWidth) / PAGE_WIDTH + 'px';
}
复制代码

VW 方案

vw 是相对单位,1vw 表示屏幕宽度的 1%

其实我们的REM方案就是VW方案的模拟,之前我们有一个公式:

(750) / (100) = (当前屏幕尺寸) / (当前屏幕1rem)

换一个转换方式:

(当前屏幕1rem) = (当前屏幕尺寸) / 7.5

而 vw 单位其实就是:

(当前屏幕1vw) = (当前屏幕尺寸) / 100

因此,REM方案就是用 JS 把屏幕宽度分成了7.5份,而 CSS3 中新增的vw单位,原生实现了把屏幕宽度分成了100份

所以,在VW方案中,我们不再需要使用JS脚本了!

750px设计稿中,1vw等于7.5px(750 / 100),因此,在设计稿中,量出200px的宽度,就因为写成26.667vw(200 / 7.5)

.box {/* 750px屏幕下,200px */width: 26.667vw;
}
复制代码

不过使用vw换算,并不像rem那么方便,这时候我们可以借助postcss-px-to-viewport 或者SCSS函数来帮我们自动转换单位

@function px2vw($px) {@return $px / 750 * 100vw;
}.box {width: px2vw(200);
}
复制代码

同样,在大屏设备下,由于屏幕宽度大,所以页面的元素同样会放大很多(屏幕宽度大,1vw也很大)。但是由于vw是相对屏幕宽度的,所以我们不能像REM方案中一样,手动控制html的根字体大小,这也是使用VW方案的一个缺点。

REM + VW 方案

REM方案的优势是可以手动控制rem的大小,防止屏幕太大时,页面元素也缩放很大,但是缺点就是需要使用JSVW方案刚好相反,无需使用JS但是无法手动控制vw的大小。

其实我们可以把两者结合:

html {/* 750px 的设计图,1rem = 100px */font-size: calc(100 * 100vw / 750);
}.box {/* 750px屏幕下,200px */width: 2rem;
}
复制代码

对于布局元素,我们仍然使用rem单位。但是对于根元素的字体大小,我们不需要使用JS来动态计算了

100 * (document.documentElement.clientWidth) / 750
复制代码

这段js可以直接使用css来实现

calc(100 * 100vw / 750)
复制代码

对于大屏设备,我们使用媒体查询

@media screen and (min-width: 450px) {html {font-size: calc(50 * 100vw / 750);}
}
复制代码

更详细的vw+rem布局方案 可以见《基于vw等viewport视区单位配合rem响应式排版和布局》

viewport 缩放方案

还有一种更简单粗暴的方法,就是我们设置initial-scale

我们的布局完全基于设计稿750px,布局元素单位也使用px固定单位 (布局视口写死750px)

对于375px宽度,我们就将整个页面缩放0.5

<meta name="viewport" content="width=750, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=0">

<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>demo</title><script>var clientWidth = document.documentElement.clientWidth;var viewport = document.querySelector('meta[name="viewport"]');var viewportWidth = 750;var viewportScale = clientWidth / viewportWidth;viewport.setAttribute('content', 'width=' + viewportWidth + ', initial-scale=' + viewportScale + ', minimum-scale=' + viewportScale  + ', maximum-scale=' + viewportScale + ', user-scalable=0');</script>
</head>
复制代码
.box {width: 200px;
}
复制代码

此方案的缺点: 整个页面都被缩放了,对于不想缩放的元素无法控制。

市面上一些营销H5页面,由于是通过后台可视化拖拽搭建出来的,为了适配各种尺寸的屏幕,该方案是成本最低的实现(易企秀就是使用这种方案)

实战

我们拿线上B站的会员购作为示例

  • rem方案
  • vw方案
  • rem+vw方案
  • viewport方案

请使用chrome开发者工具模拟移动端设备查看

源码直接右键查看即可,代码没有经过压缩,可以很直观的看到各种方案的css适配写法

参考

  • 移动端适配有哪几种方案?
  • 不要再问我移动适配的问题了
  • 关于移动端适配,你必须要知道的
  • 基于vw等viewport视区单位配合rem响应式排版和布局

http://chatgpt.dhexx.cn/article/wPnqVsJU.shtml

相关文章

FTP服务应用(手机端与电脑端无线传输)

FTP服务应用&#xff08;手机端与电脑端无线传输&#xff09; 准备工具&#xff1a;Android手机.KSWEB软件。 1.利用Android手机.打开移动网络共享。 2.电脑连上WiFi热点。 3.Android手机安装KSWEB软件&#xff0c;并打开FTP服务器。 4.在KSWEB软件左划到FTP模块&#xff0c;将…

移动端适配方案有哪几种?

虽然我们课程明确的区分各种移动端适配方案&#xff0c;但依然有很多同学搞不清楚移动端等比适配和响应式&#xff0c;这里对移动端主流适配方案给大家做一个分析。 移动端适配是指同一个页面可以在不同的移动端设备上都有合理的布局。主流的实现方案有两种&#xff1a; 响应…

solr简介和使用

一、搜索功能的流行方案 由于搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量需要搜索引擎的功能需求,目前在实现搜索引擎的方案上有集中方案可供选择: 1、基于Lucene自己进行封装实现站内搜索。工作量及扩展性都较大,不采用。 2、调用Google、Baidu的…

solr 安装和使用

Solr是基于ApacheLucene构建的流行、快速、开源的企业搜索平台 Solr具有高度可靠性、可扩展性和容错性&#xff0c;提供分布式索引、复制和负载平衡查询、自动故障切换和恢复、集中配置等功能。Solr为许多世界上最大的互联网站点提供搜索和导航功能 环境准备 linux centos7 ja…

什么是Solr,它能为我们解决什么问题,怎么用?

一. 什么是Solr? 其实我们大多数人都使用过Solr,也许你不会相信我说的这句话,但是事实却是如此啊 ! 每当你想买自己喜欢的东东时,你可能会打开某宝或者某东,像这样一搜,就能搜到很多东西,你知道你看到的这些数据都来自哪儿吗?百度一下你就知道!这些数据来自哪儿吗?等你了解…

solr实现原理

solr那是我1年前使用到的一个搜索引擎&#xff0c;由于当初对于配置了相应了&#xff0c;但是今天突然面试问到了&#xff0c;哎&#xff0c;太久了&#xff0c;真的忘记了&#xff0c;今天特地写一篇博客记下来 solr是一个独立的企业级搜索应用服务器&#xff0c;它对外t提供…

solr的使用详解

一、Solr简介 由于搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量需要搜索引擎的功能需求&#xff0c;目前在实现搜索引擎的方案上有几种方案可供选择&#xff1a; 基于Lucene自己进行封装实现站内搜索。工作量及扩展性都较大&#xff0c;不采用。 调用Go…

solr基础理解和功能分析

一、solr概述 Solr是一个开源搜索平台&#xff0c;用于构建搜索应用程序。 它建立在Lucene(全文搜索引擎)之上。Solr是一个可扩展的&#xff0c;可部署&#xff0c;搜索/存储引擎&#xff0c;优化搜索大量以文本为中心的数据。 二、solr管理界面功能 1.Logging 展示Solr的日…

Solr基本概念

Solr是一种开放源码的、基于Lucene的搜索服务器。它易于安装和配置&#xff0c;而且附带了一个基于HTTP 的管理界面。 官网&#xff1a; http://lucene.apache.org/solr/ Solr全文检索基本原理&#xff1a; http://www.importnew.com/12707.html 相关概念&#xff1a; Core: …

Solr 原理、API 使用

日萌社 人工智能AI&#xff1a;Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战&#xff08;不定时更新&#xff09; 搜索引擎&#xff1a;Elasticsearch、Solr、Lucene ELK中的ES&#xff1a;ElasticsearchSolrCloud 的搭建、使用Solr 高亮显示Spring Data Solr …

Solr的工作原理

1. Solr的简介 ​ Solr是一个独立的企业级搜索应用服务器&#xff0c;它对外提供类似于Web-service的API接口。用户可以通过http请求&#xff0c;向搜索引擎服务器提交一定格式的XML文件&#xff0c;生成索引&#xff1b;也可以通过Http Get操作提出查找请求&#xff0c;并得到…

Solr搜索引擎原理

本文转载至&#xff1a;http://www.importnew.com/12707.html 场景&#xff1a;小时候我们都使用过新华字典&#xff0c;妈妈叫你翻开第38页&#xff0c;找到“坑爹”所在的位置&#xff0c;此时你会怎么查呢&#xff1f;毫无疑问&#xff0c;你的眼睛会从38页的第一个字开始从…

【Solr启动原理】

Solr集群启动&#xff0c;都做了哪些事情&#xff1f;做了很多事&#xff0c;over。 启动流程大致如下&#xff1a; 1. 启动入口&#xff1a;web.xml。Solr归根结底是个Web服务&#xff0c;必须部署到jetty或者tomcat容器上。 2. SolrRequestFilter过滤器的实现类是org.apache…

Solr的工作原理以及如何管理索引库

1. Solr的简介 ​ Solr是一个独立的企业级搜索应用服务器&#xff0c;它对外提供类似于Web-service的API接口。用户可以通过http请求&#xff0c;向搜索引擎服务器提交一定格式的XML文件&#xff0c;生成索引&#xff1b;也可以通过Http Get操作提出查找请求&#xff0c;并得到…

solr底层原理

一、总论 根据http://lucene.apache.org/java/docs/index.html定义&#xff1a; Lucene是一个高效的&#xff0c;基于Java的全文检索库。 所以在了解Lucene之前要费一番工夫了解一下全文检索。 那么什么叫做全文检索呢&#xff1f;这要从我们生活中的数据说起。 我们生活中…

全文搜索引擎Solr原理和实战教程

Solr简介 1.Solr是什么? Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。Solr 提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。Solr是一个高性能,采用Java开发, 基于Lucene的全文搜索服务…

solr全文检索实现原理

solr那是我1年前使用到的一个搜索引擎&#xff0c;由于当初对于配置了相应了&#xff0c;但是今天突然面试问到了&#xff0c;哎&#xff0c;太久了&#xff0c;真的忘记了&#xff0c;今天特地写一篇博客记下来 solr是一个独立的企业级搜索应用服务器&#xff0c;它对外t提供…

Solr工作原理

Solr简介 Solr是一个独立的企业级搜索应用服务器&#xff0c;它对外提供类似于Web-service的API接口。用户可以通过http请求&#xff0c;向搜索引擎服务器提交一定格式的XML文件&#xff0c;生成索引&#xff1b;也可以通过Http Get操作提出查找请求&#xff0c;并得到XML格式…

Solr的原理及使用

1.Solr的简介 Solr是一个独立的企业级搜索应用服务器&#xff0c;它对外提供类似于Web-service的API接口。用户可以通过http请求&#xff0c;向搜索引擎服务器提交一定格式的XML文件&#xff0c;生成索引&#xff1b;也可以通过Http Get操作提出查找请求&#xff0c;并得到XML格…

Solr原理剖析

一、简介 Solr是一个高性能、基于Lucene的全文检索服务器。Solr对Lucene进行了扩展&#xff0c;提供了比Lucene更为丰富的查询语言&#xff0c;并实现了强大的全文检索功能、高亮显示、动态集群&#xff0c;具有高度的可扩展性。同时从Solr 4.0版本开始&#xff0c;支持SolrCl…