数据大屏常用布局-等比缩放布局(Scale Laylout)-使用 CSS Transform Scale 实现等比缩放

数据大屏常用布局-等比缩放布局(Scale Laylout)-使用 CSS Transform Scale 实现等比缩放

1.介绍

1.1 典型特征和典型特点

Scale Layout 的典型特征:

1.浏览器缩小

2.整个页面一起缩

3.布局不变

4.字体可以缩到几 px

工程上意味着:

  • 页面有一个固定"设计尺寸"
  • 浏览器变化时 不重排(不 reflow)
  • 只是 整体做 transform

为什么适合数据大屏?

数据大屏的典型特点

  • 固定分辨率设计(1920×1080 / 3840×2160)
  • 主要是 看,不是 点
  • 运行环境可控(会议室 / 大屏电视)

1.2 效果展示

效果实现展示:

1.3 CSS 编写原则

在这种方案下,你的 CSS 编写原则是

CSS 世界里永远是 1920×1080,缩放交给 JS,使用固定 px,不要写响应式

2.实战案例-使用 CSS Transform Scale 实现等比缩放

  1. 固定设计尺寸

在全局样式中,#app 被设置为固定的设计尺寸:

Index.css

css 复制代码
#app {
  @apply inline-block absolute left-1/2;
  width: 1920px;
  height: 1080px;
  transform-origin: 0 0;
  color: rgba(255, 255, 255, 0.9);
}
  1. 动态缩放计算

使用 useScreenScale hook 计算缩放比例:

typescript 复制代码
import { onMounted, onUnmounted } from 'vue'

const useScreenScale = () => {
	/**
	 * Scales the screen based on the design dimensions.
	 * window resize is not usually triggered, so no need to use debounce
	 * @return {void} This function does not return a value.
	 */
	const handleScreenScale = () => {
		const designDreftWidth = 1920
		const designDreftHeight = 1080

		const scale =
			document.documentElement.clientWidth / document.documentElement.clientHeight <
			designDreftWidth / designDreftHeight
				? document.documentElement.clientWidth / designDreftWidth
				: document.documentElement.clientHeight / designDreftHeight

		if (document.querySelector('#app') !== null) {
			;(document.querySelector('#app') as HTMLElement).style.transform =
				`scale(${scale}) translate(-50%)`
		}
	}
	onMounted(() => {
		handleScreenScale()
		window.onresize = () => handleScreenScale()
	})

	onUnmounted(() => {
		window.onresize = null
	})
}

export default useScreenScale

缩放逻辑:

  • 比较当前屏幕宽高比与设计稿宽高比(16:9)

  • 如果屏幕更窄:按宽度缩放 scale = 屏幕宽度 / 1920

  • 如果屏幕更高:按高度缩放 scale = 屏幕高度 / 1080

  • 应用变换:transform: scale(scale) translate(-50%)

    • translate(-50%)和left(50%)配合,实现水平居中
  • scale() 缩放,scale就是缩放比例

  • translate(-50%) 配合 left-1/2 实现居中

  1. 在 App.vue 中启用
javascript 复制代码
<script setup lang="ts">
useScreenScale()
</script>

页面如何实现等比缩放?

页面无需额外处理,因为:

所有页面都在 #app 内部

#app 整体缩放,内部元素自动跟随

使用固定像素值即可,例如:

html 复制代码
 <div class="w-[1114px] h-full">
        <HistoryEventsList
          ref="historyEventsListRef"
          @update:queryParams="handleTrendQuery"
          @open:warningEventDetail="handleOpenWarningEventDetail"
        />
      </div>
      <div class="w-[738px] h-full">

这些固定像素值(如 1114px、738px)会随 #app 的缩放比例自动缩放。

3.注意坑点- Element Plus 弹出层的默认行为

Element Plus 弹出层的默认行为,Element Plus 的弹出层组件(el-select、el-cascader、el-date-picker 等)默认会将下拉菜单挂载到 body 上,而不是组件所在的 DOM 树中。

DOM 结构示意:

html 复制代码
<body>
  <div id="app">  ← 这里应用了 transform: scale(0.75)
    <HistoryEventsList>
      <el-select>  ← 输入框在这里
      </el-select>
    </HistoryEventsList>
  </div>
  
  <!-- 默认情况下,下拉菜单会挂载到这里 -->
  <div class="el-select-dropdown">  ← 下拉菜单在 body 下,不在 #app 内!
    <el-option>...</el-option>
  </div>
</body>

由于缩放是写在app上的,但是弹出层挂在了body上,所以应该将弹出层挂到app上,使用append-to="#app"

html 复制代码
<el-date-picker
            v-model="currentDateRange"
            :shortcuts="EVENT_SHORTCUTS"
            append-to="#app"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            size="small"
            :style="{ width: '100%', height: '32px' }"
          />
相关推荐
0思必得02 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5163 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino3 小时前
图片、文件的预览
前端·javascript
layman05285 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔5 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李5 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN5 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒5 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库5 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052475 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫