CSS:像素问题总结

物理像素与逻辑像素

物理像素(Physical Pixel)

物理像素(Physical Pixel):屏幕上真实存在的、最小发光单元

它是硬件层面的。比如一块屏幕:1179 × 25561080 × 2400。这些数字说的都是 物理像素数量

固定不变(硬件决定),数量越多 → 越清晰,由屏幕制造商决定

物理尺寸(Physical Size)

定义:屏幕在现实世界中的实际大小(单位是英寸 / 毫米)

例如:6.1 英寸和6.7 英寸

  • 1英寸=2.54里面=25.4毫米

这是你用尺子量出来的大小

PPI

真正把两者连接起来的是:PPI = 每英寸像素数

公式是:PPI = 物理像素数量 ÷ 屏幕物理尺寸(英寸)

或者反过来:物理尺寸 = 物理像素 ÷ PPI

假设 1 英寸长度。

  • 低 PPI 屏幕(200 PPI):每个像素比较大。

    |■■■■■■■■■■|
     200 个像素
    
  • 高 PPI 屏幕(400 PPI):每个像素更小、更密。

    |■■■■■■■■■■■■■■■■■■|
     400 个像素
    

PPI 才决定清晰程度

分辨率

分辨率是:屏幕一共有多少个物理像素

比如:1179 × 25561080 × 24001920 × 1080

它描述的是:横向像素 × 纵向像素

单位是:像素(px)

例子

手机 分辨率 屏幕尺寸
A 1080px 宽 6.1 英寸
B 1080px 宽 5.4 英寸

假设两个手机,物理像素一样,物理尺寸不同

那结果是:B 的 PPI 更高,B 更清晰,像素更密

逻辑像素(Logical Pixel)

逻辑像素(Logical Pixel):操作系统提供给开发者的“虚拟坐标单位”。

它不是物理存在的点。它是:一个 UI 抽象单位。

逻辑像素是操作系统厂商定的。

  • 🍎 iOS → Apple 决定
  • 🤖 Android → Google 定规范,手机厂商按规范实现
  • 🌐 浏览器 → 浏览器厂商根据系统缩放决定

在不同平台叫什么?

它们本质是同一种东西,只是名字不同。

平台 逻辑像素名称
Web/CSS px
iOS pt
Android dp
Flutter logical pixel
React Native dp
微信小程序 rpx

为什么需要它?

假设两台手机:

设备 物理分辨率 屏幕尺寸
A 750 × 1334 4.7 英寸
B 1170 × 2532 6.1 英寸

如果你写:按钮宽 300 像素。

会发生什么?

  • 在低分辨率手机上 → 按钮很大
  • 在高分辨率手机上 → 按钮很小

这会导致:UI 失控,字体难看,交互体验混乱

所以操作系统做了一件事:把真实屏幕抽象成一个统一的“逻辑坐标系”。这个坐标系单位,就是逻辑像素。

确实存在两个“px”

分辨率里的 px

1179px × 2556px:这里的 px 指的是: 物理像素(硬件像素)。这是屏幕真实的发光点数量。

CSS / 开发里的 px

width: 100px;
  • 这里的 px 指的是:逻辑像素(CSS Pixel),它不是物理像素。

为什么名字一样?

历史原因。

早期电脑显示器:

  • 1 CSS px ≈ 1 物理像素
  • 没有高分屏
  • DPR = 1

所以当年:px = pixel = 物理像素

后来 Retina / 高分屏出现后:1 CSS px ≠ 1 物理像素,但名字没改

于是产生了今天的混淆。

混淆主要发生在 Web,因为 CSS px 继承了“pixel”这个历史名称,但含义已经升级为逻辑像素

uni-app 的 CSS 里的 px

uni-app 的 CSS 里使用的 px 是逻辑像素(CSS 像素),不是物理像素

因为 uni-app 本质是:

  • H5 → 浏览器渲染
  • 小程序 → WebView / JSCore 渲染
  • App → 也是 WebView(nvue 另说)

而在 Web 渲染体系里:物理像素 = 逻辑像素 × DPR

CSS 里的 px 永远指的是 逻辑像素(CSS Pixel)

两者之间的桥梁:DPR

核心公式(这是最重要的一条):物理像素 = 逻辑像素 × DPR

  • DPR = Device Pixel Ratio
  • 意思是:1 个逻辑像素等于多少个物理像素。

iPhone 15 Pro

  • 物理宽:1179px
  • 逻辑宽:393pt
  • DPR ≈ 3

操作系统的意思是:开发者世界宽度是 393,我帮你放大 3 倍映射到真实屏幕

所以:100 逻辑像素 → 300 物理像素

DPR 会因设备不同而不同

设备 物理分辨率 逻辑分辨率 DPR
早期普通手机 640px 宽 320px 宽 2
高清屏手机 1170px 宽 390px 宽 3
低端安卓 720px 宽 360px 宽 2
高端安卓 1440px 宽 360px 宽 4

厂商的决定

手机厂商是如何决定“逻辑像素是多少”的?也就是:为什么有的手机是 375,有的是 390,有的是 411?

决策顺序

厂商不是先算 DPR。而是按下面顺序决策:

① 物理屏幕尺寸(英寸)
② 物理分辨率(清晰度目标)
③ 视觉舒适区间(UI物理大小)
④ 生态兼容性
⑤ 性能与功耗
→ 最终反推出逻辑像素

逻辑像素是一个“工程平衡结果”。

真正的目标不是像素

厂商真正关心的是:UI 的“物理尺寸”是否舒适。

比如:

  • 按钮物理高度大约 7~9mm
  • 字体物理高度大约 3~4mm

用户拿在手里的真实尺寸要稳定。

不是像素数量。

核心变量:屏幕尺寸(英寸)

假设两台手机:

屏幕尺寸 物理分辨率
6.1 英寸 1179 × 2556
6.1 英寸 1080 × 2400

虽然分辨率不同,但用户拿在手里的物理尺寸是一样的。所以:UI 的物理尺寸也必须接近

如何保证“物理尺寸稳定”?

回到那条核心公式:物理像素 = 逻辑像素 × DPR

物理像素已经由屏幕决定。

厂商需要决定:逻辑宽度DPR

iOS 的决策逻辑(高度控制)

苹果做法很稳定:

第一步:确定视觉宽度区间

  • 主流 iPhone 逻辑宽:375 / 390 / 414 / 430 pt
  • 为什么在这个区间?因为这是人体工程学实验的结果。
    • 单手可读宽度
    • 字体排版舒适
    • 手指点击范围合理

第二步:让 DPR 接近整数

  • 例如:物理宽 1179,如果选逻辑宽 393,1179 ÷ 393 ≈ 3,完美整数。那就选 393。
  • 常见的DPR有:2/3/4
  • 为什么要接近整数:
    • GPU 放大整数倍最干净
    • 不容易出现半像素
    • 图片资源好管理(@2x @3x)

Android 的逻辑(更弹性)

Android 设备多得多。

Google 定义:160dpi = 基准密度

然后逻辑单位 dp 按密度算。

常见逻辑宽:360 / 393 / 411 dp

这些数字来自:

  • Material Design 排版宽度建议
  • 多列栅格设计
  • 设备分布统计

Android 更接受非整数 DPR,例如 2.625。

一个标准375

375 是怎么来的?

回到历史:iPhone 6(2014年)

  • 物理分辨率:750 × 1334
  • DPR = 2
  • 逻辑宽度:750 ÷ 2 = 375pt

这台手机成为:

  • 当时最主流尺寸
  • 设计稿标准宽
  • App UI 设计基准

从此:375 成为移动端设计“黄金宽度”。

现在还都是 375 吗?

不是。我们看最近 iPhone:

机型 逻辑宽
小屏旧款 320
标准款 375
新标准款 390
Plus / Max 414 / 430

例如:390 很常见(6.1 英寸);414 / 430 是大屏,而375 只是其中一档。

Android 更不统一。

常见逻辑宽:360 / 393 / 411 dp

375 在 Android 上反而不算主流。

为什么 375 这么“出名”?

因为:

  1. iPhone 6 销量巨大
  2. 设计生态围绕它建立
  3. 750px 设计稿 = 375pt × 2
  4. 小程序也沿用了 750 设计体系

所以很多教程都用 375 举例。

但现实不是全部 375。

为什么不统一成 375?

因为:

  • 屏幕物理尺寸在变大
  • 用户期望显示更多内容
  • 大屏如果还是 375 会显得太松
  • 厂商希望利用大屏优势

所以逻辑宽会略微增加。

那为什么变化不大?

你会发现:

  • 375 → 390 → 414
  • 360 → 393 → 411

都在一个区间:360 ~ 430

这是人手持阅读舒适区。

  • 太窄信息少
  • 太宽阅读困难

UI的设计稿

设计稿里的 px 是什么?

比如设计师说:

设计稿宽:750px
按钮高度:88px
字体:32px

这些 px:不是手机硬件像素,是设计坐标单位

它只是一个“比例参考网格”。

为什么不是物理像素?

  • 因为物理像素:每个手机都不同,分辨率不同,PPI 不同,DPR 不同

  • 如果设计按物理像素画,那每个手机都要重新设计一套。这显然不可能。

设计稿的本质

设计稿的 px 本质是:逻辑像素的放大版本

举例:

  • iPhone 主流逻辑宽:375pt

  • 设计稿常用:750px

  • 关系是:1pt = 2 设计稿px

这只是方便设计对齐。

完整流程图:

设计稿 px(比例单位)
        ↓
开发逻辑像素(pt / dp / px)
        ↓
系统 × DPR
        ↓
物理像素(真实屏幕)

不同平台设计基准

平台 常见设计稿宽
iOS 750px(对应375pt)
Android 720 / 750px
小程序 750px
Web 1920 / 1440px

为什么设计稿统一用 px?

因为设计软件(Figma / Sketch / PS):

  • 默认单位就是 px
  • 方便标注
  • 方便对齐
  • 方便交付

但它的 px 是:抽象设计像素

关键理解

设计稿的 px ≠ CSS px ≠ 物理像素

但它们之间可以映射。例如:

设计稿 100px
→ 开发 50pt
→ 物理 150px(假设 DPR=3)

UI 设计不是基于像素数量设计的,

而是基于:比例,视觉节奏,信息密度,人体工程学

px 只是表达工具。

rpx

什么是 rpx?

rpx = responsive pixel(响应式像素),是小程序提出的自适应单位。

它的核心规则只有一句话:750rpx = 屏幕宽度

不管什么手机:小屏、大屏、高分屏,屏幕宽永远被分成 750 份。

https://uniapp.dcloud.net.cn/tutorial/syntax-css.html

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html?spm=5176.28103460.0.0.4f9a6308x7i3Ra

rpx 是怎么工作的?

假设:手机 A 逻辑宽:375px;手机 B 逻辑宽:414px

  • 手机 A:1rpx = 375 / 750 = 0.5px
  • 手机 B:1rpx = 414 / 750 ≈ 0.552px
  • 所以:100rpx在不同手机上会变成不同的 px。
  • 这就是“自适应”。

rpx 和 px 的区别

单位 本质 是否自适应
px 逻辑像素 ❌ 不自动缩放
rpx 屏幕比例单位 ✅ 自动按宽度缩放

rpx 的本质是什么?

rpx 本质是:屏幕宽度的 1/750

它不是物理像素,也不是逻辑像素,而是一个“比例单位”。

真正渲染流程是:rpx → px(逻辑像素)→ 物理像素

为什么是 750?

因为移动端设计历史原因。主流 iPhone 逻辑宽是:375pt

设计稿通常做成:750px(2 倍)

关系是:1pt = 2 设计稿px

所以:750 设计稿成为行业默认。

小程序直接采用这个标准。

为什么 uni-app 使用 rpx?

设计稿直接 1:1 开发

设计师给你:(假设是750px的设计稿)

按钮 88px
边距 30px
字体 32px

开发直接写:

height: 88rpx;
padding: 30rpx;
font-size: 32rpx;

不用除 2,不用算比例,不用适配不同宽度。

自动适配不同手机

rpx 自动按屏幕宽度换算。

开发不需要关心:

  • 375
  • 390
  • 414
  • 411

系统帮你做了。

小程序生态统一

uni-app 兼容:

  • 微信小程序
  • H5
  • App

而小程序标准就是 rpx。

比 px 更适合移动端

px 是固定逻辑像素:在小屏大屏上不变。

width: 200px;

rpx 是比例单位:自动按屏幕缩放。

width: 200rpx;

rpx 的简图理解

设计稿:

|30|-------------690-------------|30|

小屏:

|30|-------690-------|30|

大屏:

|30|------------690------------|30|

比例保持一致。

举例说明

假设设计稿

设计稿宽度:750px

设计内容:

元素 设计稿尺寸
页面左右边距 30px
卡片宽度 690px
按钮高度 88px
标题字号 36px

开发代码示例(正确做法)

<template>
  <view class="page">
    <view class="title">标题文字标题文字标题文字标题文字标题文字</view>

    <view class="card">
      <text>卡片内容</text>
    </view>

    <view class="btn">确认按钮</view>
  </view>
</template>

<style>
.page {
  padding: 30rpx;     /* 设计稿 30px */
}

.title {
  font-size: 36rpx;   /* 设计稿 36px */
  margin-bottom: 30rpx;
}

.card {
  width: 690rpx;      /* 设计稿 690px */
  height: 200rpx;
  background: #f5f5f5;
  border-radius: 16rpx;
  margin-bottom: 40rpx;
}

.btn {
  
  width: 690rpx;  
  /* 设计稿 88px */
  height: 88rpx;
  background: #007aff;
  color: #fff;
  text-align: center;
  line-height: 88rpx;
  border-radius: 12rpx;
}
</style>

不同设备上会发生什么?

手机 逻辑宽
A 375px
B 414px

手机 A(375px 宽)

换算公式:1rpx = 375 / 750 = 0.5px

按钮高度:88rpx = 44px

手机 B(414px 宽)

换算公式:1rpx = 414 / 750 ≈ 0.552px

按钮高度:88rpx ≈ 48.5px

屏幕变宽,rpx 自动按比例放大,所有元素按比例变大,视觉比例保持一致

如果用 px 会怎样?

<template>
  <view class="page">
    <view class="title">标题文字-标题文字-标题文字-标题文字-标题文字</view>

    <view class="card">
      <text>卡片内容</text>
    </view>

    <view class="btn">确认按钮</view>
  </view>
</template>

<style>
.page {
  padding: 15px;     /* 30 ÷ 2 */
}

.title {
  font-size: 18px;   /* 36 ÷ 2 */
  margin-bottom: 15px;
}

.card {
  width: 345px;      /* 690 ÷ 2 */
  height: 100px;     /* 200 ÷ 2 */
  background: #f5f5f5;
  border-radius: 8px; /* 16 ÷ 2 */
  margin-bottom: 20px; /* 40 ÷ 2 */
}

.btn {
  width: 345px; 
  height: 44px;      /* 88 ÷ 2 */
  background: #007aff;
  color: #fff;
  text-align: center;
  line-height: 44px;
  border-radius: 6px; /* 12 ÷ 2 */
}
</style>

手机 A(375px 宽)

屏幕宽 = 375,刚好铺满。

  • 375 - 15 - 15 = 345
|15|----345----|15|

按钮高度 44px
字体 18px:20 * 18=360 >345,字体会拍到第二行

手机 B(414px 宽

屏幕宽 = 414,card和button还是345px,这个时候就会多出39px

  • 414-15*2=384

  • 384-345=39

  • 54=39+15

|15|----345----|54空余|

另外标题长度为20 * 18=360,card和button是345px,刚好大约是一个字体长宽度(360-384=15

标题只占一行:20 * 18=360<384

×

喜欢就点赞,疼爱就打赏