跳转目录🚀
篇章 | 知识点 |
---|---|
CSS进阶之形变与动画 (一) | transform、垂直居中总结、transition动画、animation动画、vertical-align |
CSS进阶之预处理语言之less (二) | Easy less插件、认识less、注释、计算方式、嵌套、变量的定义导入less文件、从less导出css样式的路径 |
CSS进阶之grid网格布局 (三) | 关于grid布局、grid-container属性、grid-items属性 |
CSS进阶之移动端适配 (四) | 媒体查询、CSS常见单位、深入理解pixel、DPR、PPI、浏览器视口Viewport、移动端适配rem方案、移动端适配vw方案 |
CSS进阶之额外内容补充 (五) | HTML5新增、CSS函数补充、BFC详解 |
1. 媒体查询
1.1 认识媒体查询
-
媒体查询: 是一种提供给
开发者
针对不同设备需求
进行定制化开发
的一个接口。可以让我们根据设备的类型
(比如:屏幕设备、打印机设备)或者特定的特性
(比如屏幕的宽度)来修改页面 -
媒体查询的使用方式:
- 方法一(常用):通过
@media
或@import
使用不同的CSS规则
/* @import是可以和媒体查询结合来使用 */ @import url(./css/body_bgc.css) (max-width: 800px); /* @media 设置媒体特性来使用 */ @media (max-width: 800px) { body { background-color: orange; } } /* @media 设置多个媒体特性需要加逻辑运算符来使用 */ @media (min-width: 500px) and (max-width: 800px) { body { background-color: orange; } } /* @media 设置媒体类型来使用 */ @media screen { }
- 方法二使用
media属性
给 <style>, <link>, <source>和其他HTML元素指定特定的媒体类型
- 方法三:使用Window.matchMedia() 和MediaQueryList.addListener() 方法来测试和监控媒体状态
- 方法一(常用):通过
-
媒体查询的三大组成:
- 媒体类型 —— Media types
- 媒体特性 —— Media features
- 逻辑运算符 —— Logical operators
1.2 媒体类型 Media types
- 注意:使用媒体查询时,必须要指定要使用的媒体类型,
若未指定,则媒体类型会隐式地应用 all 类型。
- 常见的媒体类型:
all
:适用于所有设备。screen(掌握)
:主要用于屏幕。print
:适用于在打印预览模式下在屏幕上查看的分页材料和文档。speech
:主要用于语音合成器。
1.3 媒体特性 Media features
- 媒体类型::描述了浏览器、输出设备,或是预览环境的具体特征。通常会将媒体特性描述为一个表达式,
每条媒体特性表达式都必须用括号括起来
1.4 逻辑运算符 Logical operators
- 逻辑运算符的使用: 媒体查询的表达式最终会获得一个Boolean值,如果结果为真(true),那么就会生效; 如果结果为假(false),那么就不会生效;如果有多个条件,我们可以通过逻辑操作符联合复杂的媒体查询。
and
:and 操作符用于将多个媒体查询规则组合成单条媒体查询not
:not运算符用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。only
:only运算符仅在整个查询匹配时才用于应用样式。, (逗号)
:逗号用于将多个媒体查询合并为一个规则。
设计一个屏幕宽度大于500,小于700的时候,body背景颜色为红色的媒体查询
1.5 媒体查询综合练习
- 我们都知道有很多移动端设备有着不同的逻辑分辨率,物理分辨率,为了让我们写的网页适用于绝大多数的移动设备,可以选择使用媒体查询来帮助我们给不同的媒体类型指定不同的样式。
<style>
/*
320~375之间 font-size: 15px;
375~414之间 font-size: 18px;
414~480之间 font-size: 21px;
大于480px font-size: 24px
*/
/* @media (min-width: 320px) and (max-width: 375px) {
.box { font-size: 15px; }
}
@media (min-width: 375px) and (max-width: 414px) {
.box { font-size: 18px; }
}
@media (min-width: 414px) and (max-width: 480px) {
.box { font-size: 21px; }
}
@media (min-width: 480px) {
.box { font-size: 24px; }
} */
/* CSS层叠性 */
@media (min-width: 320px) {
.box { font-size: 15px; }
}
@media (min-width: 375px) {
.box { font-size: 18px; }
}
@media (min-width: 414px) {
.box { font-size: 21px; }
}
@media (min-width: 480px) {
.box { font-size: 24px; }
}
</style>
2. CSS常见单位详解
前面编写的CSS中,我们经常会使用px来表示一个长度(大小),比如font-size设置为18px,width设置为100px。
- 整体可以分成两类:
绝对长度单位
(Absolute length units)相对长度单位
(Relative length units)
2.1 CSS中的绝对长度单位
- 绝对长度单位:大多数在用于打印时比用于屏幕输出时更有用,在屏幕上我们经常使用px。它们与其他任何东西都没有关系,通常被认为是相同的大小。
- px像素:px是一个个长度(length)单位,CSS中还有非常多的长度单位
2.2 CSS中的相对长度单位
- 相对长度单位:相对长度单位就是字面含义,它总是相对于其他一些东西,会相对于父元素的字体大小,或者视图端口的大小。
- 相对单位的好处:经过一些仔细的规划,您可以使文本或其他元素的大小与页面上的其他内容相对应
下图举例了一些常用的相对长度单位,特别是红框的单位是需要牢记于心的。
2.2.1 相对单位的使用
- em的使用:
.container {
font-size: 15px;
}
.box {
/* font-size: 20px; */
/* 如果自己没有设置, 那么会继承父元素的font-size */
/*
如果font-size中有写em单位, 可以理解成相对于父元素
但是更准确的理解依然是相对于自己的
*/
font-size: 1em;
/* 1.em: 相对自己的font-size */
width: 10em;
height: 5em;
background-color: orange;
}
- rem的使用:
html {
font-size: 1.5px;
}
.box {
width: 100rem;
height: 100rem;
font-size: 20rem;
background-color: orange;
}
- vw、vh的使用:
/* body {
margin: 0;
padding: 0;
} */
.box {
width: 10vw;
height: 10vh;
background-color: orange;
}
3. 深入理解pixel、DPR、PPI
3.1 当我们聊pixel时,到底在聊些什么?
- pixel(px):我们已经一直在使用px单位了,
px是pixel单词的缩写
,翻译为像素
。其中,pixel的pix为picture图片的常用简写
,el表示element元素
,像素即画像元素之意有时亦被称为pel(picture element)
- 那么像素到底是什么呢?
像素是影响显示的基本单位。(比如屏幕上看到的画面、一幅图片)
3.2 像素的不同分类
- 场景举例:我们买电脑、手机等设备时常常会说它们的分辨率是多少,而我们在使用时电脑屏幕上又常用1920*1080的分辨率,它们到底有什么区别呢?
这里我们要深入到不同的像素概念中,来理解CSS中的pixel到底代表什么含义。
- 像素单位常见的有三种像素名称::
物理像素
(也称之为设备像素)逻辑像素
(也称之为设备独立像素)CSS像素
3.3 物理像素和逻辑像素
-
物理像素 即设备像素
- 设备像素指的是
显示器上的真实像素
,每个像素的大小是屏幕固有的属性,屏幕出厂以后就不会改变
了 - 我们在购买
显示器或者手机的时候
,提到的设备分辨率就是设备像素的大小
- 比如
iPhone X的分辨率 1125x2436,指的就是设备像素
;
- 设备像素指的是
-
设备独立像素,也叫逻辑像素
- 如果
面向开发者
我们使用设备像素显示一个100px的宽度
,那么在不同屏幕上显示效果会是不同的
; - 开发者
针对不同的屏幕
很难进行较好的适配,编写程序必须了解用户的分辨率
来进行开发 - 所以在设备像素之上,
操作系统为开发者进行抽象,提供了逻辑像素的概念
; - 比如你购买了一台显示器,在
操作系统上是以1920x1080设置的显示分辨率
,那么无论你购买的是2k、4k的显示器
,对于开发者来说,都是
1920x1080的大小。
- 如果
-
CSS像素:CSS中我们经常使用的单位也是pixel,它在
默认情况下等同于设备独立像素(也就是逻辑像素)
;毕竟逻辑像素才是面向我们开发者的;
我们可以通过JavaScript中的screen.width和screen.height获取到电脑的逻辑分辨率
3.4 DPR、PPI
-
DPR:Device Pixel Ratio 设备像素比
- DPR的背景:2010年,iPhone4问世,不仅仅带来了移动互联网,还带来了Retina屏幕。Retina屏幕翻译为视网膜显示屏,可以为用户带来更好的显示。在Retina屏幕中,
一个逻辑像素在长度上
对应两个物理像素
,这个比例称之为设备像素比(device pixel ratio)
- 我们可以通过window.devicePixelRatio获取到当前屏幕上的DPR值;
- DPR的背景:2010年,iPhone4问世,不仅仅带来了移动互联网,还带来了Retina屏幕。Retina屏幕翻译为视网膜显示屏,可以为用户带来更好的显示。在Retina屏幕中,
-
PPI(了解):Pixels Per Inch 每英寸像素
- PPI的应用 :通常用来表示一个打印图像或者显示器上像素的密度;前面我们提过1英寸=2.54厘米,在工业领域被广泛应用;
4.视口 viewport
4.1 认识视口 viewport
-
视口的概念:在一个浏览器中,我们可以
看到的区域就是视口(viewport
),我们说过fixed就是相对于视口来进行定位的.- 在PC端的页面中: 我们是
不需要对视口进行区分
,因为我们的布局视口和视觉视口是同一个
- 在移动端的页面中:布局的视口和你可见的视口是不太一样的,是因为
移动端的网页窗口往往比较小
,我们可能会希望一个大的网页在移动端可以完整的显示
,所以在默认情况下,移动端的布局视口是大于视觉视口的
;
- 在PC端的页面中: 我们是
-
在移动端,我们可以将视口划分为三种情况:
布局视口
(layout viewport)视觉视口
(visual layout)理想视口
(ideal layout)
4.2 布局视口 layout viewport
- 布局视口
- 在默认情况下,
布局是口的默认宽度是980px
,它会按照宽度为980px来布局一个页面的盒子和内容。 - 为了
能完整的把内容显示在页面中,对整个页面进行缩小
。
- 在默认情况下,
4.3 视觉视口 visual viewport
- 视觉视口
- 如果默认情况下,我们按照980px显示内容,那么右侧有一部分区域就会无法显示,所以手机端浏览器会默认对页面进行缩放以显示到用户的可见区域中。
显示在可见区域的这个视口,就是视觉视口(visual viewport)
。
- 布局视口与视觉视口的区分
备注: 这些概念的区分,事实上来自ppk,他也是对前端贡献比较大的一个人(特别是在移动端浏览器)
https://www.quirksmode.org/mobile/viewports2.html
4.4 理想视口 ideal viewport
- 理想视口
- 我们了解到如果在默认情况下的布局视口的980px宽是不适合我们进行布局的,我们需要把布局视口的缩放机制和视口宽度进行设置,让布局视口刚好处于移动端窗口,我们把这样的视口称为
理想视口
-
通过meta设置布局视口的宽度:
<!-- width: 设置布局视口的宽度 width=device-width 布局视口宽度等于媒体设备的宽度 initial-scale=1.0 初始比例为1.0 user-scalable=no 用户不可以缩放 minimum-scale=1.0, maximum-scale=1.0 变相禁用用户缩放 --> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- 我们了解到如果在默认情况下的布局视口的980px宽是不适合我们进行布局的,我们需要把布局视口的缩放机制和视口宽度进行设置,让布局视口刚好处于移动端窗口,我们把这样的视口称为
5. 移动端适配
5.1 什么是移动端适配?
- 背景介绍:移动互联网的快速发展,让人们已经越来越习惯于使用手机来完成大部分日常的事务。前端我们已经学习了大量HTML、CSS的前端开发知识,并且也进行了项目实战 ,这些知识也
同样适用于移动端开发
;因为目前移动端设备较多,如果想让一个页面真正适配于移动端,我们最好多了解一些移动端的知识并对其进行一些适配
。 - 移动端开发目前主要包括三类:
原生App开发
(iOS、Android、RN、uniapp、Flutter等)小程序开发
(原生小程序、uniapp、Taro等)Web页面
(移动端的Web页面,可以使用浏览器或者webview浏览)
- 两个重要的概念区分
自适应
:根据不同的设备屏幕大小来自动调整尺寸、大小;响应式
:会随着屏幕的实时变动
而自动调整,是一种更强的自适应;
5.2 为什么要做移动端适配?
- 为什么要做适配? 移动端的屏幕尺寸通常是非常繁多的,很多时候我们希望在不同的屏幕尺寸上显示不同的大小
- 场景解释:
- 我们在针对一款手机进行设计布局时,设置了一个100x100的盒子
- 但是在不同设备上,因为他们的逻辑像素不同,会使得它在更大的布局视口上会显得很小,更小的布局上显得很大
- 因此我们需要进行适配让它在多种设备的上所占据视口的空间比例是相同的。
- 我们有几种可行的适配方案
-
方案一(不推荐): 百分比设置
- 注意:因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一,所以百分比在移动端适配中使用是非常少的;
-
方案二: flex的弹性布局
-
方案三(大推荐):
vw单位
- 可以理解成分成100份的rem
- 可以理解成分成100份的rem
-
方案四(小推荐):
rem单位+动态html的font-size
- 我们使用rem单位,然后在不同的屏幕给html设置不同的font-size,
-
5.3 适配方案 – rem+动态html的font-size
- 方案思路:rem单位是相对于html元素的font-size来设置的,那么如果我们需要在不同的屏幕下有不同的尺寸,需要动态的修改html的font-size尺寸。
- 在开发中,我们只需要考虑两个问题:
- 针对
不同的屏幕,设置html不同的font-size
- 将
原来要设置的尺寸,转化成rem单位
- 针对
- 比如如下案例:设置一个盒子的宽度是1rem,设置不同的屏幕上html的font-size不同.
5.3.0 px与rem的单位换算
- 方案一:手动换算
1. 1rem = 1根标签html的文字大小
2. 根标签html的文字大小 = 视口的宽度 / 分成的分数(常分为10份,方便计算)
3. rem值 = 元素的px值 / 根标签html的文字大小 - 方案二:less/scss函数
.pxToRem(@px) {
result: 1rem * (@px / 37.5);
}
.box {
width: .pxToRem(100)[result];
height: .pxToRem(100)[result];
background-color: orange;
}
p {
font-size: .pxToRem(14)[result];
}
- 方案三:postcss-pxtorem(后续学习):目前在前端的工程化开发中,我们可以借助于webpack的工具来完成自动的转化;
- 方案四:VSCode插件
5.3.1 方案一:媒体查询
- 思路: 可以通过
媒体查询来设置不同尺寸范围内的屏幕html的font-size尺寸
- 缺点:
- 我们
需要针对不同的屏幕编写大量的媒体查询
- 如果
动态改变尺寸,不会实时的进行更新
,只是一个个区间
- 我们
@media screen and (min-width: 320px) {
html {
font-size: 20px;
}
}
@media screen and (min-width: 375px) {
html {
font-size: 24px;
}
}
@media screen and (min-width: 414px) {
html {
font-size: 28px;
}
}
@media screen and (min-width: 480px) {
html {
font-size: 32px;
}
}
.box {
width: 5rem;
height: 5rem;
background-color: orange;
}
5.3.2 方案二:编写js代码
- 思路: 如果希望实时改变屏幕尺寸时,font-size也可以实时更改,可以通过js代码;
- 方法:
- 根据html的宽度计算出
font-size的大小
,并且设置到html
上 - 监听
页面的实时改变
,并且重新设置font-size的大小到html
上;
- 根据html的宽度计算出
// 获取所有html元素
const htmlEl = document.documentElement
// 375px -> 16px
// 320px -> 12px
// 我们需要动态的改变字体大小,因此需要获取网页的宽度
// 给window添加监听事件
window.addEventListener("resize", function () {
// 拿到客户端的宽度
const htmlWidth = htmlEl.clientWidth
// 将宽度分成10份
const htmlFontSize = htmlWidth / 10
console.log(htmlFontSize)
// 将值给到html的font-size
htmlEl.style.fontSize = htmlFontSize + "px"
})
5.3.3 方案三:lib-flexible库
- lib-flexible库:它和我们自己编写js的代码所做的事情是相同的,我们可以直接引入它。
- 源代码
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
5.4 适配方案 - vw
- 在flexible GitHub上已经有写过这样的一句话: 所以它更推荐使用viewport的两个单位vw、wh。
- vw的兼容性如何呢?
5.4.1 vw单位的作用
- 在之前的rem适配中,我们需要自己根据视口宽度来决定根元素html的字体大小,而vw单位本身就是参照于视口宽度的百分之一,使用vw可以让我们减少一个转换的流程,即
/*
rem:
1> 动态的设置html的font-size
font-size: 视口的宽度 / 10
2> 换算成rem的单位
*/
/* html {
font-size: 10vw;
} */
/*
1> 动态的设置html的font-size
font-size: 视口的宽度 / 100 -> 1vw
*/
.box {
width: 26.667vw;
height: 26.666vw;
background-color: orange;
}
5.4.2 vw和rem的对比
- vw相比于rem的优势:
- 优势一: 不需要去计算不同屏幕下html的font-size大小,也不需要给html设置这样一个font-size;
- 优势二: 不会因为设置html的font-size大小,而必须给body再设置一个font-size,防止继承;
- 优势三: 因为不依赖font-size的尺寸,所以不用担心某些原因html的font-size尺寸被篡改,页面尺寸混乱;
- 优势四: vw相比于rem更加语义化,1vw刚才是1/100的viewport的大小;
- 优势五: 可以具备rem之前所有的优点;
- 总结
- rem事实上是作为一种过渡的方案,它利用的也是vw的思想
- 前面不管是我们自己编写的js,还是flexible的源码,都是将1rem等同于设计稿的1/10,在利用1rem计算相对于整个屏幕的尺寸大小;
- 那么我们来思考,1vw不是刚好等于屏幕的1/100吗?而且相对于rem还更加有优势;
5.4.3 px与vw的单位换算
- 方案一:手动换算
- 比如有一个在375px屏幕上,100px宽度和高度的盒子,我们需要将100px转成对应的vw值:100/3.75=26.667,其他也是相同的方法计算即可
- 方案二:less/scss函数
- 方案三:postcss-px-to-viewport-8-plugin(后续学习):和rem一样,在前端的工程化开发中,我们可以借助于webpack的工具来完成自动的转化。
- 方案四:VSCode插件:px to vw 的插件,在编写时自动转化;