移动端布局值rem适配布局
在流式布局和flex布局之中,我们的文字都是固定大小。高度也都是固定的。我们怎么让文字和高度自适应呢?
1. rem基础
rem是一个单位,rem(root rem)是一个相对单位,类似于em em是父亲元素字体大小
不同的是rem的基准是相对于html元素(根元素)的字体大小
比如 根元素(html) 设置font-size=12px 非根元素设置width:2rem,则换成px表示的就是24px。
理解em单位和rem单位:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>理解rem单位</title> <style> html { font-size: 14px; } div { font-size: 12px; } p { /* em是父元素的字体大小 所以 width 是 120px height 是120px width: 10em; height: 10em; */ /* rem的基准是HTML元素的字体大小 所以width是 140px height 是 140px */ width: 10rem; height: 10rem; background-color: pink; } </style> </head> <body> <div> <p></p> </div> </body> </html>
rem的优点:
可以通过修改html里面的文字大小来改变页面中的元素的大小。
可以实现对页面中元素大小的整体控制。
2. 媒体查询
2.1 什么是媒体查询
媒体查询(Media Query) 是CSS3新语法。
作用:
使用@media 查询,可以针对不同的媒体类型定义不同的样式.
@media 可以针对不同的屏幕尺寸设置不同的样式。
当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面.
目前针对很多苹果手机 安卓手机 平板等设备都用的到媒体查询。
2.2 语法规范
@media mediatype and|not|only(media feature) {
CSS-Code:
}
用@media开头,注意@符号.
mediatype 媒体类型
关键字 and not only
media feature 媒体特性 必须有小伙好包含。
关键字:
and 可以将多个媒体特性连接到一起 相当于且的意思
not 排除某个媒体类型 相当于非的意思 可以省略
only 指定某个特定的媒体类型 可以省略
媒体特性:
每种媒体类型都有各自不同的特性,根据不同媒体类型的媒体特性设置不同的展示风格,我们了解一下我们常用的。
width:定义输出设备中页面可见区域的宽度
min-width:定义输出设备中页面最小的可见区域宽度
max-width: 定义输出设备中页面最大可见区域宽度.
代码示例:
屏幕宽度小于等于500 div是宽高140px的盒子 小于等于800 是宽高160px的盒子
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>媒体查询</title> <style> /* mediatype 查询类型*/ /* mediatype all 用于所有设备 */ /* mediatype print 用于打印机和打印预览 */ /* scree 用于电脑屏幕 平板电脑 智能手机等 */ /* 这句话的意思就是 在屏幕上 并且最大的宽度是800px 设置我们想要的样式 max-width:800px 小于等于800px*/ @media scree and (max-width: 800px) { html { font-size: 16px; } } /* 可以根据不同的尺寸 改变不同的样式 */ @media screen and (max-width: 600px) { html { font-size: 14px; } } div { width: 10rem; height: 10rem; background-color: pink; } </style> </head> <body> <div></div> </body> </html>
案例 根据页面宽度改变背景颜色:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>根据页面宽度改变背景颜色</title> <style> /* 1. 媒体查询一般按照从大到小 或者 从小到大的顺序来 一般采用从小到大*/ /* 2. 小于540px 页面的背景色为蓝色*/ @media screen and (max-width: 539px) { body { background-color: blue; } } /* 3. 540-970 我们的页面颜色变为绿色 */ /* @media screen and (min-width: 540px) and (max-width: 969px) { body { background-color: green; } } */ /* 之所以省略 是因为下面>=970时 会层叠掉 >= 540px的时候 */ @media screen and (min-width: 540px) { body { background-color: green; } } /* 970以上 变为红色 */ @media screen and (min-width: 970px) { body { background-color: red; } } /* 从大到小 */ /* 大于等于970px */ /* @media screen and (min-width: 970px) { body { background-color: red; } } */ /* 大于等于540 */ /* @media screen and (max-width: 969px) { body { background-color: green; } } */ /* 小于等于 539 */ /* @media screen and (max-width: 539px) { body { background-color: blue; } } */ </style> </head> <body> </body> </html>
2.3 媒体查询+rem实现元素动态大小变化
rem单位是跟着html来走的,有了rem页面元素可以设置不同大小尺寸
媒体查询可以根据不同设备宽度来修改样式
媒体查询+rem 就可以实现不同的设备宽度 实现页面元素大小的动态变化。
代码示例:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>媒体查询+rem</title> <style> * { margin: 0; padding: 0; } @media screen and (min-width: 320px) { html { font-size: 50px; } } @media screen and (min-width: 640px) { html { font-size: 100px; } } .top { height: 1rem; line-height: 1rem; font-size: 0.5rem; background-color: green; color: #fff; text-align: center; } </style> </head> <body> <div class="top"> 购物车 </div> </body> </html>
2.4 媒体查询引入资源
当样式比较繁多 我们可以针对不同的媒体使用不同的stylessheets(样式表)
原理:直接在link中判断设备的尺寸 然后引用不同的CSS文件。
引入资源的语法规范
<link rel="stylesheet" media="mediatype and|not|only (media feature)" href="">
代码示例:
css部分
div {
float: left;
width: 100%;
height: 100px;
}
div:nth-child(1) {
background-color: pink;
}
div:nth-child(2) {
background-color: purple;
}
640px
div {
float: left;
width: 50%;
height: 100px;
}
div:nth-child(1) {
background-color: pink;
}
div:nth-child(2) {
background-color: purple;
}
html部分
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>rem引入资源</title> <!-- 当我们屏幕大于等于640px 的时候 我们让div 一行显示两个 --> <!-- 当我们屏幕小于等于640px 的时候 我们让div 一行显示一个 --> <!-- 引入资源语法规范: <link rel="stylesheet" media="mediatype and|not|only (media feature)" href=""> --> <!-- 媒体查询最好的方法是从小到大 --> <link rel="stylesheet" media="screen and (min-width: 320px)" href="../CSS/320.css"> <link rel="stylesheet" media="screen and (min-width: 640px)" href="../CSS/great640.css"> <style> </style> </head> <body> <div>1</div> <div>2</div> </body> </html>
3 Less基础
CSS 是一门非程序语言,没有变量 函数 SCOPE(作用域)等概念.
CSS需要书写大量看似没有逻辑的代码 CSS冗余度比较高
不方便维护及扩展 不利于复用
CSS没有很好的计算能力
非前端开发工程师来讲 往往会因为缺少CSS编写经验而很难写出组织良好且易于维护的CSS代码
3.1 Less介绍
Less(Leaner Style Sheets的缩写) 是一门CSS扩展语言 也成为CSS的预处理器。
做为CSS的一种形式的扩展 他并没有减少CSS的功能,而是在现有CSS的语法上,为CSS加入程序式语言的特性。
它在CSS的语法基础上 引入了变量 Mixin(混入),运算以及函数等功能,大大滴简化了CSS的编写,并且降低了CSS的维护成本,
Less的中文网址: http://lesscss.cn/
比较常见的CSS预处理器: Sass Less Stylus
3.2 Less安装
windows 安装步骤:
(1) 安装 nodejs 可选择版本(8.0) 网址: http://nodejs.cn/download/
(2) 检查是否安装成功,使用cmd命令 (win10 是 window+f 打开运行输入cmd) --输入 "node -v" 查看版本即可
(3)基于nodejs在线安装Less 使用cmd命令 "npm-install -g less"
(4) 检查是否安装成功 使用cmd 命令 lessc -v 查看版本即可
mac 安装步骤
http://www.kejunfeng.com/2018/08/18/mac-webstorm-nodejs-less.html
3.3 Less的使用
3.3.1 less变量
变量是指没有固定的值 可以改变的 因为我们CSS中的一些颜色和数值等经常使用。
语法:
@变量:值;
命名规范:
必须有@为前缀
不能包含特殊字符
不能以数字为开头
大小写敏感
代码示例:
文件名为start.less
//定义了一个字体为14px的变量
@font:14px;
// 定义一个粉色的变量
@color:pink;
body {
background-color: @color;
}
div {
color: @color;
font-size: @font;
}
3.3.2 less编译
本质上,Less包含一套自定义的语法及一个解析器。用户根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的CSS文件。
所以我们需要把我们的less文件,编译生成对应的css文件 这样我们的html页面才能使用.
我使用的是VSCode编译器 其中一个插件 EasyLess可以把less文件编译为css文件。
安装插件完毕后,重新加载VSCode 只要保存一下less文件 就会自动生成css文件。
自动生成了一个css文件。我们在less文件中修改变量,保存后,生成的css文件也会有相应的改变。我们可以在html页面中直接使用该css文件。
代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="../Less/start.css"> </head> <body> <div></div> </body> </html>
3.3.3 less嵌套
代码示例
html代码:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>less嵌套</title> <link rel="stylesheet" href="../Less/next.css"> </head> <body> <div class="header"> <a href="#">我是链接</a> </div> <div class="nav"> <div class="logo">沈丘县</div> </div> </body> </html>
less代码:
后代可以直接写在父亲的里面
.header {
width: 200px;
height: 200px;
background-color: pink;
// less嵌套 子元素的样式 直接写在父亲里面
a {
color: red;
}
}
.nav {
.logo {
color: green;
}
}
编译而成的css文件:
.header {
width: 200px;
height: 200px;
background-color: pink;
}
.header a {
color: red;
}
.nav .logo {
color: green;
}
如果遇见(交集|伪类|伪元素选择器)
内层选择器的前面没有&符号 则它被解析为父选择器的后代
如果有&符号,他就被解析为父元素自身或父元素的伪类。
代码示例:
less文件
.header {
width: 200px;
height: 200px;
background-color: pink;
// less嵌套 子元素的样式 直接写在父亲里面
a {
color: red;
// 2.如果有伪类 交集选择器 伪元素选择器 我们内层选择器的前面需要加&符号
&:hover {
color: blue;
}
}
}
.nav {
// 2.如果有伪类 交集选择器 伪元素选择器 我们内层选择器的前面需要加&符号
&::before {
content: "你好";
}
.logo {
color: green;
}
}
生成的CSS文件
.header {
width: 200px;
height: 200px;
background-color: pink;
}
.header a {
color: red;
}
.header a:hover {
color: blue;
}
.nav .logo {
color: green;
}
3.3.4 less运算
任何数字 颜色 或者 变量都是可以参与运算的。就是Less提供了 加(+) 减(-) 乘(*) 除(/) 算术运算。
注意
运算符中间左右有个空格隔开
对于两个不同的单位值之间的运算 运算结果的值取第一个值的单位
如果两个值之间只有一个值有单位 则运算结果就取该单位。
代码示例:
@border:5px + 5; div { width: 200px - 50; height: 200px * 2; border: @border solid red; } img { width: 82 / 50rem; height: 82 / 50rem; }
编译后的css文件
div { width: 150px; height: 400px; border: 10px solid red; } img { width: 1.64rem; height: 1.64rem; }
4 rem的适配方案
1. 让一些不能等比自适应的元素,达到当设备尺寸放生改变的时候,等比例适配当前设备。
2.使用媒体查询根据不同设备按比例设置html的字体大小,然后页面元素使用rem做尺寸单位,当html字体大小变化
元素的尺寸也会发生变化。从而达到等比例缩放适配。
4.1 rem实际开发适配方案
1.按照设计稿与设备宽度的比例,动态计算并设置html根标签的font-size大小.(媒体查询)
2.CSS中 设计稿元素的宽 高 相对位置等取值,按照同等比例换算为rem为单位的值。
4.2 rem适配方案技术使用
技术方案1: less 媒体查询 rem
技术方案2: flexible.js rem (推荐使用)
总结:
两种方案都存在 但是方案二更简单。但是现阶段还没学习到js代码。
那么我们怎么动态的设置html标签font-size的大小呢。
(1) 假设设计稿是750px
(2) 假设我们把整个屏幕划分成15等份(划分标准不一 可以是20份也可以是10等份)
(3) 每一份作为html的字体大小 这里就是 750 / 15 = 50px
(4) 那么在320px设备的时候 字体的大小为 320 / 15 就是21.33px
(5) 用我们页面元素的大小除以不同的html字体大小会发现他们的比例还是相同的。
(6) 比如我们以750px为标准设计稿
(7) 一个100*100像素的页面元素在750px屏幕下 就是100/50转换成rem就是2rem*2rem 比例是1:1
(8) 320屏幕下 html字体大小为21.33px 则2rem = 42.66px 此时宽和高都是42.66 但是宽高比是1:1
(9) 但是已经能实现不同屏幕下 页面元素盒子等比例缩放的效果。
元素大小的取值方法:
公式. 页面元素的rem值 = 页面元素值 (px) / (屏幕宽度 / 划分的份数)
(屏幕宽度 / 划分的份数) 就是html font-size的大小。
或者 页面元素的rem值 = 页面元素值(px) / html font-size的字体大小。
苏宁首页部分:
HTML部分:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <title>苏宁在手 天下我有</title> <link rel="stylesheet" href="../CSS/normalize.css"> <link rel="stylesheet" href="../CSS/index.css"> </head> <body> <!-- 顶部搜索框 --> <div class="search-content"> <a href="" class="classity"></a> <div class="search"> <input type="search" placeholder="厨卫保暖季 每千减百"> </div> <a href="" class="login">登录</a> </div> <!-- banner --> <div class="banner"> <img src="../upload/banner.gif" alt=""> </div> <!-- 广告部分 --> <div class="ad"> <a href="#"> <img src="../upload/ad1.gif" alt=""> </a> <a href="#"> <img src="../upload/ad2.gif" alt=""> </a> <a href="#"> <img src="../upload/ad3.gif" alt=""> </a> </div> <!-- nav 模块 --> <nav> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> <a href="#"> <img src="../upload/nav1.png" alt=""> <span>爆款手机</span> </a> </nav> </body> </html>
Less部分:
common.less
// 设置常见的屏幕尺寸 修改里面的html文字大小
a {
text-decoration: none;
}
// 一定要写到最上面
html {
font-size: 50px;
}
// 我们此次定义的划分的份数 为 15
@no: 15;
// 320
@media screen and (min-width: 320px) {
html {
font-size: 320px / @no;
}
}
// 360
@media screen and (min-width: 360px) {
html {
font-size: 360px / @no;
}
}
// 375 iphone 678
@media screen and (min-width: 375px) {
html {
font-size: 375px / @no;
}
}
// 384
@media screen and (min-width: 384px) {
html {
font-size: 384px / @no;
}
}
// 400
@media screen and (min-width: 400px) {
html {
font-size: 400px / @no;
}
}
// 414
@media screen and (min-width: 414px) {
html {
font-size: 414px / @no;
}
}
// 424
@media screen and (min-width: 424px) {
html {
font-size: 424px / @no;
}
}
// 480
@media screen and (min-width: 480px) {
html {
font-size: 480px / @no;
}
}
// 540
@media screen and (min-width: 540px) {
html {
font-size: 540px / @no;
}
}
// 720
@media screen and (min-width: 720px) {
html {
font-size: 720px / @no;
}
}
// 750
@media screen and (min-width: 750px) {
html {
font-size: 750px / @no;
}
}
index.less
// 首页的样式less文件
@import "common.css";
// @import 导入的意思 可以把一个样式文件导入到另外一个样式文件里面
// link 是把一个 样式文件引入到 html页面里面
body {
min-width: 320px;
width: 15rem;
margin: 0 auto;
font-family: Arial,Helvetica;
background-color: #F2F2F2;
}
// 页面元素rem计算公式: 页面元素的px / html 字体大小 50
// search-content
@baseFont: 50;
.search-content {
display: flex;
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 15rem;
height: 88rem / @baseFont;
background-color:#FFC001;
.classify {
width: 44rem / @baseFont;
height: 70rem / @baseFont;
margin: 11rem / @baseFont 25rem / @baseFont 7rem / @baseFont 24rem / @baseFont;
background: url(../images/classify.png) no-repeat;
// 背景缩放
background-size: 44rem / @baseFont 70rem / @baseFont;
}
.search {
flex: 1;
input {
outline: none;
width: 100%;
border: 0;
height: 66rem / @baseFont;
border-radius: 33rem / @baseFont;
background-color:#FFF2CC;
margin-top: 12rem / @baseFont;
font-size: 25rem / @baseFont;
padding-left: 55rem / @baseFont;
color: #757575;
}
}
.login {
width: 75rem / @baseFont;
height: 70rem / @baseFont;
line-height: 70rem / @baseFont;
margin: 10rem / @baseFont;
font-size: 25rem / @baseFont;
text-align: center;
color: #fff;
}
}
// banner
.banner {
width: 750rem / @baseFont;
height: 368rem / @baseFont;
img {
width: 100%;
height: 100%;
}
}
// ad
.ad {
display: flex;
a {
flex: 1;
img {
width: 100%;
}
}
}
// nav
nav {
width: 750rem / @baseFont;
a {
float: left;
width: 150rem / @baseFont;
height: 140rem / @baseFont;
text-align: center;
overflow: hidden;
img {
display: block;
width: 82rem / @baseFont;
height: 82rem / @baseFont;
// margin: 10rem / @baseFont auto 0;
}
span {
font-size: 25rem / @baseFont;
color: #333;
}
}
}
rem 适配方案2: flexible.js (推荐使用)
淘宝团队推出的高校移动端适配库 我们不再需要些不同屏幕的媒体查询 因为里面的js做了处理.
原理是:把当前设备划分成10等份 但是不同的设备下比例还是一致的。
我们要做的 就是确定好我们当前设备的html文字大小就可以了。
比如 当前设计稿是750px 那么我们只需要把html文字设置为75px (750px / 10)就可以。
剩余的 交给 flexible.js来计算。
flexible.js GitHub地址:https://github.com/amfe/lib-flexible
那么我们不使用Less 怎么进行px和人的转换呢? 在此我使用的是VSCode编辑器。可以使用cssrem这个插件进行转换。
这个插件会把我们书写的px值 自动转换为rem。
但是 这个插件 默认16px为1rem。所以我们需要修改一些默认值。
方法:
点击VSCode下方的这只按钮->弹框选中设置->搜索cssRoot 修改为我们项目需要的默认值.
使用适配方案2制作苏宁移动端首页搜索框布局:
html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0"> <title>苏宁在手 天下我有</title> <link rel="stylesheet" href="../CSS/normalize.css"> <link rel="stylesheet" href="../CSS/index.css"> <!-- 引入flexiable.js文件 --> <script src="../js/flexiable.js"></script> </head> <body> <div class="search-content"> <a href="#" class="classify"></a> <div class="search"> <form action=""> <input type="search" placeholder="输入你想搜索的商品"> </form> </div> <a href="#" class="login">登录</a> </div> </body> </html>
注意引入了淘宝的flexiable.js
css部分:
body {
min-width: 320px;
max-width: 750px;
width: 10rem;
margin: 0 auto;
line-height: 1.5;
font-family: Arial, Helvetica;
background: #f2f2f2;
}
@media screen and (min-width:750px) {
html {
font-size: 75px !important;
}
}
.search-content {
display: flex;
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 10rem;
height: 1.173333rem;
background-color: #ffc001;
align-items: center;
}
.classify {
width: .586667rem;
height: .933333rem;
background: url(../images/classify.png) no-repeat;
background-size: .586667rem .933333rem;
margin: 0 .133333rem;
}
.search {
flex: 1;
height: 100%;
}
.search input {
border: none;
outline: none;
width: 100%;
height: .88rem;
border-radius: .44rem;
padding-left: .733333rem;
color: #757575;
font-size: .333333rem;
margin-top: .1333333rem;
}
.login {
width: 1rem;
height: .933333rem;
margin: .133333rem;
color: #fff;
text-align: center;
line-height: .933333rem;
font-size: .333333rem;
text-decoration: none;
}
省去了less 文件 还是很方便的。