移动web开发布局——rem适配布局
目标:
- 使用
rem
单位; - 使用媒体查询基本语法;
- 使用less语法;
- 使用2中rem适配方案;
- 完成示例页面;
前言
之前我们使用flex布局实现移动web开发时,页面基本上是固定的,而且无论是流式布局
还是flex布局
主要都是针对宽度进行的布局;如果想对高度,如布局可以随着屏幕变化,宽、高同时进行等比例缩放,就要用到rem适配布局;
rem基础
rem单位:
rem(root em)是一个相对单位,类似于em,em是父元素字体大小;
不同的是rem的基准是相对html元素的字体大小;
比如,根元素(html)设置font-size:12px;
非根元素设置width:2rem;
换算成px就是24px;
- em:相对父元素,字体大小;
- rem:相对根元素,字体大小;
html{
/* 根元素只有一个 */
font-size:14px;
}
div{
/* 父元素很多 */
font-size:12px;
}
p{
width:10em;
height:10rem;
background:red;
}
所有的基于同一的根元素的font-size设置的rem单位的元素:
最终就可以通过修改html里边的文字大小,来改变页面中所有元素的大小,进行整体控制;
媒体查询
html中设置的font-size如何动态变化;这就要用到媒体查询;
媒体查询(Media Query)是CSS3新语法:
- 使用
@media
可以针对不同媒体类型定义不同样式; - 可以针对不同屏幕尺寸设置不同样式;(重置浏览器大小,会触发浏览器宽高重新渲染)
- 目前针对众多的移动端设备的不同屏幕尺寸,都需要用到多媒体查询;
语法规范
@media mediatype and|not|only (media feature){
css code;
}
- 用@media开头
- mediatype指定媒体类型(如指定打印机)
- all:所有设备
- print:打印机设备
- screen:手机 平板 屏幕(不可省略)
- 关键字
- and: 将多个媒体特性链接(不可省略)
- not :排出某个媒体类型
- only:指定某个特定的媒体类型
- media feature 媒体特性,必须使用小括号包含;
- width:最常用的就是宽度(数字后边 必须跟上单位,如px)
- min-width:最小宽度(数字后边 必须跟上单位,如px)
- max-width:最大宽度(数字后边 必须跟上单位,如px)
示例:
/* 小于等于800px的屏幕 背景色设置为粉色 */
@media screen and (max-width:800px){
body{
background:pink;
}
}
/* 小于等于500px的屏幕 背景色设置为红色 */
@media screen and (max-width:500px){
body{
background:red;
}
}
使用:
- 从大到小、小到大进行设置;(建议从小到大)
- 由于包含等号:对于小于540px的屏幕,屏幕特性
max-width
应该设置为539px
;
一个完整示例:
@media screen and (max-width:539px){
body{
background-color:red;
}
}
/* @media screen and (min-width:539px) and (max-width:969px){ */
/* 从小到大写的话 可以简写(利用媒体查询的层叠性) */
@media screen and (min-width:539px){
body{
background-color:green;
}
}
@media screen and (min-width:970px){
body{
background-color:blue;
}
}
rem + 媒体查询
可以实现不同屏幕尺寸元素大小的动态变化;
*{
margin:0;
padding:0;
}
@media screen and (min-width:320px){
html{
font-size:60px;
}
}
@media screen and (min-width:640px){
html{
font-size:80px;
}
}
.header{
/* rem */
height:1rem;
font-size:.2rem;
/* 文字居中 */
line-height:1rem;
text-align:center;
background:green;
color:#fff;
}
引入资源
可以针对不同的媒体使用不同的样式表;直接在link中判断屏幕的尺寸,然后引入不同的css;
<!-- 上下两个div,宽度小于640px时,纵向展示,否则横向展示 -->
<link ref="stylesheet" media="meidatype and|not|only (media feature)" href="mystyle.css">
less的使用
使用less 着重要使用less提供的计算能力:
比如,一个UI设计的图片高80px,html的font-size设置为50px,那么该图片高就可以设置为
80 / 50rem
;
- 一定注意:less的运算符 左右两侧 必须敲上空格;
- 对于参与运算的数值,如果只有一个有单位,那结果就以这个作为单位;
- 如果参与运算的数 都有各自的单位,那结果就以
第一个
出现的单位作为单位; - 颜色 也可以进行运算:#666-#222;
- 使用小括号可以改变算数运算的优先级;
less编译:
vscode的
easy less
插件,可以完成less文件自动编译css文件的过程;使用时直接使用同名的css文件即可;
rem适配方案
目标:
- 屏幕尺寸变化,界面元素能等比例适配;
方案:
- 不同设备按比例设置html字体大小;
- 页面所有元素都使用rem做尺寸单位;
原理:
- 按照设计稿与设备宽度比例,计算并确定html根标签font-size大小;
- CSS中,设计稿元素的宽高、相对位置等取值,按照同等比例换算为rem单位的值;
实现:
- 技术方案1:
- less + 媒体查询 + rem
- 技术方案2:(更推荐,因为更简单)
- flexible.js(淘宝的库) + rem
技术方案1:less + 媒体查询 + rem
目前一般依据6s屏幕宽750px 为准,出一套基准设计图;具体的方案如下:
- 把屏幕等分为15份(也可以是20份,指定一个等分数即可);
- 750px/15=50px,50px即作为html的字体大小;
- 在适配320px宽的设备时,字体大小就是 320/15 = 21.33px;(这样保证了等比例)
@media screen and (min-width:320px){
html{
font-size:21.33px;
}
}
@media screen and (min-width:750px){
html{
font-size:50px;
}
}
- 一个div的宽高,如果在750px宽的设计稿上是100px,那么转换为rem之后就是 100/50 = 2rem;
- 这样,在320px宽的屏幕上,2rem=42.66px;实现盒子的等比例缩放效果;
div{
width:2rem;
height:2rem;
background:red;
}
common.less:主要屏幕尺寸的媒体查询根元素字体大小设置
// 写在最上边
html{
font-size:50px;
}
// 15份
@num:15;
// 从 小 到 大
@media screen and (min-width:320px){
html{
font-size:320px / @num;
}
}
@media screen and (min-width:360px){
html{
font-size:360px / @num;
}
}
@media screen and (min-width:375px){
html{
font-size:375px / @num;
}
}
@media screen and (min-width:384px){
html{
font-size:384px / @num;
}
}
@media screen and (min-width:400px){
html{
font-size:400px / @num;
}
}
@media screen and (min-width:414px){
html{
font-size:414px / @num;
}
}
@media screen and (min-width:424px){
html{
font-size:424px / @num;
}
}
@media screen and (min-width:480px){
html{
font-size:480px / @num;
}
}
@media screen and (min-width:540px){
html{
font-size:540px / @num;
}
}
@media screen and (min-width:720px){
html{
font-size:720px / @num;
}
}
@media screen and (min-width:750px){
html{
font-size:750px / @num;
}
}
然后在主界面的less中引入common.less:
// 在一个less样式文件中,导入另一个less样式文件
@import "common";
...
主界面less body修改:
@import "common";
body{
min-width:320px;
width:15rem;//要使用rem
margin:0 auto;
line-height:1.5;
font-family:Arial,Helvetica;
background:#FFF;
}
// 顶部固定搜索框
@baseFont:50;
.search-content{
// 固定布局
position:fixed;
top:0;
left:50%;
transform:translateX(-50%);
width:15rem;
height:88rem / @baseFont;//88px 是750设计图中的盒子高度
background:green;
}
rem转换:设置一个margin:10px 11px 12px 13px;
转换成rem单位
margin:10rem / @baseFont 11rem / @baseFont 12rem / @baseFont 13rem / @baseFont ;
技术方案2:flexible.js(淘宝的库) + rem
- 不需要写那么多的媒体查询;
- 依照当前屏幕划分10等份;
- 我们需要做的:
- 依照设计稿,企鹅双ing当前设备html文字的大小(如 750px / 10 = 75px);
- 页面元素的rem值:xxxrem / 75;
- 剩余的flexible.js会处理;
设置好视口->引入公共css之后->还要引入flexible.js->现在对比第一种方案,只需要在less文件中直接写body样式即可:
// 主界面less body修改
body{
min-width:320px;
max-width:750px;//flexible是根据屏幕划分的 所以要设置最大宽度
width:10rem;//要使用rem (10份)
margin:0 auto;
line-height:1.0;
font-family:Arial,Helvetica;
background:#FFF;
}
/* 由于flexible默认是依照 屏幕宽进行的10等分划分,那么最好设置一个上限:如果屏幕超过750px,就按照750px来显示 */
@media screen and (min-width:750px){
html{
font-size:75px !important;
}
}
// 顶部固定搜索框
@baseFont:75;
.search-content{
// 固定布局
position:fixed;
top:0;
left:50%;
transform:translateX(-50%);
width:10rem;
height:88rem / @baseFont;//88px 是750设计图中的盒子高度
background:green;
}
VSCode px转rem插件 cssrem:可以自动完成px到rem单位的转换;
- 使用了这个插件,就可以不用less的计算了;
- 但是cssrem插件默认的html字体大小是16px,需要修改插件的默认设置: cssrem.rootFontSize:75;(Setting->Extensions->cssrem,修改后重启VSCode)
实际页面的各个元素的所有单位全部转换为rem单位,最终实现适应移动web开发的rem适配布局;