一套求解器,十种分辨率不走样
数据大屏的设计稿只有 2880×1547 一张,目标屏从 1366×768 到 4K,比例还各不相同。我把适配规则写成一个比例因子、三组 clamp 和一条地图定位规则,十种分辨率下横向比例和 1920 基本一致,侧栏不滚动、不溢出。
- CATEGORY
- 研究
- YEAR
- 2026
- STATUS
- 笔记
- TOOLS
- css / clamp / javascript
entry记录
一块数据大屏有两个页签,两页共用一个顶栏:运行分析页中央是带光环的三维地图,顶部有一条 KPI 指标带,左右各排三张图表卡片;设施分析页把同一张地图换成路线与设施标记的版本,左栏放 9 个要素开关、一组视图操作和图例,右栏是智能助手对话面板。设计稿按 2880×1547 画,是 1920 屏的 1.5 倍;运行环境是全屏展示,覆盖 1366 到 1920 的 16:9、16:10、3:2 以及 2K 和 4K,不含 21:9。我负责设计侧,要向前端讲清楚这张稿子在各种屏幕上怎么实现。设计侧只给一张稿和一句「自适应」,前端就只能猜,所以这次把适配规则做成了能运行的页面:每个尺寸都有公式,每个公式都能在浏览器里拖动窗口看到效果。
把设计稿放进不同屏幕,有三处互相冲突:三维地图是从一张 4704 宽的全幅位图里按画板裁出来的,底部光环从左右卡片背后穿过,不能当成栅格里的中间一栏去拉伸,一拉比例就变;大屏文字可读的底线是 12px,左栏 9 行开关和右栏对话面板的标题栏在 12px 下至少要 240px 宽,但如果直接给侧栏设宽度下限,小屏上侧栏占比会从 35% 涨到 44%,地图被挤成中间一小块,画面明显比 1920 难看;画板高 1547,不是标准 16:9(1.5 乘 1080 应为 1620),按宽度等比缩放后,16:9 屏幕的高度比设计稿少 4.7%,左栏在设计稿里只剩 49px 余量,到了 1366×768 上要么出滚动条,要么把行压扁,而需求方不允许内部滚动。整屏等比缩小也不行:小屏上会出现 8px 的字。方案要同时满足三条:横向比例与 1920 一致,纵向内容装得下,两个页签切换时地图和侧栏不跳。
运行分析页的结构前后改了五版。最先试的是三栏栅格加断点,做了一版就看出断点之间的档位全靠硬凑,断点一多前端也记不住。于是把画面拆成两层:顶栏、侧栏和 KPI 带组成面板层,按视口求解尺寸;地图层是一张始终铺满视口的位图,只按省域轮廓的包围盒来定位和缩放。
整套计算只用一个比例因子 k,取宽、高两个方向上当前屏相对设计稿的缩小比例中较小的那个。所有尺寸用 CSS 函数 clamp(下限, 设计稿值 × k, 上限) 限制在上下限之间:中间档位严格等比,小屏碰到下限保住可读,大屏碰到上限防止空荡。整套方案最核心的是地图定位,相当于手写一个只认省域轮廓包围盒、保持纵横比完整装入容器的 object-fit: contain:先算出左右侧栏之间的中央可视区域,把包围盒按比例放进去,再把包围盒中心定在可视区域高度的 56.7% 处,复刻设计稿里位于 61.2% 屏高的构图。底图四周要往外多补一圈画面(出血),否则小比例屏会露底。适配规则写成连续函数,不列断点表,因为断点表只管列出的尺寸,函数能覆盖任意宽高,还能直接放进演示页运行,设计和前端看的是同一份东西。
运行分析页随后做了几处取舍。v3.2 让三张卡片直接填满侧栏可用高度,不做顶对齐;填满后如果卡片高过自身宽度,就把侧栏加宽到卡片呈正方形,但中央可视区域宽度不低于 55%。v4 的字号不再用视口宽度单位 vw,全部由 JS 算出后写进 CSS 变量,图表库读同一份变量,规则统一为基准乘 k、12px 下限、k 封顶 1.35,不再单独维护一套紧凑档字阶。v5 把侧栏宽度下限从 300 降到 240,解决了紧凑屏上地图被挤小的问题。两页所有栏内容在 12px 下的最小宽度都逐个量过,240 是能保住排版的底线;500k 在 1366 上算出来是 237,只差 3px,所以十档分辨率下横向几乎全部等比,多数档位双侧栏占 34.7%,中央可视区域占 62.5%。
设施分析页用同一套求解器,对齐要求有四条:顶栏共用;地图用同一条定位规则,落点以第一页为准;两页侧栏宽度相等;第二页单个侧栏面板的高度等于第一页三张卡片加两个间距。结果两页的求解函数逐字相同,只换两个轮廓常数,切换页签时横向完全不跳。两个方向分开处理:横向比例最容易被看出来,必须和 1920 基准屏一致;纵向差异靠填满、压间距、降字号来消化,复杂度就降了下来。
设施分析页的左栏要装下 9 行开关、视图操作和图例,不许出滚动条。左栏用三档行模式,按剩余高度逐档往下退:A 档完整,名称加描述两行;B 档精简,单行;C 档双列。评审时补了三条约束:紧凑档允许退到 B 单行,但描述文字是全页唯一允许低于 12px 的元素,可以退到 10px;开关、计数、色标、星标这些小部件不能跟着 k 缩,否则在 1366 上显大、4K 上显小,改为跟着行高走,用字号做上下限;面板内的元素只还原设计稿视觉,不做交互组件化。
第一版交付后,设计侧做了一次改版,目的是在紧凑屏上也让名称和描述保住两行显示,不再出现第一版的单行档。改版把图例从左栏移出,做成地图正下方的一条横带;左栏行高从 78 加到 88,名称和描述的字号加到 20 和 16;视图操作按钮加了图标;右栏与左栏等高;地图整体上移。
这次没有覆盖第一版,另起了一份 v2。先算账:两行能做到,但 1366×768 要用满所有让步空间;拆掉图例在紧凑档只省出约 95px,底部的图例带又占回 44px 加上边距和间隔,侧栏净高只多了 6px。v2.0 最初的让步阶梯里有两级是把按钮退成纯图标,我否掉了:视图操作在任何分辨率下都必须是「图标 + 文字」,这是产品侧的硬要求。剩下的让步分三步:先把描述字号从 12 退到 10;再把行内边距和行距从 8 退到 6;最后去掉视图操作的标题,按钮高度从 32 退到 30。三步用满后,1366×768 刚好装下两行,行高 45.7;1536 和 1600 只用到第一步,1440、1680 及以上不用让步。随后 v2.2 去掉了图例带里单独占一行的「图例」二字,v2.3 把交付页改写成面向前端的精简版。图例带和地图上移是版面本身的改动,求解器抹不平,这个代价写进了方案:两页切换时侧栏底和地图在纵向各跳约 60 到 140px,消息区也少了 60 到 100px。12px 字号下限、按钮必须带文字、不允许内部滚动,这几条不能让的先定死,剩下的让步就排得出先后。
设施页第一版直接拿设计稿里「外轮廓」图层的尺寸当包围盒,结果省域比第一页小了 8%,在 1920 上右沿偏了 78px,评审演示页时打开两页叠加的参考线才看出来。改为在导出位图上按像素阈值实测,量出 1770×1172。第一页的情况正好相反:那张图带一圈发光光环,按像素阈值会把光环算进去,反而是设计稿里的节点常数准。所以取哪个值不能写成固定规则,要靠同分辨率下两页叠在一起的参考线去验。
v2.1 的紧凑让步原本写成 max(6, 16c),其中 c 是侧栏宽除以 500,侧栏里的尺寸按它缩放。这个算式在 1366 上算出来是 7.7 而不是 6,多出的 1.7px 乘上 18 处间距,正好把 1366 推回单行档。改成了绝对值 6,因为只有紧凑档会走到这一步,不需要再乘比例。
v1.2 把描述文字的下限改成 10px 时,规则一开始写成了全局生效,1920 上本来够放的 12px 也被压成了 10。后来改成先试 12,A 档装不下时再退到 10。
左栏高度模型漏算了面板上下两条 1px 的描边,最后一行贴底,跑自动化截图逐行量像素时才发现。
文档里曾写 C 双列档会在 1280×720 触发,实测不会,兜底排版走的是 B 档,于是把文档改成了「保险档,支持范围内不触发」。这类出入是评审文档时对着十档表逐条核出来的,验收标准是文档里的每一个数字都要能在演示页里看到。
顶栏的透明底图一开始导不出来,设计软件导出的 PNG 被混合模式图层压成了白底。办法是先导出文字转成图形轮廓(文字转曲)的 SVG,删掉画布底色矩形,再用无头浏览器(没有界面、由脚本控制的浏览器)以透明背景截图。
定稿里两页共用 k、边距、顶栏、侧栏宽度、可视区域宽度和省域轮廓宽度;设施分析页 v2 左栏按阶梯求解,任何一级按钮都保留图标加文字,右栏的消息区是整页唯一允许滚动的区域。每份方案都打包成一个单文件网页交给前端:上半部分是公式、十档分辨率对照表和验收清单;下半部分是交互演示,可以选预设分辨率、输入任意尺寸、拖动窗口实时重排,上面叠了地图轮廓、可视区域、图例带以及另一页在同分辨率下的侧栏框参考线,并配有实时读数面板,前端对着读数面板就能核对自己的代码。十种常规分辨率全部用无头浏览器按真实视口打开演示页截图,逐一检查左栏列表无溢出、9 行描述各自成行、按钮图标和文字无截断、图例带单行放得下、控制台无报错。
process对比
两页共用的量
- k
- min(W/2880, H/1547) · 1366: 0.474 · 1920: 0.667 · 3840: 1.333
- 侧栏宽 S
- clamp(240, 500k, 560),高屏可加宽 · 240 / 333 / 578
- 顶栏 T
- clamp(64, 136k, 200) · 65 / 91 / 181
- 可视区域占宽
- W − 2(M+S) · 62.1% / 62.5% / 67.1%
- 省域轮廓占宽
- contain 的结果 · 59.6% / 58.8% / 62–63%
- 档位
- k < 0.60 紧凑 · < 1.0 标准 · ≥ 1.0 宽裕
- 字号
- 基准 × min(k, 1.35) · 12px 硬下限 · KPI 数字 34 下限
- 兜底
- 小于 1280×720 按 1280×720 排版后整屏 scale 缩小居中
- 窗口变化
- 写 CSS 变量 → 强制重排 → 防抖 200ms → 通知图表重绘
公式
k = min(W / 2880, H / 1547)
M = clamp(16, 40k, 56) 安全边距
T = clamp(64, 136k, 200) 顶栏功能条高
S = clamp(240, 500k, 560) 侧栏宽
channel = W − 2(M + S) 中央可视区域宽
s = min(channel·(1−padX)/OUT_W, Hc·(1−padY)/OUT_H)
cx = W/2, cy = top + 0.567·Hc 包围盒中心的落点运行分析页
- 卡片
- 三等分填满侧栏 · 宽高比超过 1.45 时压间距换高度 · 间距压到 8 仍不够则放弃比例,绝不溢出
- 紧凑档图表
- 轴标签隔一个显示 · 类目名两字缩写 · 柱宽不超过 16 · 类目多于 6 个取前 6 · 图例并入单位行
设施分析页 v2
- c
- 侧栏宽 ÷ 500,侧栏内的尺寸按它缩放
- 侧栏顶
- T + clamp(24, 65k, 100)
- 图例带高
- 2·max(12, 25c) + max(20, 30c),贴在地图正下方居中
- 侧栏底
- 图例带上方 15k,左右面板等高
- 右栏标题栏
- max(64, 92c)
- 让步阶梯
- 描述 12 → 10 · 内边距与行距 8 → 6 · 去标题、按钮 32 → 30
验证的十种分辨率
1366×768、1440×900、1536×864、1600×900、1680×1050、1920×1080、1920×1200、2256×1504、2560×1440、3840×2160。
result小结
- 结论
- 十种常规分辨率下横向比例与 1920×1080 基本一致,侧栏占 34.7%、可视区域占 62.5%,1366 只差 3px;侧栏不滚动、不溢出,两页切换横向不跳;1366×768 上左栏仍是「名称 + 描述」两行。
- 参数
- k = min(W/2880, H/1547) · 侧栏 clamp(240, 500k, 560) · 顶栏 clamp(64, 136k, 200) · 字号 基准 × min(k, 1.35)、12px 下限
- 没做完
- 规则只覆盖 16:9、16:10、3:2 和 2K/4K,不含 21:9;小于 1280×720 时只能整屏缩小居中、留黑边;设施分析页 v2 与运行分析页切换时,侧栏底和地图纵向各跳约 60–140px,要不跳得同步两页版面。
log日志
- 2026-10
- 首次记录