一、 分辨率
| 分辨率 | 典型设备 | 字体大小 | 布局策略 | 单位选择 |
|---|---|---|---|---|
| 1920×1080 | 普通台式显示器、高端笔记本、会议平板 | 14px-18px | 响应式栅格 | rem、%、px |
| 2560×1440 | 普通台式显示器、高端笔记本、会议平板 | 14px-18px | 响应式栅格 | rem、%、px |
| 3840×2160 | 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 | >=24px,甚至40px+ | 固定比例布局+视口单位 | vw/vh、vmin |
| 5120×2880 | 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 | >=24px,甚至40px+ | 固定比例布局+视口单位 | vw/vh、vmin |
| 7680×4320 | 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 | >=24px,甚至40px+ | 固定比例布局+视口单位 | vw/vh、vmin |
| 拼接屏(如 3840×1080 多屏) | 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 | >=24px,甚至40px+ | 固定比例布局+视口单位 | vw/vh、vmin |
超大屏
常见分辨率
-
3840×2160(4K UHD)
-
5120×2880(5K)
-
7680×4320(8K)
-
或拼接屏(如 3840×1080 多屏)
典型设备
- 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙
字体大小
-
=24px,甚至40px+
布局策略
- 固定比例布局+视口单位
单位选择
- vw/vh、vmin
开发注意点
-
禁用滚动条:超大屏通常是全屏展示,因此需要禁用滚动条
-
使用vw/vh + clamp() 控制元素大小,确保在4k/8k下比例协调
-
测试正式设备: 浏览器模拟器无法还原观看距离和像素密度。
-
1px边框在8k屏上可能看不到,建议使用2px+
二 、开发方案
1. 等比例大屏/超大屏
- transform: scale() + 容器包裹(最稳定)
2. 超大长屏幕
- 场景 1:超宽拼接屏(如 3840×1080、5760×1080)------ 常见于数据看板、监控墙
垂直方向:严格按 1080px 高度布局(保证字体、组件高度可读)
水平方向:使用 响应式栅格 / 弹性布局 / 动态列数,填满整个宽度
实现:
【1】禁用全局 scale,改用 vw + rem
/* 根字体基于高度固定,避免文字随宽度无限变大 */
html {
<!-- 16px × (当前屏幕高度 / 设计稿高度) 如果屏幕分辨率高度不是1080,可以直接替换这个公式 -->
font-size: calc(1080px / 1080 * 16px); /* 固定为 16px,或根据需求微调 */
}
/* 主容器高度固定为 1080px,宽度 100% */
.dashboard {
width: 100vw;
height: 1080px; /* 关键:高度锁定 */
overflow: hidden;
}
【2】水平区域使用弹性布局或 CSS Grid
<template>
<div class="dashboard">
<Header class="header" />
<div class="content">
<!-- 使用 Grid 自动分配列宽 -->
<ChartCard v-for="item in charts" :key="item.id" />
</div>
</div>
</template>
<style scoped>
.content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); /* 自适应列数 */
height: calc(100% - 80px);
gap: 20px;
padding: 20px;
}
</style>
【3】关键元素使用 vh 控制高度(可选)
.card {
height: 30vh; /* 约 324px @1080p,比例合理 */
}
三 、缩放方案-代码封装
screenAdaptive.ts
interface AdaptiveOptions {
designWidth?: number; // 设计稿宽度,默认 1920
designHeight?: number; // 设计稿高度,默认 1080
mode?: 'width' | 'height' | 'auto' | 'widthAndHeight'; // 缩放模式
containerSelector?: string; // 容器选择器,默认 .screen
transformOrigin?: string; // transform-origin,默认 top left
};
//定义默认配置项
const DefaultContainerSelector = '.screen';
const DEFAULT_OPTIONS: Required<AdaptiveOptions> = {
designWidth: 1920,
designHeight: 1080,
mode: 'auto', // auto = 等比缩放(取 min(scaleX, scaleY))
containerSelector: DefaultContainerSelector,
transformOrigin: 'top left'
};
let resizeTimer: number | null = null;
export const initScreenAdaptive = (options: AdaptiveOptions = {}) => {
const opts = { ...DEFAULT_OPTIONS, ...options };
const { designWidth, designHeight, mode, containerSelector, transformOrigin } = opts;
const adapt = () => {
const container = document.querySelector<HTMLElement>(containerSelector);
if (!container) return;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
let scale: number = 1;
let scaleX: number = 1;
let scaleY: number = 1;
if (mode === 'width') {
// 仅按宽度缩放(高度可能溢出)
scale = screenWidth / designWidth;
} else if (mode === 'height') {
// 仅按高度缩放(宽度可能溢出)
scale = screenHeight / designHeight;
} else if (mode === 'widthAndHeight') {
// 宽高都按比例缩放
scaleX = screenWidth / designWidth;
scaleY = screenHeight / designHeight;
} else {
// auto: 等比缩放,保证完整显示(类似 background-size: contain)
const scaleX = screenWidth / designWidth;
const scaleY = screenHeight / designHeight;
scale = Math.min(scaleX, scaleY);
}
// 设置容器尺寸和缩放
container.style.width = `${designWidth}px`;
container.style.height = `${designHeight}px`;
container.style.transform = mode === 'widthAndHeight' ? `scale(${scaleX}, ${scaleY})` : `scale(${scale})`;
container.style.transformOrigin = transformOrigin;
};
// 首次执行
adapt();
// 监听窗口变化(带防抖)
const onResize = () => {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = window.setTimeout(adapt, 100);
};
window.addEventListener('resize', onResize);
// 返回销毁函数(可选)
return () => {
window.removeEventListener('resize', onResize);
if (resizeTimer) clearTimeout(resizeTimer);
};
}
// 将 页面坐标(clientX, clientY)转换为 设计稿坐标
export const getDesignCoords = (
clientX: number,
clientY: number,
containerSelector = DefaultContainerSelector
): { x: number; y: number } => {
const container = document.querySelector<HTMLElement>(containerSelector);
if (!container) {
return { x: clientX, y: clientY };
}
// 获取容器的边界和 transform 值
const rect = container.getBoundingClientRect();
const style = window.getComputedStyle(container);
const transform = style.transform;
let scaleX = 1;
let scaleY = 1;
if (transform && transform !== 'none') {
// 解析 matrix( a, b, c, d, tx, ty )
const matrix = new DOMMatrix(transform);
scaleX = matrix.a; // scaleX
scaleY = matrix.d; // scaleY
}
// 将页面坐标转换为容器内的原始设计稿坐标
const x = (clientX - rect.left) / scaleX;
const y = (clientY - rect.top) / scaleY;
return { x, y };
}
使用方法:
【1】引入
import { initScreenAdaptive } from './screenAdaptive';
【2】使用
//定义设计稿的分辨率
const DesignDraftWidth = 1920;
const DesignDraftHeight = 1080;
//dom加载完成后,进行可视窗口大小判断
if (window.innerWidth > DesignDraftWidth) {
initScreenAdaptive({
designWidth: DesignDraftWidth,
designHeight: DesignDraftHeight,
mode: 'height',
transformOrigin: 'center'
});
}
//div容器需要配置默认样式名称.screen(也可以自定义)
<div class='screen'>
/* 这里存放需要缩放的dom元素 */
</div>
注意
对于大多数组件库的弹框、抽屉等组件默认绑定到是body标签上,故无法进行缩放,只有把这些组件绑定到你的包裹容器(.srceen)才可以实现缩放