移动端适配

博客围绕移动端适配问题展开,先介绍物理像素、设备独立像素、CSS像素、设备像素比和rem等基本概念,接着阐述淘宝lib - flexible库的flexible实现方案及1px物理像素的解决办法,最后介绍视口单位适配方案,还提及相关PostCss插件。

前言:这周工作碰到了移动端1px的问题。以前一直写样式也没有特别注意着一点。还有就是rem的原理。这些其实就是比较常见的移动端适配问题。现阶段比较主流的适配方案有二种。一种是flexible + rem,另一种是vw

下面我们来看一下具体情况

1、基本概念

在了解具体方案原理前,我们先来看一下一些基本概念:

1.1、物理像素(physical pixel)

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。

1.2、设备独立像素(density-independent pixel)

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。(老早在没有 retina 屏之前,设备独立像素与物理像素是相等的)

1.3、CSS像素

CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs。

1.4、设备像素比(device pixel ratio)

设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

设备像素比 = 物理像素 / 设备独立像素

JavaScript中,可以通过window.devicePixelRatio获取到当前设备的dpr。而在CSS中,可以通过-webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)
因此在iphone 6、7、8 的 dpr 为 2的设备中,一个设备独立像素便为 4 个物理像素,因此在 css 上设置的 1px 在其屏幕上占据的是 2个物理像素,0.5px 对应的才是其所能展示的最小单位。

1.5、rem

简单的理解,rem就是相对于根元素<html>font-size来做计算。而我们的方案中使用rem单位,是能轻易的根据<html>ont-size计算出元素的盒模型大小。而这个特色对我们来说是特别的有益处。

2、flexible实现方案

了解了前面一些相关概念之后,接下来我们来看实际解决方案。淘宝有一个名叫lib-flexible的库,而这个库就是用来解决H5页面终端适配的。
我们把屏幕分成10等分,那么

  • 物理像素为 750 = 375 * 2,那么 10rem = 750px,1rem = 75px;
  • 物理像素为 1125 = 375 * 3,那么 10rem = 1125px,1rem = 112.5px ;
  • 物理像素为 1242 = 414 * 3, 那么 10rem = 1242px,1rem = 124.2px;
function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 540) {
            width = 540 * dpr;
        }
        var rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

2.1、1px的物理像素的解决方案

由此我们得到一个1px像素的解决方案。viewport 的 initial-scale 具有缩放页面的效果。对于 dpr=2 的屏幕,1px压缩一半便可与1px的设备像素比匹配,这就可以通过将缩放比 initial-scale 设置为 0.5=1/2 而实现。以此类推 dpr=3的屏幕可以将 initial-scale设置为 0.33=1/3 来实现。

<meta name="viewport" content="width=device-width, initial-scale=0.5, maximum-scale=0.5">
if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

3、视口单位适配方案

将视口宽度 window.innerWidth 和视口高度 window.innerHeight 等分为 100 份,且将这里的视口理解成 idealviewport 更为贴切,并不会随着 viewport 的不同设置而改变。

1、vw : 1vw 为视口宽度的 1%
2、vh : 1vh 为视口高度的 1%
3、vmin : vw 和 vh 中的较小值
4、vmax : 选取 vw 和 vh 中的较大值

如果设计稿为 750px,那么 1vw = 7.5px,100vw = 750px。其实设计稿按照设么都没多大关系,最终转化过来的都是相对单位,上面讲的 rem 也是对它的模拟。

跟之前一样的痛点,我们仍然需要花费大量不必要的计算时间去把标注图中的px转换为vw,有没有类似于postcss-px2rem的工具呢?很荣幸能再次站在巨人的肩膀上,已经有大神写了了类似的PostCss插件 postcss-px-to-viewport

参看资料
https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html

<think> 首先,用户的问题是:“我想了解移动端适配的原理 请问移动端适配的原理”。系统指令要求我使用中文回答,结构清晰,逐步解决问题,并保证回答真实可靠。 我需要参考提供的引用内容。这些引用是关于移动端适配原理的: - [^1] 讨论了移动端适配的原因和一些概念。 - [^2] 解释了rem布局原理,涉及rem单位基于html的font-size- [^3] 强调适配的目的是让设计稿在不同设备上表现一致。 - [^4] 提到物理像素、逻辑像素,以及网易和淘宝的方案。 - [^5] 讨论了使用media query或data-dpr来处理字号大小。 用户的问题焦点是“移动端适配的原理”,所以我需要整理这些原理的核心点。 关键原理点: 1. **适配的必要性**:不同设备有不同屏幕尺寸、分辨率和像素密度(DPI),需要确保网页在各种设备上显示一致。 2. **viewport设置**:在HTML的meta标签中设置viewport来控制页面的缩放和尺寸,如:`<meta name="viewport" content="width=device-width, initial-scale=1.0">`。这使得页面宽度等于设备宽度。 3. **单位系统**:使用相对单位来实现适配- **rem单位**:rem基于根元素(html)的font-size。开发者设置html的font-size为设备宽度的某个比例,然后所有尺寸用rem表示。这样当设备宽度变化时,元素尺寸自动缩放。 - 例如,设计稿宽度750px,设置html font-size为750/10 = 75px(假设10rem为设计稿宽度)。那么一个100px宽的元素在CSS中写为100/75 ≈ 1.333rem。 - **vw/vh单位**:视口宽度/高度单位。1vw = 1%视口宽度。可以直接使用vw来定义尺寸,避免依赖rem。 4. **像素密度处理**:物理像素和逻辑像素(CSS像素)的区别。高DPI设备有更多物理像素,但CSS像素基于逻辑像素。有时需要处理不同DPI,如使用data-dpr属性来调整文本大小。 5. **常见方案**: - **网易方案**:基于rem,动态计算html的font-size- **淘宝方案(Flexible)**:类似,但更完整,处理了高清屏和dpr。 6. **实现方式**: - 使用JavaScript在页面加载时动态设置html的font-size,基于设备宽度。 - 或者使用CSS媒体查询(media queries)来根据不同宽度设置样式。 回答结构应该清晰: 1. **介绍适配的必要性**:解释为什么需要移动端适配。 2. **核心原理**:详细说明viewport、相对单位(尤其是rem)、和动态计算。 3. **常见实现方案**:简述网易和淘宝的方法。 4. **总结原理**:强调基于相对单位和动态计算。 系统指令还要求生成相关问题,所以我需要在回答末尾添加相关问题。 此外,回答中引用的段落末尾自然地添加引用标识,如[^1]、[^2]等。所以我需要正确引用这些来源。 最后,系统指令要求使用$...$和$$...$$格式处理数学表达式,但这里可能没有复杂的数学,主要是单位解释。 现在,构建回答: - 开头:重申问题,说明适配原理。 - 主体:分步骤解释原理。 - 结尾:总结,并添加相关问题。 生成相关问题: 1. rem单位和em单位有什么区别? 2. 如何实现动态rem适配? 3. 移动端适配中如何处理高清屏(Retina屏幕)? 4. viewport设置的具体作用是什么? 确保回答真实可靠:基于提供的引用内容。 </think> ### 移动端适配的原理 移动端适配的核心原理是确保网页在不同设备(如手机、平板)上具有一致的视觉表现和用户体验。由于不同设备的屏幕尺寸、分辨率和像素密度(DPI)差异巨大,适配的目标是将设计稿(通常是固定宽度,如750px)灵活地映射到各种屏幕上。这主要通过相对单位、动态计算和视口控制实现。下面我将逐步解释关键原理,以确保回答清晰可靠。 #### 1. **适配的必要性:设备多样性与像素密度** - 不同设备(如iPhone 12与Android手机)的物理像素(硬件像素点)和逻辑像素(CSS像素)不一致。例如,一个750px的设计稿在高DPI设备(如Retina屏幕)上可能被渲染为更多物理像素,导致元素过小或过大。 - **物理像素与逻辑像素**:物理像素是设备的实际像素点,逻辑像素是CSS使用的像素单位。高DPI设备(dpr > 1)会将一个逻辑像素映射到多个物理像素上。适配的目的是让设计稿在任何设备上都保持比例一致[^3][^4]。 - 适配确保文本、图像和布局都能自适应缩放,避免出现滚动或溢出问题。 #### 2. **核心原理:相对单位与动态计算** 移动端适配的核心是使用相对单位而非固定单位(如px),并通过动态计算实现缩放。主要方法包括: - **viewport设置**:在HTML的`<head>`中添加meta标签控制视口: ```html <meta name="viewport" content="width=device-width, initial-scale=1.0"> ``` - `width=device-width`:强制页面宽度等于设备逻辑宽度(如iPhone的逻辑宽度为375px)。 - `initial-scale=1.0`:禁止用户缩放,确保初始缩放比例为1:1。这解决了设备宽度不一致的问题[^4][^3]。 - **rem单位布局原理**: - rem(root em)基于根元素(html)的font-size。所有尺寸(如width、height)使用rem单位,这样当html的font-size变化时,元素尺寸自动缩放。 - **动态计算font-size**:通过JavaScript在页面加载时设置html的font-size为设备宽度的比例。例如: - 设计稿宽度750px,设置html font-size = 设备宽度 / (750 / 基准值)。基准值常设为10(便于计算)。 - 公式:$$ \text{html font-size} = \frac{\text{deviceWidth}}{\text{设计稿宽度} \times \text{基准值比例}} \times \text{基准值} $$ - 假设设备宽度375px(标准iPhone),设计稿750px,设定1rem = 100px(基准值),则html font-size = 375 / 7.5 = 50px。元素在设计稿中100px宽时,CSS写为$1rem$(因为100px / 100 = 1rem)。在375px设备上,实际渲染为50px * 1rem = 50px,保持比例一致[^2][^4]。 - 示例:设计稿元素高度100px,在750px设备下,1rem = 750/10 = 75px,元素高度为$100 / 75 \approx 1.333rem$。在375px设备下,1rem = 375/10 = 37.5px,元素高度为$1.333 \times 37.5 \approx 50px$,比例不变[^2]。 - **vw/vh单位**:视口宽高单位(1vw = 1%视口宽度),可直接用于CSS。例如,设计稿元素100px宽,视口宽度750px时,元素设为$100 / 750 \times 100vw \approx 13.333vw$。这避免了JavaScript动态计算,但兼容性略差于rem[^2]。 #### 3. **处理像素密度和文本大小** - 高DPI设备(dpr > 1)需要额外处理文本和图像清晰度: - **data-dpr属性**:如淘宝方案,在html标签添加data-dpr属性(如`<html data-dpr="2">`),然后通过CSS媒体查询调整文本大小: ```css .text { font-size: 12px; } [data-dpr="2"] .text { font-size: 24px; } /* dpr=2时放大文本 */ ``` 这确保文本在高清屏上不模糊[^5]。 - **图像适配**:使用SVG图标或`srcset`属性为不同dpr提供多倍图,优化显示效果。 #### 4. **常见实现方案** - **网易方案**:基于rem,通过JavaScript计算html font-size计算公式:$$ \text{font-size} = \frac{\text{deviceWidth}}{7.5} $$(适合750px设计稿)。优点是简单高效[^4]。 - **淘宝方案(Flexible)**:结合rem和viewport缩放,动态设置dpr和font-size。处理高DPI更全面,适合复杂场景。例如,设置viewport的scale=1/dpr,避免缩放失真[^4][^5]。 - **媒体查询(Media Queries)**:CSS方案,根据不同屏幕宽度设置font-size。例如: ```css @media (min-width: 375px) { html { font-size: 37.5px; } } /* iPhone适配 */ ``` 但不如JavaScript灵活,适合简单页面[^5]。 #### 总结 移动端适配的原理本质是通过相对单位(rem/vw)和动态计算(JavaScript或CSS),将设计稿的固定尺寸映射到不同设备逻辑宽度上,同时处理像素密度以实现一致性。viewport控制基础缩放,rem/vw实现弹性布局,data-dpr优化高清显示。这是一种成本低、效果好的方案,确保用户体验统一[^1][^3][^4]。 相关问题: 1. rem单位和em单位在移动端适配中有什么区别? 2. 如何用JavaScript实现动态rem适配? 3. 移动端适配中如何处理Retina屏幕的高清显示问题? 4. viewport的initial-scale属性具体如何影响页面缩放?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值