自适应
开发移动端网页时,为了适配分辨率不同的机型,需要让网页根据设备自适应布局,所以得设置meta标签:
1
| <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
如果不设置width=device-width
,设备会按默认的视口宽度(通常是较宽的桌面屏幕)渲染网页,导致网页内容在移动设备上显示不良,出现内容被截断或水平滚动的情况
圣杯布局
圣杯布局是一种两边盒子宽度固定,中间盒子自适应的三栏布局,其中,中间栏放在文档流前面,保证先行渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <template> <div> <header class="header"> <div>left</div> <div>center</div> <div>right</div> </header> </div> </template> <style lang='less'> .header { display: flex; div { height: 50px; line-height: 50px; color: white; text-align: center; } // 两边固定、中间铺满 div:nth-child(1) { width: 100px; background-color: pink; } div:nth-child(2) { flex: 1; background-color: greenyellow; } div:nth-child(3) { width: 100px; background-color: cyan; } } </style>
|
对于小手机而言,这个布局的效果太怪了
![](/img/loading.gif)
相对长度单位
px是固定的绝对长度单位,就像厘米cm一样,不会因为设备屏幕的不同而变化(无法进行自适应)
rem是可变的相对长度单位,根据html的font-size进行缩放,因此可以进行自适应,但需要计算每个屏幕大小所适合的font-size,才能确定布局是否合适
若需计算,可以使用flexible.js库
vw和vh也是相对长度单位,是相对viewport视口的单位,配合meta标签可以直接使用,无需计算:1vw=$1 \over 100$视口宽度;1vh=$1 \over 100$视口高度
百分比%相对于父元素,而vw和vh一定相对于视口
但开发时,根据设计图的px换算vw很麻烦,最好是能自动转换单位,可以用PostCSS编写一个px转vw/vh的插件
PostCSS插件
Vite已经内置了PostCSS,如果没有就自行安装
tsconfig.node.json配置:
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "noImplicitAny": false, "lib": ["ES2015", "DOM"] }, "include": ["vite.config.ts", "plugins/**/*"] }
|
新建plugins文件夹,编写/plugins/postcss-px-to-vw.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import { Options } from 'element-plus' import { Plugin } from 'postcss'
interface Options { viewportWidth?: number }
const Options: Options = { viewportWidth: 375 }
export const PostCssPxToVW = (options: Options = Options): Plugin => { const opt = Object.assign({}, Options, options) return { postcssPlugin: 'postcss-px-to-viewport', Declaration(node) { if(node.value.includes('px')) { const num = parseFloat(node.value) node.value = `${((num/opt.viewportWidth)*100).toFixed(2)}vw` console.log(node.prop, node.value) } } } }
|
在vite.config.js引入postcss插件:
1 2 3 4 5 6
| plugins: [...], css: { postcss: { plugins: [PostCssPxToVW()] } }
|
这样一来效果就好多了,布局在各种尺寸都会呈现差不多的效果:
![](/img/loading.gif)
全局样式切换
其实就是所谓的“主题”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <template> <div> <header class="header"> <div>left</div> <div>center</div> <div>right</div> </header> <!-- 一堆用于切换样式的按钮 --> <div> <button @click="change(36)">大</button> <button @click="change(24)">中</button> <button @click="change(14)">小</button> </div> </div> </template> <script setup lang='ts'> // import { useCssVar } from '@vueuse/core'
const change = (num: number)=> { // 1.可以使用VueUse库,具有切换css变量的方法 // const size = useCssVar('--size') // size.value = num + 'px'
// 2.或者不用库,使用原生方法 console.log(document.documentElement.style.getPropertyValue('--size')) document.documentElement.style.setProperty('--size', num + 'px')
// 如果需要记忆用户的样式设定,可以使用localstorage存储 // 用户进入/刷新时,若storage存有样式设定,则更换样式;否则使用默认样式 }
</script> <style lang='less'> // 在:root中定义css变量,作用于全局(挂载于html标签) // 想要动态切换全局字体大小,使用css变量即可 // 只要这个变量的值改变,全局相关的样式都会改变 :root { --size: 14px } .header { display: flex; div { height: 50px; line-height: 50px; color: black; text-align: center; // 记得使用css变量 font-size: var(--size); } // ......省略 } </style>
|
当点击任意按钮时,文字的大小就会随之变化
![](/img/loading.gif)
本站的自适应播放器也使用了全局样式切换,打开控制台一探究竟吧(