前言
以前做移动端项目布局都是rem来做的,但rem需要在页面中引入js,根据设备的宽度来修改根节点<html>标签的font-size样式属性(相对长度单位。相对于根元素(即html元素),通过font-size 来计算值的倍数)才能配使用!
rem单位
下面是以前rem适配的js代码:
(function(doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth;
if(!clientWidth) {
return false;
}
// 750 是按照PSD设计稿以iphone6、7、8来设定的!
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if(!doc.addEventListener) {
return false;
}
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
上面的适配缩放是以750px的宽度来设定的(一般情况下UI在设计移动端APP、Web、小程序等都是以iPhone6/7的尺寸为例的)。
所以当我们在写css样式时就要缩小倍数来使用rem了,比如在宽度为750px的PSD设计稿的中某个标题的文字大小是16px时,此是在css样式中就要写成:font-size: 0.16rem;某个图片的宽是320px,高是240px,圆角是8px时在css样式中就要写成:img{ width:32rem; height:24rem; border-radius: 0.08rem;}
使用上面的写法,可以在不同大小宽高的移动设备中适配了,这样写虽然可以,但还有更好的适配方案,比如可以通过视口单位来做。
视口单位(vw、vh)
先来看看网上对视口的解释:在PC端,视口指的是在桌面端,指的是浏览器的可视区域;而在移动端,它涉及3个视口:
- Layout Viewport(布局视口)
- Visual Viewport(视觉视口)
- Ideal Viewport(理想视口)
视口单位中的《视口》,PC端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport。
CSS3规范,视口单位主要包括以下4个:
单位 | 说明 |
vw | 1vw = 视口宽度的1%,100vw = 视口宽度 |
vh | 1vh = 视口高度的1%,100vh = 视口高度 |
vmin | 选取vw和vh中最小的那个 |
vmax | 选取vw和vh中最大的那个 |
vw 与 vh:相对于视口的高度和宽度,而不是父元素的(CSS百分比是相对于包含它的最近的父元素的高度和宽度),如果给一个DOM元素设置100vw 的宽,和 100vh 的高,那么它将完全覆盖整个视口。
1vw = 视口宽度的1%,1vh = 视口高度的1%。
比如:
# 浏览器高度950px,宽度为1920px,
1vh = 950 / 100 = 9.5 px,1vw = 1920 / 100 = 19.2 px
vmax相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax。
vmin相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin。
比如:
浏览器视口尺寸为370px,那么 1vw = 370px * 1% = 6.5px(浏览器会四舍五入向上取7)
浏览器兼容性:
1、PC端
- Chrome:自 26 版起就完美支持(2013年2月)
- Firefox:自 19 版起就完美支持(2013年1月)
- Safari:自 6.1 版起就完美支持(2013年10月)
- Opera:自 15 版起就完美支持(2013年7月)
- IE:自 IE10 起(包括 Edge)到现在还只是部分支持(不支持 vmax,同时 vm 代替 vmin)
2、移动端
- Android:自 4.4 版起就完美支持(2013年12月)
- iOS:自 iOS8 版起就完美支持(2014年9月)
新的视口单位
vw和vh虽然好用,但在移动设备上有时候,视口大小会受到浏览器的工具栏、状态栏等控件的存在或不存在的影响。
比如在微信浏览器中,下面有前进、后通控件时,如果将高度设为 100vh 的元素将从视口中溢出。
虽然视口大小可以更改,但 vw 和 vh 大小不会更改。因此,大小为 100vh 的元素将从视口中溢出。向下滚动时,这些动态工具栏将缩回。在此状态下,大小为 100vh 的元素将覆盖整个视口。
为解决这个问题,在 CSS 中还指定了视口的各种状态,目前在 Chrome108 中发布,加入了已经支持的还有 Safari 和 Firefox浏览器等。
- 小视口:这些动态工具栏是展开
- 大视口:这些动态工具栏是缩回
表示大视口的单位以 lv 为前缀单位: lvw、lvh、lvi、lvb、lvmin 和 lvmax。
表示小视口的单位以 sv 为前缀单位: svw、svh、svi、svb、svmin 和 svmax。
除非调整视口本身的大小,否则这些视口百分比单位的大小是固定的(因此是稳定的)。
除了上面的大视口和小视口,还有一个动态视口,它动态考虑了动态工具栏。
- 动态视口:
- 展开动态工具栏时,动态视口等于小视口的大小。
- 当动态工具栏缩回时,动态视口等于大视口的大小
表示动态视口的单位以 dv 为前缀单位:dvw、dvh、dvi、dvb、dvmin 和 dvmax。
使用场景:
在实际工作中情况中,如果仅使用vw作为CSS单位,vh可在某些页面要求宽和高都为100%时,就可以使用100vw去代替100%使用。
如:
{width:100%; height:100%;}
使用vw, vh改写为:
{width: 100vw; height: 100vh;}
会好很多,特别是在如今流行的曲面屏手机中更应该如此。
这里以Vue-cli3脚手架为基础,在vue中使用 sass 和 vw/wh来搭建一个移动端Web项目的布局
在Vue-cli 3中提供了两种方式集成sass / scss(当然,如果习惯less的写法也是一样的做法)
1、创建项目并添加sass
$ vue create vuedemo
? Please pick a preset: (Use arrow keys)
> default (babel, eslint)
Manually select features
移动上下键选择“Manually select features”:表示手动选择创建项目的特性。
显示如下:
? Check the features needed for your project: (Press <space> to select, <a> to t
oggle all, <i> to invert selection)
>( ) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
(*) CSS Pre-processors
( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
移动上下键在CSS Pre-processors,按提示点击空格键选择CSS-processors。
显示如下:
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> SCSS/SASS
LESS
Stylus
选择第一个SCSS/SASS作为我们的CSS预处理器。
完成后项目会帮我们安装sass-loader node-sass。
2、手动安装
如果在创建项目没有选择CSS 预处理器,我们也可以手动安装sass-loader node-sass来集成scss。
npm install -D sass-loader node-sass
3、使用实例:
安装完成后,只需要在style标签中指定lang为scss即可:
<style lang="scss" scoped>
$color = red;
.box{
color: $color;
}
</style>
在实际工作中,有的一常用的初始化样式、颜色、字体等都是整个项目是要用到的,如果每个页面都去引用一次就在繁琐了,所以我们可以把常用的必用的放在一个全局的scss样式方件中,一次引用,全局使用!
使用Sass全局变量
https://www.cnblogs.com/Mrrabbit/p/11180287.html
创建scss样式文件:(我是放在vue根目录中的src目录下的public目录下【可以自定义】),vue cli会自动使用我们安装的sass-loader作为scss内容的加载器。
global.scss内容如下:
$color: #2656ec;
@function vw($px) {
/*这里是以移动端PSD设计稿 宽为750px,高为1334px为例,所以这里 除以750,以便在使用时,不用去计算倍数, PSD设计稿中的尺寸是多少,我们样式就是多少!!!*/
@return ($px / 750) * 100vw;
}
vue cli是基于webpack构建项目,如果想对sass-loader传递一些配置项,可以在vue.config.js配置。在项目的根目录下如果没有找到vue.config.js,手动创建即可。
Vue官方实例:CSS 相关 | Vue CLI🛠️ Vue.js 开发的标准工具https://cli.vuejs.org/zh/guide/css.html#css-modules
vue.config.js内容如下:
module.exports = {
//解决打包后index.html文件找不到js/css资源问题
baseUrl: './',
//配置sass(css编译工具)
css: {
loaderOptions: {
sass: {
/*
@/ 表示 src/ 的别名, 如要有多个scss可以在 ; 后面在 @import "@/其他.scss";
注:
1、我这个global.scss文件是在src目录下的public目录中(可以自定义)。
2、引入的文件要以.scss为后缀名,不能是sass!!!不然会报错!!!
*/
data: `@import "@/public/global.scss";`
}
}
},
configureWebpack: {
//解决在本地开发联调API是跨域问题
devServer: {
proxy: {
'/Api': {
target:'https://www.easy-mock.com/mock/5d48e8d73dbe173654aeece6/api',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/Api': ''
}
}
}
}
}
};
扩展:
通过使用vw函数方法(不用像rem去计算倍数啦, 在这里我们直接看PSD设计稿中的尺寸是多少,在我们样式表中就是多少!!)
实例代码如下:
<style lang="scss" scoped>
body {
background: #4882ff;
}
.login {
width: 100%;
height: 100vh;
background: #4882ff url(./assets/login-bg.jpg) repeat-y;
background-size: cover;
.btns {
text-align: center;
input {
width: vw(570); /*这里在PSD设计稿中input的宽度就是570px*/
height: vw(92);
border-radius: vw(92);
background: #224bd2;
display: inline-block;
}
button {
display: inline-block;
width: vw(560);
height: vw(88);
color: white;
font-size: vw(36); /*这里在PSD设计稿中字体的大小就是36px*/
border-radius: vw(88);
border: vw(4) solid #cfddfd;
background: linear-gradient(left, #236af4, #2654eb);
}
}
}
</style>