尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Web大屏适配终极方案:vw/vh + flex + clamp() 完美组合

Web大屏适配终极方案:vw/vh + flex + clamp() 完美组合 文章目录前言一、主流大屏适配方案对比1. 媒体查询Media Queries2. Rem适配方案3. 缩放变换Scale4.百分比布局二、新一代适配方案vw/vh flex clamp()方案优势基础方案vw/vh flex1. vw/vh 单位2. Flex 弹性布局3. 核心思想4.实践示例字体使用vh还是vw图片长宽使用vh还是vw总结:5. 工程化中使用scss解决vw/vh与px换算问题终极方案vw/vh flexclamp(示例图表适配三、总结前言在数据可视化、监控中心、展厅大屏等场景中Web 页面需要在各种尺寸的大屏幕上完美展示这给前端开发者带来了不小的挑战。本文将对比主流的大屏适配方案重点介绍一套简单高效的 “vwvhflexclamp ()” 组合方案让你的大屏页面轻松实现无缝适配。一、主流大屏适配方案对比在深入讲解推荐方案之前我们先来看看目前常用的几种大屏适配方案及其优缺点1. 媒体查询Media Queries通过设置多个断点为不同尺寸屏幕编写不同样式。/* 传统媒体查询方式 */.container{width:100%;}media screenand(min-width:1920px){.element{font-size:18px;padding:20px;}}media screenand(max-width:1366px){.element{font-size:14px;padding:15px;}}优点针对性强可在关键断点处做精细化调整缺点需要为多个断点编写多套代码代码冗余维护困难适配成本高断点之间跳跃不够平滑2. Rem适配方案通过 JavaScript 根据屏幕尺寸动态计算根元素 font-size页面元素使用 rem 单位。// 基于屏幕宽度设置rem基准值functionsetRem(){constbaseSize16;// 1rem 16pxconstscaledocument.documentElement.clientWidth/1920;document.documentElement.style.fontSizebaseSize*scalepx;}setRem();window.addEventListener(resize,setRem);/* 使用rem单位 */.container{width:50rem;/* 基于根字体大小计算 */font-size:1rem;}优点适配较为灵活缺点依赖 JavaScript计算逻辑复杂可能出现加载闪烁。只保证宽度适配高度控制不当可能出现滚动条。3. 缩放变换Scale通过 transform: scale () 将整个页面等比缩放。functionsetScale(){consttargetWidth1920;constcurrentWidthdocument.documentElement.clientWidth;constscalecurrentWidth/targetWidth;document.body.style.transformscale(${scale});document.body.style.transformOrigintop left;}优点一次开发适配所有尺寸实现简单缺点可能导致内容模糊字体渲染质量下降缩放后点击区域错位风险图片变形性能消耗大4.百分比布局使用百分比作为长度单位元素尺寸基于父元素计算。.container{width:90%;/* 相对于父容器 */height:80%;}优点简单易用无需额外脚本缺点百分比是相对于父元素的层级嵌套时计算复杂难以精确控制二、新一代适配方案vw/vh flex clamp()这个组合方案汲取了各种方案的优点解决了它们的痛点让我们一步步深入了解。方案优势纯 CSS 实现不依赖 JavaScript自动适应各种屏幕尺寸无需预设断点元素尺寸相对视口动态调整保持整体比例可限制元素尺寸范围避免极端情况下的显示问题开发简单学习成本低基础方案vw/vh flex1. vw/vh 单位vw视口宽度单位和 vh视口高度单位是CSS3引入的相对单位1vw 视口宽度的1%1vh 视口高度的1%/* 直接基于视口尺寸 */.container{width:100vw;/* 全屏宽度 */height:100vh;/* 全屏高度 */padding:2vw;/* 基于宽度的内边距 */font-size:1.5vw;/* 基于宽度的字体大小 */}2. Flex 弹性布局Flex布局轻松实现水平和垂直布局精确控制元素对齐提供强大的空间分配能力.dashboard{display:flex;flex-direction:column;gap:1.5vw;/* 弹性间隙 */}.widget{flex:1;/* 自动填充剩余空间 */min-height:200px;}3. 核心思想vw/vh处理整体布局和主要尺寸其中元素的宽度用vw单位元素的高度用vh单位margin和padding上下方向用vh左右方向用vw。flex处理内部元素排列、间距、空间分配。4.实践示例假设设计稿为1920x1080实现一个导航栏60px高度主体区域横向3段布局左右300px宽度中间占满 大屏页!--html--divclasscontainer!--导航栏--divclassnavigation-bar/div!--主体--divclassmaindivclassleft/divdivclasscenter/divdivclassright/div/div/div/** * css 样式 */.container{width:100vw;height:100vh;display:flex;flex-direction:column;background-color:#f2f2f2;gap:1.5vh;}.navigation-bar{width:100%;height:5.56vh;/**60px */background-color:#fff;}.main{flex:1;/**占满剩余空间**/height:0;width:100%;display:flex;gap:1vw;}.left,.right{width:15.625vw;/**300px */height:100%;background-color:#fff;}.center{flex:1;width:0;height:100%;background-color:#fff;}运行效果从运行效果可以看出无论屏幕尺寸如何变化大屏布局始终保持响应式。继续给页面添加其他元素图片、文字!--html--divclasscontainer!--导航栏--divclassnavigation-bardivclassuser-infoimgclassavatarsrchttps://xxxxxspanclassusername管理员/span/div/div!--主体--divclassmaindivclassleftimgclasspicsrchttps://xxxxxxh4classtitle大屏响应式布局/h4/divdivclasscenter/divdivclassright/div/div/div/** * css 样式 */*{margin:0;padding:0;}.container{width:100vw;height:100vh;display:flex;flex-direction:column;background-color:#f2f2f2;gap:1.5vh;}.navigation-bar{width:100%;height:5.56vh;/**60px */background-color:#fff;}.main{flex:1;/**占满剩余空间**/height:0;width:100%;display:flex;gap:1vw;}.left,.right{width:15.625vw;/**300px */height:100%;background-color:#fff;padding:1.4vh0.78vw;box-sizing:border-box;}.center{flex:1;width:0;height:100%;background-color:#fff;}.user-info{display:flex;align-items:center;height:100%;padding:0.46vh0.52vw;/**5px 10px */box-sizing:border-box;}.avatar{width:3.7vh;/**40px */height:3.7vh;/**40px */border-radius:50%;}.username{margin-left:0.5vw;/**10px */font-size:1.48vh;}.pic{width:10.4vw;height:auto;}.title{font-size:1.04vw;}运行效果注意到上面代码头像尺寸和用户名字体大小用vh单位而风景图和大屏响应式布局文字用vw单位。字体和图片长宽比的处理是关键问题。下面分别探讨字体使用vh还是vw字体的适配单位选择取决于设计意图和父容器的宽高比。如果父容器高度空间小或屏幕高度的变化比宽度更频繁使用vh可以使字体大小随着视口高度变化保持与整体布局高度的比例一致否则使用vw。如果宽高空间都比较大多数情况下字体使用vw单位更合适因为宽度是响应式设计中最常变化的维度。图片长宽使用vh还是vw图片长宽适配单位一样取决于设计需求和父容器的宽高方向空间。如果不要求保持图片或背景长宽比宽度用vw高度用vh如果要求保持图片长宽比跟字体一样取决父容器空间父容器高度方向空间小用vh否则用vw另一个属性设置为“”auto”那么图片的高度会根据原始宽高比自动计算使得图片与整体保持比例一致最大程度防止图片超出父容器。或另一个属性设置具体值结合object-fit属性裁剪图片设置显示效果。//宽度空间有限保持长宽比img{width:50vw;height:auto;}或//高度空间有限保持长宽比img{height:50vh;width:auto;}或//保持长宽比裁剪img{height:50vh;width:70vh;object-fit:cover;}示例中的头像昵称因为导航栏高度只有60px而宽度占满全屏高度空间有限宽度伸缩对布局影响小所以使用vh限制高度允许宽度自动伸缩。而风景图片跟标题父容器.left高度占满空间大宽度方向空间小所以使用vw。总结:对于字体大小和图片尺寸适配使用什么单位没有固定答案应该具体场景具体分析。当父容器高度空间小字体或图片在该方向伸缩容易超出父容器则采用vh否者vw默认使用vw。5. 工程化中使用scss解决vw/vh与px换算问题如上述示例每次从设计稿获取元素尺寸px需要手动计算转换vh单位例如导航栏高度60px转换为vh为60/1080*100≈5.56vh设计稿尺寸1920x1080每次都要这样计算非常麻烦。在工程化项目中可以使用scss 定义全局函数结合calc自动计算。假设设计稿尺寸为1920x10801新建一个全局scss文件/style/responsive.scss//px转vwfunctionw($size){returncalc($size/1920*100vw)}//px转vhfunctionh($size){returncalc($size/1080*100vh)}其中$size为元素从设计稿读出的尺寸px2把responsive.scss注入全局使得函数w、h可以全局使用以vite为例打开vite.config.js添加exportdefaultdefineConfig((mode){constenvloadEnv(mode.mode,process.cwd());return{...............................................,//添加底下代码css:{preprocessorOptions:{scss:{additionalData:use /style/responsive.scss as *,//路径修改为实际},},}3在页面中使用从设计稿读取元素宽高值size单位pxpx转vw使用w(size)函数px转vh使用h(size)函数。style langscssscoped...../**导航栏*/.navigation-bar{width:100%;height:h(60);/**60px */background-color:#fff;}.user-info{display:flex;align-items:center;height:100%;padding:h(5)w(10);/**5px 10px */box-sizing:border-box;}.avatar{width:h(40);/**40px */height:h(40);/**40px */border-radius:50%;}.username{margin-left:w(10);/**10px */font-size:h(16)}.pic{width:w(200);/**200px */height:auto;}.title{font-size:w(20);/**20px */}/style终极方案vw/vh flexclamp(基础方案vw/vh flex基本满足大部分常规比例大屏开发然而在适配一些极端比例屏幕时问题出现了超宽屏幕的尴尬5120×1440/* 在超宽屏上基于宽度的字体变得巨大 */.title{font-size:2.5vw;/* 在5120px宽度下 128px过于夸张 */}/* 内容被过度拉伸 */.content{padding:3vw;/* 左右内边距过大 */}超窄屏幕的窘境1024×768/* 在窄屏上基于宽度的字体变得太小 */.metric{font-size:1.2vw;/* 在1024px宽度下 12.3px难以阅读 */}/* 间距过度压缩 */.grid{gap:0.8vw;/* 间隙只有8px过于拥挤 */}clamp() 函数clamp() 是一个非常实用的 CSS 函数它通过 clamp(min, val, max) 的语法将一个值限制在最小值和最大值之间中间值通常基于视口单位如 vw、vh动态计算当中间值介于最大值最小值之间就取中间值。.title{font-size:clamp(16px,2.5vw,32px);/* 最小16px理想值2.5vw最大32px */}通过 clamp () 的最小和最大值设置避免元素在极端尺寸下变得过大或过小而影响体验。clamp不仅可以限制字体大小还可以应用于元素尺寸自适应、间距与内边距自适应、边框 / 阴影等细节适配等根据实际开发场景灵活应用。示例以上面的实践示例为例保持屏幕宽度缩放屏幕高度模拟超宽屏观察页面布局变化。从运行效果可以看出随着长宽比变小导航栏高度不断变小到极端比例下头像和文字就看不清接下来我们通过clamp优化限制导航栏高度范围使其不会过大或过小导致看不清。/** 导航栏 */.navigation-bar{width:100%;height:clamp(40px,h(60),100px);/**最小40px最大100px,理想h(60) */background-color:#fff;}/** 头像 */.avatar{width:clamp(30px,h(40),80px);/***最小30px最大80px,理想h(40) */height:clamp(30px,h(40),80px);/***最小30px最大80px,理想h(40) */border-radius:50%;}/** 用户名 */.username{margin-left:w(10);/**10px */font-size:clamp(14px,h(16),20px);/***最小14px最大20px,理想h(16) */}运行效果图表适配ECharts 等图表库适配无法通过css一步到位只能通过js动态计算尺寸并监听窗口大小变化事件调用resize()方法重绘图表达到响应式。可以仿造scss h\w函数思路封装宽高2个方向的px转换vh/vw。/utils/responsive.js/** * 设计稿尺寸1920*1080 * param {*} size 转换尺寸单位px * returns *///px转vhexportconsth(size){letwindowHeightdocument.documentElement.clientHeight||document.body.clientHeight;returnsize/1080*windowHeight;};//px转vwexportconstw(size){letwindowWidthdocument.documentElement.clientWidth||document.body.clientWidth;returnsize/1920*windowWidth;};图表使用import{h,w}from/utils/responsive.js//echart配置constoption{grid:{top:h(20),//顶部距离left:w(30),//左侧距离right:w(30),//右侧距离bottom:h(25)//底部距离},xAxis:{type:category,data:[Mon,Tue,Wed,Thu,Fri,Sat,Sun],axisLabel:{fontSize:w(14),//字体大小lineHeight:w(20),//行高}},yAxis:{type:value},series:[{data:[150,230,224,218,135,147,260],type:line}]};三、总结vwvhflexclamp () 的组合方案为 Web 大屏适配提供了一种简单高效的解决方案。它既保留了 vw/vh 单位的自适应特性又通过 flex 布局实现了灵活的元素排列同时利用 clamp () 函数限制了尺寸的极端变化完美平衡了灵活性和可控性。这种方案特别适合数据可视化大屏、监控中心等场景能够在各种尺寸的屏幕上保持良好的视觉效果和用户体验。
返回列表