news 2026/9/29 4:49:12

Vue3+TS+Vite数据大屏自适应方案详解:scale与rem两种方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3+TS+Vite数据大屏自适应方案详解:scale与rem两种方法

vue3+ts+vite数据大屏自适应总结(两种方法)

做数据大屏这个需求,我估计不少前端同学都经历过:设计稿永远是1920x1080,看着也挺正常,结果一到现场投放屏上就露馅——要么上下滚出滚动条,要么两边空一大块,要么所有图表被拉伸得没法看。我最近正好用vue3+ts+vite这套技术栈重构了一个可视化大屏项目,把自适应这块从头到尾重新梳理了一遍,总结下来其实就两条路:整体等比缩放和动态换算单位。本文把这两套方案的原理、核心代码、取舍逻辑和实际踩坑记录全部展开,帮你做完大屏自适应之后不用再被测试追着提bug。

这篇文章适合几类人看:刚接手vue3大屏项目、对自适应方案还在纠结怎么选的同学;已经用了一种方案但出了各种奇怪问题、想找排查思路的同学;以及项目完了想做个技术总结沉淀一下的。所有代码都基于vue3+ts+vite,ECharts部分用的是5.x版本,具体版本差异不影响逻辑理解。

1. 项目背景与需求分析

1.1 大屏项目为什么总会卡在自适应

做后台管理系统的时候,页面是给鼠标和键盘用的,窗口大小随便拖,内容自适应滚动就完事。但数据大屏不一样,它是给“看”的,不是给“用”的。投放场景往往是一个固定分辨率的屏幕,可能是会议室的一块1080P电视,也可能是指挥中心一面2K的三联屏,甚至有些客户现场还是老旧的1366x768工业屏。

需求方给设计稿的时候,UI一般只出1920x1080一版。你如果老老实实把所有尺寸写成px,开发完在本地预览一切正常,拿到现场一接屏,那画面只能用“灾难”来形容。更麻烦的是,大屏项目后期经常会有“现场屏幕换了一个”的突发需求,投放分辨率一变,固定px方案就得改一轮样式,改完这里适配了那里又歪了。

所以大屏自适应的本质需求是:设计稿按固定尺寸出,运行环境按任意分辨率投,页面需要在这两者之间保持 1:1 的视觉比例。理解这一点,后面看方案就清晰了。

1.2 为什么这套项目选了vue3+ts+vite

这个项目技术栈选型时其实纠结过要不要直接用vue2。后来确定vue3+ts+vite,主要三个原因:组合式API把自适应逻辑抽成hook之后复用和隔离都舒服,不用再像vue2那样大量混入mixin;TS上业务方给的数据结构比较杂,有接口类型约束后面改字段会少踩很多坑;vite冷启动确实比webpack快,大屏页开发时改动频繁反馈会更快。对echarts的按需引入、对postcss插件生态,三者配合都很成熟,没什么历史包袱。

要说vue3和vue2在大屏场景下最直观的差别,就是逻辑复用。vue2时代写一个自适应的mixin,data、computed、watch全塞在一起,看代码要来回跳。vue3一个useXxx函数把所有状态和副作用集中管理,大屏里一套缩放逻辑、一套轮询逻辑、一套图表resize逻辑,都是独立模块,后面哪个环节出问题直接找到对应hook排查。

1.3 先理清:自适应到底要解决什么问题

很多同学一上来就查“大屏自适应方案”,结果被各种名词绕晕。其实你只要想清楚,要解决的其实就是三件事:

第一,页面整体布局不能变形。按1920设计稿写的栅格、间距、图表尺寸,在目标屏幕上保持比例关系,该占多少视觉空间还是占多少。

第二,内容不能溢出或留白过多。不能出现滚动条,也不应该出现大面积的黑色留白。

第三,图表本身要跟着动。ECharts初始化时是按容器像素尺寸绘制的,容器尺寸变了图表不resize,就会出现局部被裁切或者图表缩在角落的情况。

两条主流路线分别从不同角度回答这三件事:scale方案直接把整块页面当成一张画布等比缩放;rem方案把px换成相对单位让布局随屏幕宽度变化。下面逐个展开。

2. 方法一:scale整体等比缩放

2.1 scale方案的核心思路

scale方案的思路非常直接:开发时完全按设计稿尺寸写一套固定px的页面,然后把整个页面用一个容器包起来,根据目标屏幕与设计稿的比例,通过CSS的transform: scale()对整体做等比缩放。

举个例子,设计稿是1920x1080,现场屏幕是2560x1440,宽度比和高度比都是1.333,那就把整体内容scale(1.333)放大。如果现场屏是1366x768,比例大概是0.711,那就scale(0.711)缩小。缩放的中心点放在容器中心,元素位置相对关系保持不变。

这样做最大的好处是开发体验好。你写CSS的时候根本不用考虑适配,设计稿量出来多少px就写多少px,包括绝对定位、间距、字体大小全都照搬,不需要开发时做额外的心算或者换算。页面开发完,剩下的事情都交给缩放函数处理。对于内容区域固定、图表密集、视觉还原度要求高的大屏来说,这个方案最省心。

2.2 手写一个useScreenScale Hook

在vue3+ts+vite项目里,我会把scale逻辑封装成一个Hook,组件里直接调用即可使用,避免每个页面复制粘贴。

// src/hooks/useScreenScale.ts import { ref, onMounted, onBeforeUnmount } from 'vue' const DESIGN_WIDTH = 1920 const DESIGN_HEIGHT = 1080 export function useScreenScale() { const scale = ref(1) const updateScale = () => { const width = document.documentElement.clientWidth const height = document.documentElement.clientHeight const scaleX = width / DESIGN_WIDTH const scaleY = height / DESIGN_HEIGHT scale.value = Math.min(scaleX, scaleY) } const onResize = () => { updateScale() } onMounted(() => { updateScale() window.addEventListener('resize', onResize) }) onBeforeUnmount(() => { window.removeEventListener('resize', onResize) }) return { scale, designWidth: DESIGN_WIDTH, designHeight: DESIGN_HEIGHT } }

这段代码里有个关键点:为什么用Math.min(scaleX, scaleY)而不是直接用宽度比例?因为大屏的首要原则是内容完整可见。如果屏幕比例和设计稿比例不一致,比如设计稿16:9,现场屏是16:10,按宽度比例缩放会导致高度溢出、出现滚动条。取两者较小值,会有一侧出现少量留白,但内容一个不落。留白问题可以通过外层背景色或设置页面底部背景图来弥补。

2.3 模板中的应用与样式细节

在组件里直接调用这个Hook,然后绑定到最外层内容容器:

<template> <div class="screen-wrapper"> <div class="screen-content" :style="{ width: designWidth + 'px', height: designHeight + 'px', transform: `scale(${scale})` }" > <!-- 大屏内容区域,按1920x1080开发 --> <div class="panel">...</div> </div> </div> </template> <script setup lang="ts"> import { useScreenScale } from '@/hooks/useScreenScale' const { scale, designWidth, designHeight } = useScreenScale() </script>

样式这里有个很容易踩坑的点,要特别说明:

.screen-wrapper { width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; background: #0a1e3a; } .screen-content { flex-shrink: 0; transform-origin: center center; }

我用的是flex布局把缩放容器居中,而不是给容器设置left/top偏移然后自己计算位置。原因很简单:flex居中天然以容器的中心点为基准,缩放大或缩小后元素依然保持在屏幕正中央,不用写死margin或者transform偏移量,也规避了不同浏览器对transform-origin解析不一致导致的位置抖动问题。

2.4 配套的ECharts适配处理

scale方案中ECharts图表也要做处理。图表是放在1920x1080固定容器里的,整体被scale之后,绘制出来的canvas图片也会一起缩放,视觉上比例没问题。但有一种情况需要主动调一下resize:浏览器窗口尺寸变化时,图表容器本身尺寸并没有变(因为是固定px),理论上不需要resize。但为了保险起见,我一般会在监听resize时对页面内所有ECharts实例统一调用一次resize,避免某些情况下的渲染残留。

同时要注意:不要在onMounted里同步初始化ECharts。因为如果用v-if控制了大屏区块的显示,或者某些容器在缩放动画过程中还未完成布局,echarts.init初始化时拿到的容器宽度可能是0,图表直接不渲染。这种情况用nextTick包一下,或者把init放在setTimeout里延迟一帧都能规避。这个坑我在多个项目里都遇到过,排查了挺久才定位到。

2.5 scale方案容易忽略的两个问题

第一个是事件坐标偏差。transform: scale是视觉变换,元素的实际布局尺寸还是1920x1080。当页面被缩放到小屏时,ECharts的tooltip定位、点击事件的坐标换算偶尔会出偏差,表现为鼠标指在某个柱子上,tooltip却出现在旁边。常见处理手段有两个:ECharts的tooltip启用confine: true限制在容器内,或者给整个容器加一些额外的坐标换算逻辑。实际项目中confine: true能解决大部分定位异常。

第二个是字体清晰度。scale放大到2K或4K屏幕上时,canvas绘制出来的图表是按1920设计稿对应的像素数渲染的,被放大后边缘会有轻微的模糊感。如果放大比例在1.5倍以内,肉眼基本感知不到;但如果投放屏和设计稿尺寸差太多,比如从1080P放大到4K,建议让ECharts的devicePixelRatio配置跟随屏幕实际像素比,再把图表容器设计稿尺寸传入渲染,清晰度会好很多。

3. 方法二:rem动态换算自适应

3.1 rem方案的做法与适用场景

另一条路线是rem方案,思路是把HTML根元素的font-size设置成跟随屏幕宽度变化的值,页面里所有尺寸用rem单位书写,这样布局会随屏幕宽度等比例缩放。

还是拿1920设计稿举例。如果把根字号设置为clientWidth的十分之一,即192px = 1rem,那么设计稿里一个960px宽的区块,写成5rem,在1920屏上就是960px。屏幕宽度变成2560时,根字号变成256px,这个区块实际宽度变成1280px,和设计稿的等比关系保持一致。

这条方案的优点是对DOM层级没有特殊要求,不需要整体包一层缩放容器,所有子组件按普通布局自然排列就能自适应,对局部组件、弹窗、列表的适配比较友好。但也正因为rem是线性换算,它在高度方向上是听天由命的:宽度方向完美等比,高度方向不一定能全屏填充,会暴露设计稿比例和屏幕比例不一致的问题。所以它更适合屏幕宽高比相对稳定、或者以宽度为主要布局依据的场景。

3.2 动态设置根字号

rem方案的第一步,写一个初始化脚本:

// src/utils/rem.ts const BASE_WIDTH = 1920 function setRootFontSize() { const clientWidth = document.documentElement.clientWidth if (!clientWidth) return document.documentElement.style.fontSize = clientWidth / 10 + 'px' } setRootFontSize() window.addEventListener('resize', setRootFontSize)

在main.ts里直接引入执行即可。为什么除以10而不是除以100或者取其他数值?这个比例纯粹为了开发方便。100的话,1920设计稿下1rem=192px,2rem=384px,后续pxtorem的根值也是192;除以10也一样,但根字号会大一些,chrome调试工具在模拟设备时显示更直观。两种都没问题,关键是和后面postcss-pxtorem的rootValue对齐。

如果你要适配的是其他基准宽度,比如1920改成750,也是一种常见做法,很多移动端项目就是这么搞的。大屏场景我仍然建议以1920为准,因为UI出大屏设计稿基本都是这个尺寸。

3.3 用postcss-pxtorem自动转换CSS中的px

手写rem有个问题:写CSS的时候要把每个px都手动换算成rem,很费劲,也容易出错。所以配合postcss-pxtorem自动处理。

先安装依赖:

npm install postcss-pxtorem -D

然后在vite.config.ts里配置:

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import postcssPxtorem from 'postcss-pxtorem' export default defineConfig({ plugins: [vue()], css: { postcss: { plugins: [ postcssPxtorem({ rootValue: 192, propList: ['*'], unitPrecision: 5, minPixelValue: 2, selectorBlackList: ['no-rem'] }) ] } } })

这里几个配置项的含义要注意。rootValue: 192对应上面脚本里1rem=192px;propList: ['*']表示所有CSS属性里的px都转换;minPixelValue: 2意思是小于等于2px的不转,防止1px边框被转成小数rem后出现渲染异常;selectorBlackList: ['no-rem']是提供逃生通道,如果某一块样式你想保留px,给选择器加上这个类名即可,pxtorem会自动跳过。

配置完以后,你写CSS还是正常的px值,构建时会自动转rem:

/* 开发时这样写 */ .box { width: 960px; margin: 20px auto; font-size: 16px; } /* 构建后相当于 */ .box { width: 5rem; margin: 0.10417rem auto; font-size: 0.08333rem; }

视觉比例在1920屏上和设计稿完全一致,在其他宽度屏幕下自动等比变化。

3.4 ECharts和JS侧尺寸的换算问题

这里有一个非常关键的坑,我必须单独拿出来说:postcss-pxtorem只能处理CSS代码,处理不了JS里写死的像素值。ECharts的配置项,比如title.fontSize、legend.itemWidth、series.symbolSize,这些是JS对象,构建时pxtorem完全不会碰它们。

你如果直接把ECharts的option写成固定px,在1920屏上没问题,换到其他宽度屏幕后,图表本身会按容器宽度撑开,但标题、图例、柱子的描点尺寸统统不会变,视觉效果立刻失衡。

解决办法是写一个换算函数,动态获取当前根字号,把设计稿px换算成运行时实际像素值:

// src/utils/adaptive.ts export const getRemBase = () => { return parseFloat(getComputedStyle(document.documentElement).fontSize) } export const px2px = (px: number) => { return (px / 192) * getRemBase() }

ECharts初始化时这样用:

import * as echarts from 'echarts' import { px2px } from '@/utils/adaptive' const option = { title: { text: '近30天销售额', fontSize: px2px(22) }, tooltip: {}, legend: { itemWidth: px2px(14), itemHeight: px2px(14) }, series: [ { type: 'bar', barWidth: px2px(16), data: [] } ] }

这样图表里的所有尺寸都会跟着根字号的变化同步缩放。注意一点:resize监听时除了调用chart.resize(),还要重新setOption一次更新这些已换算的尺寸,因为根字号变化后旧的像素值已经不匹配当前屏幕了。为了性能考虑,resize监听可以加个简单的节流或者在尺寸变化累计到一定程度后再重绘。

3.5 rem方案在实践中的边界问题

rem方案也有自己的短板。最典型的就是宽高比不一致问题。1920x1080设计稿是16:9,如果现场屏幕是16:10,按宽度换算后,高度方向上内容会不够填满,底部会出现空白;反过来,如果现场屏是带鱼屏,宽度比例很大,内容会被拉得特别扁,视觉上图表会被压扁变形。这就是当年rem方案在移动端很普及、但大屏场景里争议多的根本原因。

第二个问题是开发体验没有scale方案爽。虽然pxtorem解决了手工换算,但一旦你遇到不想转换的局部元素,还得记得往选择器加黑名单类名。而且图表配置里的字体和尺寸还要额外包一层px2px,每个图表都要处理,写起来略啰嗦。

所以我的判断是:rem方案适合屏幕比例稳定、且大屏内部包含较多普通滚动列表、文本模块、弹窗的场合,它能保留DOM自然流布局的好处。如果页面非常纯粹就是几块图表,还是scale方案来的直接。

4. 两种方案横向对比与选型思路

4.1 关键维度对比

把两套方案放在一起看,横向差异就很明显:

对比维度scale整体缩放rem动态换算
实现复杂度低,一个Hook搞定中,需要初始化脚本+构建配置+JS尺寸适配
布局还原度完全还原设计稿比例宽度等比,高度方向受屏幕宽高比影响
开发效率高,写固定px即可中,图表配置需手动适配
文字和图表清晰度缩放倍数过大时可能有轻微模糊字体随比例变化,无模糊问题
对普通列表/滚动场景不适合,内容被等比缩放不自然适合,布局可自然流动
不同分辨率兼容性宽高比差异大时出现留白,但内容完整宽高比差异大时底部留白或内容被压扁
局部换肤/业务定制内容比例定死,不好单独调整每个模块可单独控制、单独缩放
团队上手成本很低,理解transform即可需要理解rem和构建配置

4.2 我实际项目里的选型逻辑

如果你问我在一个全新的大屏项目里怎么选,我的经验是分三步判断:

第一步,看投放屏比例是否固定。如果现场屏幕型号确定,基本都是16:9的宽屏,那无脑选scale,开发爽、效果稳定、还原度最高。

第二步,看内容和交互复杂度。如果页面里除了图表还有大量滚动列表、实时消息流、弹窗、多tab切换,甚至可能需要一些交互操作,scale方案会让这些内容也跟着等比缩放,滚动条和弹窗的表现很不自然。这种场景建议rem方案或混合方案:整体用rem,局部特殊模块再用scale微调。

第三步,看团队基建成熟度。如果项目里已经有不少封装好的组件,这些组件的样式都是用px写的,要让它们立刻兼容rem,就得把这批组件全部过一遍pxtorem的转换规则。如果组件本身写得比较规范,比如没有写死行内style,转换成本可控;如果组件历史包袱重,那scale方案几乎不需要改组件就能接入,优先考虑。

4.3 混合方案的简单思路

我在实际操作中发现,两个方案并不是非此即彼。有些大屏项目最终采用的是“混合”形态,常见组合是:最外层用scale做整体兜底,保证在任何屏幕下内容完整显示;内部对需要自然滚动的模块,单独把它的样式从rem体系中恢复为px,再挂一个独立的滚动容器,让这部分按浏览器窗口高度自适应。

复杂场景下还可以用JS动态判断:屏幕宽高比与设计稿相差超过某个阈值时切到rem模式,接近设计稿比例时回归scale模式。不过这种混合方案维护成本高,前期没有明显收益,不建议一开始就奔着它去。先把基础方案跑通,后面真有需求再局部加逻辑。

5. 真实项目踩坑实录与排查清单

5.1 ECharts初始化时容器宽度为0

这个问题遇到频率极高。大屏页面通常会先把所有面板渲染出来,但某些面板被v-if或者v-show控制着,或者父级容器处于display: none状态时,图表初始化拿到的容器尺寸就是0,ECharts直接画不出来或者画出来的图表只有一小块。

后来我把所有图表初始化统一放进nextTick里,并且用一个简单的延迟加载机制,确保容器已经完成布局后再init。如果页面里有tab切换,切到某个tab时再初始化对应图表,比一次性全部初始化更靠谱。这种场景下图表实例化代码最好放在tab切换的回调函数里,避免在页面初始时就绑到一个不可见的容器上。

5.2 scale之后tooltip定位不准

用scale方案后,页面整体被transform缩放,ECharts的tooltip默认跟随鼠标事件生成的页面坐标定位,在缩放容器内会出现坐标偏移。严重的时候,鼠标明明指在左侧的柱子上,tooltip却跑到右侧空白区域。

我的解决思路是给tooltip配置confine: true,让tooltip被限制在图表容器内部,同时配合position回调做手动偏移修正。如果图表数量不大,也建议直接让tooltip跟随鼠标,在position回调里把鼠标坐标换算成容器内的相对坐标返回。这个处理方式虽然要写一点代码,但定位最准确,基本不会出现“tooltip和图形分离”的观感。

5.3 rem方案下ECharts的字体小到看不见

这是rem方案最常见的翻车场景:CSS字体都正常缩放了,图表的title和图例文本却小得看不清。原因就是上面说的,ECharts配置项里的数值不走pxtorem。

解决方式不再重复,核心就是封装一个px2px函数并统一用于所有图表配置尺寸。这里提醒一点:如果项目里已经有不少现成的ECharts配置代码,一次全量替换的工作量不小,建议提前定个规范,新图表一律走自适应尺寸函数,旧图表再安排时间切换。不要边开发边零散改,很容易漏掉某个字号,视觉比例就乱了。

5.4 resize监听重复绑定导致页面卡顿

这个问题在大型项目里特别容易发生。每个图表组件都在自己的onMounted里挂window resize监听,十几个图表就绑了十几个监听函数,每次窗口缩放或者切换显示器分辨率,所有监听全部触发,会导致明显的卡顿和页面闪烁。

我现在的做法是做一个全局的resize派发器,或者用代码层面去重。简单方案是封装一个useChartResize的Hook,内部维护一个ECharts实例数组,只在全局注册一次resize监听,统一遍历数组调用所有实例的resize方法。组件卸载时把实例从数组里移除。这样无论页面里有多少图表,全局只会有一个resize监听,性能开销非常小。

5.5 vite build打包后大屏白屏

大屏项目打包上线后白屏,大部分时候不是自适应方案的问题,而是vite的base路径配置没处理。项目中如果使用了图片、字体等静态资源,默认资源路径是/开头的绝对路径,部署到服务器的子目录下就会找不到资源。

解决办法是在vite.config.ts里配置base: './',让资源路径变成相对路径,这样部署到任意子目录都能正常加载。另外要注意,如果项目里用了window.location.pathname这类逻辑做路由或资源判断,换成相对路径后要重新验证,避免路径拼接出错。这个问题我几乎每次做vite构建部署都会碰到,写出来给同样用vite做数据大屏部署的同学提前避坑。

5.6 常见问题速查表

现象原因解决方案
图表初始化空白容器初始尺寸为0nextTick后初始化,或切tab时再init
tooltip位置偏移transform scale影响坐标tooltip配confine: true或用position回调
图表字体过小ECharts配置px未被pxtorem转换JS侧统一用px2px换算函数
resize后页面卡顿多个图表重复绑定监听全局统一派发resize事件
打包后白屏vite base路径问题配置base: './'
高度方向溢出屏幕宽高比与设计稿不一致scale方案取min比例,或用flex居中留白
字体低于12px被浏览器限制rem缩放比例过大对关键大屏提示最少支持分辨率,或换scale方案

最后说点实际体会

这两套方案我都在真实项目里跑过,给我的感觉是:大屏自适应没有“银弹”,最重要的是先把需求问清楚。投放屏幕是什么分辨率,这个定了,方案基本就定了。如果只是先在本地看看效果,后面再拉到现场接屏,那scale方案的容错性最好,怎么换屏幕内容都不会丢。如果需要长期维护、模块多、交互密集,rem方案虽然前期配置麻烦一点,但后期的可维护性和灵活度确实更香。

我自己现在的默认做法是:直接按keynote大屏的标准场景,优先用scale方案先跑通Demo,因为可以让业务方最快看到完整效果,反馈周期短;等确认了真实的投放环境之后,再根据屏幕比例和交互需求决定要不要切换到rem,或者做局部混合适配。这样既不耽误前期沟通效率,也不会在一开始就背上复杂的适配代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 4:48:35

Android掌纹识别轻量化部署:RandomForest模型实战全解析

掌纹识别这几年在移动端的热度一直在涨&#xff0c;尤其在不方便摘口罩、不方便用指纹的场景下&#xff0c;掌纹作为独立生物特征的优势就体现出来了。它不像人脸那样对光线敏感&#xff0c;也不像指纹那样容易受磨损影响&#xff0c;而且用手机摄像头就能采集&#xff0c;不需…

作者头像 李华
网站建设 2026/9/29 4:48:27

GitHub热门AI工具盘点:10款实用AI工具速览与TaoToken统一接入配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 4:47:26

Hindsight:Chrome取证利器,解析历史记录与SQLite数据

1. Hindsight 是什么&#xff1a;不是我“事后才发现”&#xff0c;而是 Chrome 取证的一把刀先说明一下&#xff0c;这里的 Hindsight 并不是心理学里那个“后见之明”的概念&#xff0c;而是一个开源的数字取证工具。名字叫 Hindsight&#xff0c;我猜作者多少有点自嘲的意思…

作者头像 李华
网站建设 2026/9/29 4:46:29

Android极致签名校验:Java+NDK+Binder四层防御架构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 4:44:48

GPU性能实时监控全攻略:从nvidia-smi到DCGM集群实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 4:44:39

Cadence Virtuoso中VCVS行为级建模:从原理到仿真避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华