我的看法
说实话,rem 方案在大屏场景下有点过度设计。它的本质是:动态 font-size + rem 单位 → 等比缩放。最终效果跟 scale 差不多——都是等比缩放,不同比例的屏幕依然会留白。
但它比 scale 多了一堆配置(PostCSS 插件、flexible 脚本、rootValue 计算),开发体验并没有提升。rem 在移动端是经典方案,但在大屏场景,我觉得不如 scale 简单或 vw/vh 灵活。
方案四:混合方案(我的推荐)
实际项目中,我一般用混合方案:
布局容器 → vw/vh(铺满屏幕)
组件内部 → rem 或 px(保持组件独立性)
ECharts 等第三方库 → JS 动态计算 px
极端比例兜底 → CSS clamp() + 最小宽度
┌─────────────────────────────────────────┐
│ 浏览器视口 (100vw × 100vh) │
│ │
│ ┌──────────┐ ┌──────────────────────┐ │
│ │ 左侧栏 │ │ 主内容区 │ │
│ │ w: 20vw │ │ w: 80vw │ │
│ │ h: 100vh │ │ h: 100vh │ │
│ │ │ │ │ │
│ │ 内部组件 │ │ ┌────────────────┐ │ │
│ │ 用 rem │ │ │ ECharts 图表 │ │ │
│ │ │ │ │ JS 计算 px │ │ │
│ │ │ │ └────────────────┘ │ │
│ └──────────┘ └──────────────────────┘ │
└─────────────────────────────────────────┘
1. 布局层用 vw/vh:
.layout-left {
width: 20vw;
height: 100vh;
}
.layout-main {
width: 80vw;
height: 100vh;
}
2. 组件内用 CSS clamp() 做弹性字体:
.card-title {
// 最小 12px,理想 1vw,最大 24px
font-size: clamp(12px, 1vw, 24px);
}
.card-value {
font-size: clamp(24px, 2.5vw, 56px);
font-weight: bold;
}
3. ECharts 封装自适应 hook(Vue 3):
// useChartResize.ts
import { onMounted, onUnmounted, ref } from 'vue'
import * as echarts from 'echarts'
export function useChartResize(chartRef: Ref<HTMLElement | null>) {
let chart: echarts.ECharts | null = null
const fitSize = (px: number, base = 1920) => {
const width = document.documentElement.clientWidth
return Math.round(px * width / base)
}
const handleResize = () => {
if (chart) {
chart.resize()
// 重要:resize 后要重新设置包含字体大小的 option
}
}
onMounted(() => {
if (chartRef.value) {
chart = echarts.init(chartRef.value)
window.addEventListener('resize', handleResize)
}
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
chart?.dispose()
})
return { chart, fitSize }
}
4. 极端比例兜底:
#app {
min-width: 1024px;
min-height: 600px;
overflow: auto; /* 实在太小就出滚动条 */
}
2026 年的新选择:CSS Container Queries
这里补充一个很多大屏适配文章没提到的新玩意儿——容器查询(Container Queries) 。
传统的媒体查询(Media Queries)基于视口尺寸,而容器查询基于父容器尺寸。这意味着组件可以根据自己所在区域的大小来调整样式,而不是根据整个屏幕。
.chart-wrapper {
container-type: inline-size;
container-name: chart;
}
@container chart (min-width: 600px) {
.chart-title { font-size: 18px; }
.chart-legend { display: flex; }
}
@container chart (max-width: 599px) {
.chart-title { font-size: 14px; }
.chart-legend { display: none; }
}
截至 2026 年初,主流浏览器(Chrome 105+、Firefox 110+、Safari 16+)都已支持容器查询。在大屏项目中,特别是一个组件可能出现在不同大小区域的场景下,容器查询比媒体查询好用得多。
不过要注意,容器查询解决的是组件级响应式,不能替代全局的适配方案。它更适合作为混合方案中的一环。
实战选型决策树
你的大屏需要适配多种比例吗?
├── 不需要(固定 16:9)
│ └── 有复杂交互吗?
│ ├── 没有 → scale ✅ 快速搞定
│ └── 有 → vw/vh + JS 图表适配
└── 需要(多种屏幕)
└── 混合方案 ✅
├── 布局:vw/vh
├── 字体:clamp()
├── 图表:JS 动态计算
└── 组件:Container Queries
常见 FAQ
Q:大屏一般用什么设计稿尺寸? A:1920×1080 最常见。如果是 4K 屏,设计稿按 3840×2160 出,但开发时可以按 1920×1080 写,浏览器会自动处理设备像素比。
Q:scale 方案字体模糊怎么办? A:没有完美解决方案。可以尝试 will-change: transform、-webkit-font-smoothing: antialiased、设置较大基础字号然后缩小(而不是小字号放大)。实在不行就换 vw/vh 方案。
Q:ECharts 图表在 resize 后字体没变怎么办? A:chart.resize() 只更新画布尺寸,不会重新计算 option 中的固定 px 值。你需要在 resize 时重新调用 setOption,将 fontSize 等值用 JS 函数动态计算。
Q:大屏需要适配移动端吗? A:一般不需要。大屏就是大屏,手机打开看的场景极少。如果甲方非要,建议做两套页面,用媒体查询切换,而不是一套代码适配所有。
总结
大屏适配没有银弹。scale 最简单但最受限,vw/vh 最灵活但开发成本高,rem 两头不靠。生产项目推荐混合方案,把每种技术用在它最擅长的地方。
最重要的是:开工前跟甲方确认好所有要投放的屏幕尺寸和比例。 很多适配问题不是技术问题,是需求沟通问题。
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。