前端-010:移动端流式布局 flex布局 rem适配布局

236 阅读11分钟

1. 视口

在学习移动端布局之前需要线了解以下什么是视口

视口(viewport)就是浏览器显示页面内容的屏幕区域。 视口可以分为布局视口、视觉视口和理想视口

1.1 布局视口 layout viewport

一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的PC端页面在手机上显示的问题

移动端基本都将这个视口分辨率设置为980px,所以PC上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页

1.2 视觉视口 visual viewport

即: 用户正在看到的网站的区域。注意:是网站的区域

可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度

1.3 理想视口 ideal viewport

为了使网站在移动端有最理想的浏览和阅读宽度而设定,理想视口,对设备来讲,是最理想的视口尺寸,需要手动添写meta视口标签通知浏览器操作

meta视口标签的主要目的:布局视口的宽度应该与理想视口的宽度一致,简单理解就是设备有多宽,我们布局的视口就多宽

1.4 meta视口标签

<meta name="viewport" content="width=device-width,
user-scalable=no, initial-scale=1.0,
maximum-scale=1.0, minimum-scale=1.0">

Snipaste_2022-03-13_19-24-49.jpg

标准的viewport设置要求:

  • 视口宽度和设备保持一致
  • 视口的默认缩放比例1.0
  • 不允许用户自行缩放
  • 最大允许的缩放比例1.0
  • 最小允许的缩放比例1.0

2. 流式布局(百分比布局)

流式布局,也就是百分比布局,也称非固定像素布局。 通过将盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充。 流式布局方式是移动web开发使用的比较常见的布局方式

重要点:

  • max-width 最大宽度 (max-height 最大高度)
  • min-width 最小宽度 (min-height 最小高度)

参考:京东手机端的布局

3. flex布局(重点)

flex布局,也称弹性布局 相比于传统布局有:操作方便,布局极为简单,且在移动端应用很广泛

但是因为是新技术,所以在PC端兼容性较差,如果是PC端页面布局,暂时还是传统布局好

3.1 flex布局原理

flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局

  • 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效
  • flex布局就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式

3.2 flex布局常见父项属性

以下由6个属性是对父元素设置的:

  1. flex-direction:设置主轴的方向
  2. justify-content:设置主轴上的子元素排列方式
  3. flex-wrap:设置子元素是否换行
  4. align-content:设置侧轴上的子元素的排列方式(多行)
  5. align-items:设置侧轴上的子元素排列方式(单行)
  6. flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap

3.2.1 flex-direction 设置主轴的方向

flex-direction 属性决定主轴的方向

主轴与侧轴: 在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有: 行和列、x 轴和y 轴

  • 默认主轴方向就是 x 轴方向,水平向右
  • 默认侧轴方向就是 y 轴方向,水平向下

Snipaste_2022-03-13_22-36-57.jpg

注: 主轴和侧轴是会变化的,就看 flex-direction 设置谁为主轴,剩下的就是侧轴。而我们的子元素是跟着主轴来排列的

属性值有:

Snipaste_2022-03-13_22-39-12.jpg

3.2.2 justify-content 设置主轴上的子元素排列方式

justify-content 属性定义了项目在主轴上的对齐方式

注: 使用这个属性之前一定要确定好主轴是哪个

Snipaste_2022-03-13_22-41-00.jpg

3.2.3 flex-wrap 设置子元素是否换行

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,flex布局中默认是不换行的

  • nowrap : 不换行 默认值
  • wrap : 换行

如果不换行无论添加多少盒子,都是在主轴直线上排列的

3.2.4 align-items 设置侧轴上的子元素排列方式(单行 )

align-items 属性是控制子项在侧轴(默认是y轴)上的排列方式 在子项为单项(单行)的时候使用

属性值:

  • flex-atart : 从上到下(默认值)
  • flex-end :从下到上
  • center : 挤到一起居中(垂直居中)
  • strech : 拉伸

3.2.5 align-content 设置侧轴上的子元素的排列方式(多行)

align-content 设置子项在侧轴上的排列方式 并且只能用于子项出现 换行 的情况(多行),在单行下是没有效果的

Snipaste_2022-03-13_22-48-28.jpg

align-content 和 align-items 区别:

  • align-items 适用于单行情况下, 只有上对齐、下对齐、居中和 拉伸
  • align-content 适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、 下对齐、居中、拉伸以及平均分
  • 配剩余空间等属性值

3.2.6 flex-flow

flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性

flex-flow:row wrap;

3.3 flex布局父项常见属性

3.3.1 flex 属性

flex 属性定义子项目分配剩余空间,用flex来表示占多少份数

.item {
flex: <number>; /* default 0 */
}

3.3.2 align-self 控制子项自己在侧轴上的排列方式

align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性

默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch

span:nth-child(2) {
/* 设置自己在侧轴上的排列方式 */
align-self: flex-end;
}

3.3.3 order 属性定义项目的排列顺序

数值越小,排列越靠前,默认为0

.item {
order: <number>;
}

注:和 z-index 不一样

4. rem + 媒体查询 适配布局

rem 适配方案技术使用(市场主流):

  • 方案1: rem + 媒体查询 + less
  • 方案2: flexible.js + rem

方案2: 是淘宝官方推出的技术方案,当然也更加简单没怎么麻烦,但是初学者推荐从方案1开始入手,了解它的实现原理,然后再自己学习方案2更加得心应手

4.1 rem 基础

rem (root em)是一个相对单位,类似于em,em是父元素字体大小

rem的基准是相对于html元素的字体大小

比如: 根元素(html)设置font-size=12px; 非根元素设置width:2rem; 则换成px表示就是24px

rem的优势: 父元素文字大小可能不一致, 但是整个页面只有一个html,可以很好来控制整个页面的元素大小

/* 根html 为 12px */
html {
font-size: 12px;
}
/* 此时 div 的字体大小就是 24px */
div {
font-size: 2rem;
}

4.2 媒体查询

媒体查询(Media Query)是CSS3新语法

  • 使用 @media 查询,可以针对不同的媒体类型定义不同的样式
  • @media 可以针对不同的屏幕尺寸设置不同的样式
  • 当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面

语法规范:

@media mediatype and|not|only (media feature) {
CSS-Code;
}
  • 用 @media 开头 注意@符号
  • mediatype 媒体类型
  • 关键字 and not only
  • media feature 媒体特性 必须有小括号包含

mediatype 查询类型:

将不同的终端设备划分成不同的类型,称为媒体类型

Snipaste_2022-03-14_23-09-26.jpg

关键字:

关键字是将媒体类型或多个媒体特性连接到一起做为媒体查询的条件

  • and:可以将多个媒体特性连接到一起,相当于“且”的意思。
  • not:排除某个媒体类型,相当于“非”的意思,可以省略。
  • only:指定某个特定的媒体类型,可以省略

媒体特性:

每种媒体类型都具体各自不同的特性,根据不同媒体类型的媒体特性设置不同的展示风格

注: 他们要加小括号包含

Snipaste_2022-03-14_23-12-30.jpg

注意: 为了防止混乱,媒体查询我们要按照从小到大或者从大到小的顺序来写,但是我们最喜欢的还是从小到大来写,这样代码更简洁

4.3 媒体查询+rem实现元素动态大小变化

  • rem单位是跟着html来走的,有了rem页面元素可以设置不同大小尺寸
  • 媒体查询可以根据不同设备宽度来修改样式
  • 媒体查询+rem 就可以实现不同设备宽度,实现页面元素大小的动态变化

4.4 Less 基础

4.4.1 CSS 弊端

CSS 是一门非程序式语言,没有变量、函数、SCOPE(作用域)等概念

  • CSS 需要书写大量看似没有逻辑的代码,CSS 冗余度是比较高的
  • 不方便维护及扩展,不利于复用
  • CSS 没有很好的计算能力
  • 非前端开发工程师来讲,往往会因为缺少 CSS 编写经验而很难写出组织良好且易于维护的 CSS 代码项目

Less (Leaner Style Sheets 的缩写) 是一门 CSS 扩展语言,也成为CSS预处理器。做为 CSS 的一种形式的扩展,它并没有减少 CSS 的功能,而是在现有的 CSS 语法上,为CSS加入程序式语言的特性

在 CSS 的语法基础之上,引入了变量,Mixin(混入),运算以及函数等功能,大大简化了 CSS 的编写,并且降低了 CSS 的维护成本,就像它的名称所说的那样,Less 可以让我们用更少的代码做更多的事情

Less中文网址: lesscss.cn/

4.4.2 Less 变量:

变量是指没有固定的值,可以改变的。因为我们CSS中的一些颜色和数值等经常使用

@变量名:值;
如:
@color: pink;

变量命名规范:

  • 必须有@为前缀
  • 不能包含特殊字符
  • 不能以数字开头
  • 大小写敏感

变量使用规范:

//直接使用
body{
color:@color;
}
a:hover{
color:@color;
}

4.4.3 Less 编译

本质上,Less 包含一套自定义的语法及一个解析器,用户根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 CSS 文件

所以需要把less文件,编译生成为css文件,这样html页面才能使用

vocode Less 插件:

Easy LESS 插件用来把less文件编译为css文件,安装完毕插件,重新加载下 vscode。只要保存一下Less文件,会自动生成CSS文件

Snipaste_2022-03-14_23-42-27.jpg

4.4.4 Less 嵌套

经常用到选择器的嵌套:

#header .logo {
width: 300px;
}

/* Less 嵌套写法 */
#header {
.logo {
width: 300px;
}
}

当遇见 (交集|伪类|伪元素选择器):

  • 内层选择器的前面没有 & 符号,则它被解析为父选择器的后代
  • 如果有 & 符号,它就被解析为父元素自身或父元素的伪类
a:hover{
color:red;
}

/* Less 嵌套写法 */
a{
&:hover{
color:red;
}
}

4.4.5 Less 运算

任何数字、颜色或者变量都可以参与运算。就是Less提供了加(+)、减(-)、乘(*)、除(/)算术运算

/*Less 里面写*/
@witdh: 10px + 5;
div {
border: @witdh solid red;
}
/*生成的css*/
div {
border: 15px solid red;
}
/*Less 甚至还可以这样 */
width: (@width + 5) * 2;

注意:

  • 乘号(*)和除号(/)的写法
  • 运算符中间左右有个空格隔开 1px + 5
  • 对于两个不同的单位的值之间的运算,运算结果的值取第一个值的单位
  • 如果两个值之间只有一个值有单位,则运算结果就取该单位

4.5 rem 适配方案过程:

动态设置 html 标签 font-size 大小

  1. 假设设计稿是750px
  2. 假设我们把整个屏幕划分为15等份(划分标准不一可以是20份也可以是10等份)
  3. 每一份作为html字体大小,这里就是50px
  4. 那么在320px设备的时候,字体大小为320/15 就是 21.33px
  5. 用我们页面元素的大小 除以不同的 html 字体大小会发现他们比例还是相同的
  6. 比如我们以 750为标准设计稿
  7. 一个100*100像素的页面元素 在 750屏幕下, 就是 100 / 50 转换为rem 是 2rem * 2 rem 比例是 1比1
  8. 320屏幕下, html 字体大小为 21.33 则 2rem = 42.66px 此时宽和高都是 42.66 但是 宽和高的比例还是 1比1
  9. 但是已经能实现不同屏幕下 页面元素盒子等比例缩放的效果

元素大小取值方法

  • 最后的公式: 页面元素的rem值 = 页面元素值(px) / (屏幕宽度 / 划分的份数)
  • 屏幕宽度/划分的份数 就是 html font-size 的大小
  • 或者: 页面元素的rem值 = 页面元素值(px) / html font-size 字体大小

rem 适配方案总结:

适配的目标: 让一些不能等比自适应的元素,达到当设备尺寸发生改变 的时候,等比例适配当前设备

怎么去达到这个目标: 使用媒体查询根据不同设备按比例设置html的字体大小,然后页面元素使用rem做尺寸单位,当html字体大小变化元素尺寸也会发生变化,从而达到等比缩放的适配