Emmet和结构伪类
认识emmet语法
◼ Emmet (前身为 Zen Coding) 是一个能大幅度****提高前端开发效率****的一个工具.
在前端开发的过程中,一大部分的工作是写 HTML、CSS 代码, 如果手动来编写效果会非常低.
VsCode内置了Emmet语法,在后缀为.html/.css中输入缩写后按Tab/Enter键即会自动生成相应代码
◼ !和html:5可以快速生成完整结构的html5代码
>(子代)和+(兄弟)
*(多个)和^(上一级)
()(分组)
属性(id属性、class属性、普通属性) {}(内容)
div#header+div#main>.container>a[href ]
a[href="http://www.baidu.com"]{百度一下}
$(数字)
ul>li.item$*5
隐式标签
CSS Emmet
结构伪类 - :nth-child
◼ :nth-child(1)
- 是父元素中的第1个子元素
◼ :nth-child(2n)
n代表任意正整数和0
是父元素中的第偶数个子元素(第2、4、6、8......个)
跟:nth-child(even)同义
◼ :nth-child(2n + 1)
n代表任意正整数和0
是父元素中的第奇数个子元素(第1、3、5、7......个)
跟:nth-child(odd)同义
◼ nth-child(-n + 2)
- 代表前2个子元素
结构伪类 - :nth-last-child( )
◼ :nth-last-child()的语法跟:nth-child()类似,不同点是:nth-last-child()从最后一个子元素开始往前计数
:nth-last-child(1),代表倒数第一个子元素
:nth-last-child(-n + 2),代表最后2个子元素
◼ :nth-of-type()用法跟:nth-child()类似
- 不同点是:nth-of-type()计数时只计算同种类型的元素
◼ :nth-last-of-type()用法跟:nth-of-type()类似
- 不同点是:nth-last-of-type()从最后一个这种类型的子元素开始往前计数
结构伪类 - :nth-of-type( )、:nth-last-of-type( )
◼ 其他常见的伪类(了解):
:first-child,等同于:nth-child(1)
:last-child,等同于:nth-last-child(1)
:first-of-type,等同于:nth-of-type(1)
:last-of-type,等同于:nth-last-of-type(1)
:only-child,是父元素中唯一的子元素
:only-of-type,是父元素中唯一的这种类型的子元素
◼ 下面的伪类偶尔会使用:
:root,根元素,就是HTML元素
:empty代表里面完全空白的元素
否定伪类(negationpseudo-class)
◼ :not()的格式是:not(x)
x是一个简单选择器
元素选择器、通用选择器、属性选择器、类选择器、id选择器、伪类(除否定伪类)
◼ :not(x)表示****除x以外的元素
额外知识补充
边框的形状
◼ border主要是用来给盒子增加边框的, 但是在开发中我们也可以利用边框的特性来实现一些形状:
◼ 假如我们将border宽度设置成50会是什么效果呢?
如果我们进一步, 将另外三边的颜色去除呢?
如果我们将这个盒子旋转呢?
◼ 所以利用border或者CSS的特性我们可以做出很多图形:
认识Web字体
◼ 在之前我们有设置过页面使用的字体: font-family
我们需要提供一个或多个字体种类名称,浏览器会在列表中搜寻,直到找到它所运行的系统上可用的字体。
这样的方式完全没有问题,但是对于传统的web开发人员来说,字体选择是有限的;
这就是所谓的 Web-safe 字体;
并且这种默认可选的字体并不能进行一些定制化的需求;
◼ 比如下面的字体样式, 系统的字体肯定是不能实现的
◼ 那么我们是否依然可以在网页中使用这些字体呢? 使用Web Fonts即可****.
Web fonts的工作原理
◼ 首先, 我们需要通过一些渠道****获取到希望使用的字体****(不是开发来做的事情):
对于某些收费的字体, 我们需要获取到对应的授权;
对于某些公司定制的字体, 需要设计人员来设计;
对于某些免费的字体, 我们需要获取到对应的字体文件;
◼ 其次, 在我们的CSS代码当中使用该字体(重要):
◼ 最后, 在部署静态资源时, 将HTML/CSS/JavaScript/Font一起部署在静态服务器中;
◼ 用户的角度:
浏览器一个网页时, 因为代码中有引入字体文件, 字体文件会被一起下载下来;
浏览器会根据使用的字体在下载的字体文件中查找、解析、使用对应的字体;
在浏览器中使用对应的字体显示内容;
使用Web Fonts
◼ 演示,通过如下的方式获取到了字体文件:
◼ 第一步:在字体天下网站下载一个字体
默认下载下来的是ttf文件;
◼ 第二步:使用字体;
◼ 使用过程如下:
1.将字体放到对应的目录中
2.通过@font-face来引入字体, 并且设置格式
3.使用字体
◼ 注意: @font-face 用于加载一个自定义的字体;
web-fonts的兼容性
◼ 我们刚才使用的字体文件是 .ttf, 它是TrueType字体.
- 在开发中某些浏览器可能不支持该字体, 所以为了浏 览器的兼容性问题, 我们需要有对应其他格式的字体;
◼ TrueType字体:拓展名是 .ttf
OpenType/TrueType字体:拓展名是 .ttf、.otf, 建立在TrueType字体之上
Embedded OpenType字体:拓展名是 .eot, OpenType字体的压缩版
SVG字体:拓展名是 .svg、 .svgz
WOFF表示Web Open Font Format web开放字体: 拓展名是 .woff,建立在TrueType字体之上
◼ 这里我们提供一个网站来生产对应的字体文件:
web fonts兼容性写法
◼ 如果我们具备很强的兼容性, 那么可以如下格式编写:
◼ 这被称为"bulletproof @font-face syntax(刀枪不入的@font-face语法)“:
- 这是 Paul Irish早期的一篇文章提及后@font-face开始流行起来 (Bulletproof @font-face Syntax)。
◼ src用于指定字体资源
url指定资源的路径
format用于帮助浏览器快速识别字体的格式;
认识字体图标
◼ 思考:字体可以设计成各式各样的形状,那么能不能把字体直接设计成图标的样子呢?
- 当然可以,这个就叫做字体图标。
◼ 字体图标的好处:
放大不会失真
可以任意切换颜色
用到很多个图标时,文件相对图片较小
◼ 字体图标的使用:
登录阿里icons(https://www.iconfont.cn/)
下载代码,并且拷贝到项目中
◼ 将字体文件和默认的css文件导入到项目中
字体图标的使用
◼ 字体图标的使用步骤:
第一步: 通过link引入iconfont.css文件
第二步: 使用字体图标
◼ 使用字体图标常见的有两种方式:
方式一: 通过对应字体图标的Unicode来显示代码;
方式二: 利用已经编写好的class, 直接使用即可;
认识精灵图CSSSprite
◼ 什么是CSSSprite
是一种CSS图像合成技术,将各种小图片合并到一张图片上,然后利用CSS的背景定位来显示对应的图片部分
有人翻译为:CSS雪碧、CSS精灵
◼ 使用CSS Sprite的好处
减少网页的http请求数量,加快网页响应速度,减轻服务器压力
减小图片总大小
解决了图片命名的困扰,只需要针对一张集合的图片命名
◼ Sprite图片制作(雪碧图、精灵图)
方法1:Photoshop, 设计人员提供
精灵图的使用
◼ 精灵图如何使用呢?
精灵图的原理是通过只显示图片的很小一部分来展示的;
通常使用背景:
✓ 1.设置对应元素的宽度和高度
✓ 2.设置精灵图作为背景图片
✓ 3.调整背景图片的位置来展示
◼ 如何获取精灵图的位置
Cusor
◼ cursor****可以设置鼠标指针(光标)在元素上面时的显示样式
◼ cursor****常见的设值有
auto:浏览器根据上下文决定指针的显示样式,比如根据文本和非文本切换指针样式
default:由操作系统决定,一般就是一个小箭头
pointer:一只小手,鼠标指针挪动到链接上面默认就是这个样式
text:一条竖线,鼠标指针挪动到文本输入框上面默认就是这个样式
none:没有任何指针显示在元素上面
CSS元素定位
标准流(Normal Flow)
◼ 默认情况下,元素都是按照normal flow(标准流、常规流、正常流、文档流【document flow】)进行排布
从左到右、从上到下按顺序摆放好
默认情况下,互相之间不存在层叠现象
<body>
<span>span1</span>
<img src="images/cube.jpg" alt="">
<span style="display: inline-block">span2</span>
<div>div</div>
<p>p</p>
<span style="display: inline-block">span</span>
<strong>strong</strong>
<h1>h1</h1>
<span>span3</span>
<span style="display: inline-block">span4</span>
<span>span5</span>
</body>
margin-padding位置调整
◼ 在标准流中,可以使用margin、padding对元素进行定位
- 其中margin还可以设置负数
◼ 比较明显的缺点是
设置一个元素的margin或者padding,通常会影响到标准流中其他元素的定位效果
不便于实现元素层叠的效果
◼ 如果我们希望一个元素可以跳出标准量,单独的对某个元素进行定位呢?
- 我们可以通过position属性来进行设置;
认识元素的定位
◼ 定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为:
例如放在另一个元素的上面;
或者始终保持在浏览器视窗内的同一位置;
认识position属性
◼ 利用position可以对元素进行定位,常用取值有5个:
◼ 默认值:
- static:默认值, 静态定位
◼ 使用下面的值, 可以让元素变成 定位元素(positioned element)
relative:相对定位
absolute:绝对定位
fixed:固定定位
sticky:粘性定位
静态定位 - static
◼ position属性的默认值
元素按照normal flow布局
left 、right、top、bottom没有任何作用
相对定位 - relative
◼ 元素按照normal flow布局
◼ 可以通过left、right、top、bottom进行定位
- 定位参照对象是元素自己原来的位置
◼ left、right、top、bottom用来设置元素的具体位置,对元素的作用如下图所示
◼ 相对定位的应用场景
- 在不影响其他元素位置的前提下,对当前元素位置进行微调
固定定位 - fixed
◼ 元素脱离normal flow(脱离标准流、脱标)
◼ 可以通过left、right、top、bottom进行定位
◼ 定位参照对象是视口(viewport)
◼ 当画布滚动时,固定不动
画布 和 视口
◼ 视口(Viewport)
文档的可视区域
如右图红框所示
◼ 画布(Canvas)
用于渲染文档的区域
文档内容超出视口范围,可以通过滚动查看
如右图黑框所示
◼ 宽高对比
- 画布 >= 视口
绝对定位 - absolute
◼ 元素脱离normal flow(脱离标准流、脱标)
◼ 可以通过left、right、top、bottom进行定位
定位参照对象是最邻近的定位祖先元素
如果找不到这样的祖先元素,参照对象是视口
◼ 定位元素(positioned element)
position值不为static的元素
也就是position值为relative、absolute、fixed的元素
子绝父相
◼ 在绝大数情况下,子元素的****绝对定位都是相对于父元素进行定位
◼ 如果希望子元素相对于父元素进行定位,又不希望父元素脱标,常用解决方案是:
父元素设置position: relative(让父元素成为定位元素,而且父元素不脱离标准流)
子元素设置position: absolute
简称为“子绝父相”
将position设置为absolute/fixed元素的特点(一)
◼ 可以随意设置宽高
◼ 宽高默认由内容决定
◼ 不再受标准流的约束
不再严格按照从上到下、从左到右排布
不再严格区分块级(block)、行内级(inline),行内块级(inline-block)的很多特性都会消失
◼ 不再给父元素汇报宽高数据 ◼ 脱标元素内部默认还是按照标准流布局
将position设置为absolute/fixed元素的特点(二)
◼ 绝对定位元素(absolutely positioned element)
- position值为absolute或者fixed的元素
◼ 对于绝对定位元素来说
定位参照对象的宽度 = left + right + margin-left + margin-right + 绝对定位元素的实际占用宽度
定位参照对象的高度 = top + bottom + margin-top + margin-bottom + 绝对定位元素的实际占用高度
◼ 如果希望绝对定位元素的宽高和定位参照对象一样,可以给绝对定位元素设置以下属性
- left: 0、right: 0、top: 0、bottom: 0、margin:0
◼ 如果希望绝对定位元素在定位参照对象中居中显示,可以给绝对定位元素设置以下属性
left: 0、right: 0、top: 0、bottom: 0、margin: auto
另外,还得设置具体的宽高值(宽高小于定位参照对象的宽高)
auto到底是什么?
◼ 800 = 200 + ml0 + mr0 + 0 + 0
◼ auto -> 交给浏览器你来出来
◼ width: auto;
1.行内非替换元素 -> width: 包裹内容
2.块级元素 ->width: 包含块的宽度
3.绝对定位元素 -> width: 包裹内容
粘性定位 - sticky
◼ 另外还有一个定位的值是position: sticky,比起其他定位值要新一些.
sticky是一个大家期待已久的属性;
可以看做是相对定位和固定(绝对)定位的结合体;
它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点;
当达到这个阈值点时, 就会变成固定(绝对)定位;
◼ sticky是相对于最近的滚动祖先包含滚动视口的(the nearest ancestor scroll container’s scrollport )
position值对比
CSS属性 - z-index
◼ z-index属性用来设置定位元素的****层叠顺序****(仅对定位元素有效)
- 取值可以是正整数、负整数、0
◼ 比较原则
-
如果是兄弟关系
✓ z-index越大,层叠在越上面
✓ z-index相等,写在后面的那个元素层叠在上面
-
如果不是兄弟关系
✓ 各自从元素自己以及祖先元素中,找出最邻近的2个定位元素进行比较
✓ 而且这2个定位元素必须有设置z-index的具体数值
CSS元素定位
认识浮动
◼ float 属性可以指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。
float 属性最初只用于在一段文本内浮动图像, 实现文字环绕的效果;
但是早期的CSS标准中并没有提供好的左右布局方案, 因此在一段时间里面它成为网页多列布局的最常用工具;
◼ 绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果
◼ 可以通过float属性让元素产生浮动效果,float的常用取值
none:不浮动,默认值
left:向左浮动
right:向右浮动
浮动规则一
◼ 元素一旦浮动后, 脱离标准流
朝着向左或向右方向移动,直到自己的边界紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止
定位元素会层叠在浮动元素上面
浮动规则二
◼ 如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界
浮动规则三
◼ 规则五: 浮动元素之间不能层叠
如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素(左浮找左浮,右浮找右浮)
如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止
浮动规则四
◼ 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出
- 比如行内级元素、inline-block元素、块级元素的文字内容
浮动规则五
◼ 规则五: 行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐
浮动的问题 – 高度塌陷
◼ 由于浮动元素脱离了标准流,变成了脱标元素,所以不再向父元素汇报高度
- 父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题
◼ 解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)
◼ 清浮动的目的是
- 让父元素计算总高度的时候,把浮动子元素的高度算进去
◼ 如何清除浮动呢? 使用clear属性
CSS属性 - clear
◼ clear属性是做什么的呢?
- clear 属性可以指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面;
◼ clear的常用取值
left:要求元素的顶部低于之前生成的所有左浮动元素的底部
right:要求元素的顶部低于之前生成的所有右浮动元素的底部
both:要求元素的顶部低于之前生成的所有浮动元素的底部
none:默认值,无特殊要求
◼ 那么我们可以利用这个特性来清除浮动.
清除浮动的方法
◼ 事实上我们有很多方法可以清除浮动
◼ 方法一: 给父元素设置固定高度 扩展性不好(不推荐)
◼ 方法二: 在父元素最后增加一个空的块级子元素,并且让它设置clear: both
会增加很多无意义的空标签,维护麻烦
违反了结构与样式分离的原则(不推荐)
◼ 方法三: 给父元素添加一个伪元素
推荐;
编写好后可以轻松实现清除浮动;
方法三 – 伪元素清除浮动
◼ 给父元素增加::after伪元素
- 纯CSS样式解决,结构与样式分离(推荐)
布局方案总结
CSS Flex布局
认识flexbox
◼ Flexbox翻译为弹性盒子:
弹性盒子是一种用于按行或按列布局元素的一维布局方法 ;
元素可以膨胀以填充额外的空间, 收缩以适应更小的空间;
通常我们使用Flexbox来进行布局的方案称之为flex布局(flex layout);
◼ flex布局是目前web开发中使用最多的布局方案:
flex 布局(Flexible 布局,弹性布局);
目前特别在移动端可以说已经完全普及;
在PC端也几乎已经完全普及和使用, 只有非常少数的网站依然在用浮动来布局;
◼ 为什么需要flex布局呢?
长久以来,CSS 布局中唯一可靠且跨浏览器兼容的布局工具只有 floats 和 positioning。
但是这两种方法本身存在很大的局限性, 并且他们用于布局实在是无奈之举;
原先的布局存在的痛点
◼ 原来的布局存在哪些痛点呢? 举例说明:
- 比如在父内容里面垂直居中一个块内容。
比如使容器的所有子项等分可用宽度/高度,而不管有多少宽度/高度可用。
比如使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。
flex布局的出现
◼ 所以长久以来, 大家非常期待一种真正可以用于对元素布局的方案: 于是flex布局出现了****;
Nature and nature's laws lay hid in night; God said "Let Newton be" and all was light.
自然与自然的法则在黑夜隐藏,于是上帝说,让牛顿出现吧!于是世界就明亮了起来.
◼ flexbox在使用时, 我们最担心的是它的兼容性问题:
- 我们可以在caniuse上查询到具体的兼容性
flex布局的重要概念
◼ 两个重要的概念:
开启了 flex 布局的元素叫 flex container
flex container 里面的直接子元素叫做 flex item
◼ 当flex container中的子元素变成了flex item时, 具备一下特点:
flex item的布局将受flex container属性的设置来进行控制和布局;
flex item不再严格区分块级元素和行内级元素;
flex item默认情况下是包裹内容的, 但是可以设置宽度和高度;
◼ 设置 display 属性为 flex 或者 inline-flex 可以成为 flex container
flex: flex container 以 block-level 形式存在
inline-flex: flex container 以 inline-level 形式存在
flex布局的模型
flex相关的属性
flex-direction
◼ flex items 默认都是沿着 main axis(主轴)从 main start 开始往 main end 方向排布
flex-direction 决定了 main axis 的方向,有 4 个取值
row(默认值)、row-reverse、column、column-reverse
flex-wrap
◼ flex-wrap 决定了 flex container 是单行还是多行
nowrap(默认):单行
wrap:多行
wrap-reverse:多行(对比 wrap,cross start 与 cross end 相反)
flex-flow
◼ flex-flow 属性是 flex-direction 和 flex-wrap 的简写。
- 顺序任何, 并且都可以省略;
justify-content
◼ justify-content 决定了 flex items 在 main axis 上的对齐方式
flex-start(默认值):与 main start 对齐
flex-end:与 main end 对齐
center:居中对齐
space-between:
✓ flex items 之间的距离相等
✓ 与 main start、main end两端对齐space-around:
✓ flex items 之间的距离相等
✓ flex items 与 main start、main end 之间的距离是 flex items 之间距离的一半space-evenly:
✓ flex items 之间的距离相等
✓ flex items 与 main start、main end 之间的距离 等于 flex items 之间的距离
align-item
◼ align-items 决定了 flex items 在 cross axis 上的对齐方式
normal:在弹性布局中,效果和stretch一样
stretch:当 flex items 在 cross axis 方向的 size 为 auto 时,会 自动拉伸至填充 flex container
flex-start:与 cross start 对齐
flex-end:与 cross end 对齐
center:居中对齐
baseline:与基准线对齐
align-content
◼ align-content 决定了多行 flex items 在 cross axis 上的对齐方式,用法与 justify-content 类似
stretch(默认值):与 align-items 的 stretch 类似
flex-start:与 cross start 对齐
flex-end:与 cross end 对齐
center:居中对齐
space-between:
✓ flex items 之间的距离相等
✓ 与 cross start、cross end两端对齐
- space-around:
✓ flex items 之间的距离相等
✓ flex items 与 cross start、cross end 之间的距离是 flex items 之间距离的一半
- space-evenly:
✓ flex items 之间的距离相等
✓ flex items 与 cross start、cross end 之间的距离 等于 flex items 之间的距离
flex-item属性 - order
◼ order 决定了 flex items 的排布顺序
可以设置任意整数(正整数、负整数、0),值越小就越排在前面
默认值是 0
flex-item属性 - flex items
◼ flex items 可以通过 align-self 覆盖 flex container 设置的 align-items
auto(默认值):遵从 flex container 的 align-items 设置
stretch、flex-start、flex-end、center、baseline,效果跟 align-items 一致
flex-item属性 - flex-grow
◼ flex-grow 决定了 flex items 如何扩展(拉伸/成长)
可以设置任意非负数字(正小数、正整数、0),默认值是 0
当 flex container 在 main axis 方向上有剩余 size 时,flex-grow 属性才会有效
◼ 如果所有 flex items 的 flex-grow 总和 sum 超过 1,每个 flex item 扩展的 size 为
- flex container 的剩余 size * flex-grow / sum
◼ flex items 扩展后的最终 size 不能超过 max-width\max-height
flex-item属性 - flex-shrink
◼ flex-shrink 决定了 flex items 如何收缩(缩小)
可以设置任意非负数字(正小数、正整数、0),默认值是 1
当 flex items 在 main axis 方向上超过了 flex container 的 size,flex-shrink 属性才会有效
◼ 如果所有 flex items 的 flex-shrink 总和超过 1,每个 flex item 收缩****的 size为
- flex items 超出 flex container 的 size * 收缩比例 / 所有 flex items 的收缩比例之和
◼ flex items 收缩****后的最终 size 不能小于 min-width\min-height
flex-item属性 - flex-basis
◼ flex-basis 用来设置 flex items 在 main axis 方向上的 base size
- auto(默认值)、具体的宽度数值(100px)
◼ 决定 flex items 最终 base size 的因素,从优先级高到低
max-width\max-height\min-width\min-height
Flex-basis
width\height
内容本身的 size
flex-item属性 - flex属性
◼ flex 是 flex-grow || flex-shrink || flex-basis 的简写,flex 属性可以指定1个,2个或3个值。
◼ 单值语法: 值必须为以下其中之一:
一个无单位数(<number>): 它会被当作<flex-grow>的值。
一个有效的宽度(width)值: 它会被当作 <flex-basis>的值。
关键字none,auto或initial.
◼ 双值语法: 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。
- 第二个值必须为以下之一:
✓ 一个无单位数:它会被当作 <flex-shrink> 的值。
✓ 一个有效的宽度值: 它会被当作 <flex-basis> 的值。
◼ 三值语法:
第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。
第二个值必须为一个无单位数,并且它会被当作 <flex-shrink>的值。
第三个值必须为一个有效的宽度值, 并且它会被当作 <flex-basis> 的值。
思考: 如下布局如何解决对其问题
CSS动画
CSS属性 - vertical-align
深入理解vertical-align – line boxes
◼ 官方文档的翻译:vertical-align会影响 行内块级元素 在一个 行盒 中垂直方向的位置
◼ 思考:一个div没有设置高度的时候,会不会有高度?
没有内容,没有高度
有内容,内容撑起来高度
◼ 但是内容撑起来高度的本质是什么呢?
- 内容有行高(line-height),撑起来了div的高度
◼ 行高为什么可以撑起div的高度?
这是因为line boxes的存在,并且line-boxes有一个特性,包裹每行的inline level
而其中的文字是有行高的,必须将整个行高包裹进去,才算包裹这个line-level
◼ 那么,进一步思考:
- 如果这个div中有图片,文字,inline-block,甚至他们设置了margin这些属性呢?
深入理解vertical-align – 不同情况分析
◼ 情况一:只有文字时,line boxes如何包裹内容?(注意:红色是包裹的div,下面也都一样)
◼ 情况二:有图片,有文字时,line-boxes如何包裹内容?
◼ 情况三:有图片,有文字,有inline-block(比图片要大)如何包裹内容?
深入理解vertical-align – 不同情况分析
◼ 情况四:有图片,有文字,有inline-block(比图片要大)而且设置了margin-bottom,如何包裹内容?
◼ 情况五:有图片、文字、inline-block(比图片要大)而且设置了margin-bottom并且有文字,如何包裹内容?
vertical-align的baseline
◼ 结论:line-boxes一定会想办法包裹住当前行中所有的内容。
◼ 但是,但是为什么对齐方式千奇百怪呢?
你认为的千奇百怪,其实有它的内在规律
答案就是baseline对齐
◼ 我们来看官方vertical-align的默认值:没错,就是baseline
◼ 但是baseline都是谁呢?
文本的baseline是字母x的下方
Inline-block默认的baseline是margin-bottom的底部(没有,就是盒子的底部)
Inline-block有文本时,baseline是最后一行文本的x的下方
◼ 一切都解释通了
vertical-align的其他值
◼ 现在,对于不同的取值就非常容易理解了
baseline(默认值):基线对齐(你得先明白什么是基线)
top:把行内级盒子的顶部跟line boxes顶部对齐
middle:行内级盒子的中心点与父盒基线加上x-height一半的线对齐
bottom:把行内级盒子的底部跟line box底部对齐
<percentage>:把行内级盒子提升或者下降一段距离(距离相对于line-height计算\元素高度), 0%意味着同baseline一 样
<length>:把行内级盒子提升或者下降一段距离,0cm意味着同baseline一样
◼ 解决图片下边缘的间隙方法:
方法一: 设置成top/middle/bottom
方法二: 将图片设置为block元素
CSS属性 - transform
◼ CSStransform属性允许你旋转,缩放,倾斜或平移给定元素。
◼ Transform是形变的意思,transformer就是变形金刚
◼ 常见的函数transformfunction有:
平移:translate(x, y)
缩放:scale(x, y)
旋转:rotate(deg)
倾斜:skew(deg, deg)
◼ 通过上面的几个函数,我们可以改变某个元素的形变
位移 - translate
◼ 平移:translate(x, y)
◼ 值个数
一个值时,设置x轴上的位移
二个值时,设置x轴和y轴上的位移
◼ 值类型:
数字:100px
百分比:参照元素本身( refer to the size of bounding box )
缩放 - scale
◼ 缩放:scale(x, y)
◼ 值个数
一个值时,设置x轴上的缩放
二个值时,设置x轴和y轴上的缩放
◼ 值类型:
- 数字:
✓ 1:保持不变
✓ 2:放大一倍
✓ 0.5:缩小一半
- 百分比:不支持百分比
transform-origin
◼ transform-origin:变形的原点
◼ 一个值:
- 设置x轴的原点
◼ 两个值:
- 设置x轴和y轴的原点
◼ 必须是<length>,<percentage>,或 left, center, right, top, bottom关键字中的一个
left, center, right, top, bottom关键字
length:从左上角开始计算
百分比:参考元素本身大小
缩放 - rotate
◼ 旋转:rotate(deg)
◼ 值个数
- 一个值时,表示旋转的角度
◼ 值类型:
deg:旋转的角度
正数为顺时针
负数为逆时针
◼ 注意:旋转的****原点****受transform-origin的影响
倾斜 - skew
◼ 旋转:skew(x, y)
◼ 值个数
一个值时,表示x轴上的倾斜
二个值时,表示x轴和y轴上的倾斜
◼ 值类型:
deg:旋转的角度
正数为顺时针
负数为逆时针
◼ 注意:旋转的****原点****受transform-origin的影响
过渡动画 - transition
◼ transition CSS 属性是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的 一个简写属性。
-
transition-property:指定应用过渡属性的名称
可以写all表示所有可动画的属性
属性是否支持动画查看文档
-
transition-duration:指定过渡动画所需的时间
- 单位可以是秒(s)或毫秒(ms)
-
transition-timing-function:指定动画的变化曲线
transition-delay:指定过渡动画执行之前的等待时间
关键帧动画
◼ 之前我们学习了transition来进行过渡动画,但是过渡动画只能控制首尾两个值:
从关键帧动画的角度相当于只是定义了两帧的状态:第一帧和最后一帧。
如果我们希望可以有更多状态的变化,可以直接使用关键帧动画。
◼ 关键帧动画****使用@keyframes来定义多个变化状态,并且使用animation-name来声明匹配:
1.使用 @keyframes创建一个规则
2. @keyframes中使用百分比定义各个阶段的样式
3. 通过animation将动画添加到属性上
◼ 另外,也可以使用from和to关键字:
from相当于0%
to相当于100%
animation属性
◼ CSS animation 属性是 animation-name,animation-duration, animation-timing-function,animation-delay,animation- iteration-count,animation-direction,animation-fill-mode 和 animation-play-state 属性的一个简写属性形式。
animation-name:指定执行哪一个关键帧动画
animation-duration:指定动画的持续时间
animation-timing-function:指定动画的变化曲线
animation-delay:指定延迟执行的时间
animation-iteration-count:指定动画执行的次数,执行infinite表示无限动画
animation-direction:指定方向,常用值normal和reverse
-
animation-fill-mode:执行动画最后保留哪一个值
none:回到没有执行动画的位置
forwards:动画最后一帧的位置
backwards:动画第一帧的位置
animation-play-state:指定动画运行或者暂停(在JavaScript中使用,用于暂停动画)
项目实战
代码规范
◼ 参考凹凸实验室代码规范:
CSS 编写顺序
CSS 编写顺序的思路
◼ 1.先确定盒子本身是如何布局
- position: absolute
- float: left/right
- display: flex
◼ 2.盒子的特性和可见性
- display: block/inline-block/inline/none
- visibility/opacity
◼ 3.盒子模型
- width/height
- box-sizing
- margin/border/padding/content
- box-shadow/text-shadow
◼ 4.内部的文本文字
- font/text
◼ 5.background
- background-image/size/position/color
◼ 6.其他
- transform/transition/overflow/white-space
组件化开发思路
◼ 事实上目前Vue、React、小程序都采用的是组件化开发思路
项目整体思路 – 各个击破
meta 元素
◼ meta元素用于定义 元数据 :
head中用于定义元数据;
比如标题title、样式style、link外部资源等;
meta用于定义那些不能使用其他定元相关(meta-related)元素定义的任何元数据信息;
◼ meta 元素定义的 元数据 的类型包括以下几种:
如果设置了 charset 属性,meta 元素是一个字符集声明,告诉文档使用哪种字符编码。
如果设置了 http-equiv 属性,meta 元素则是编译指令。
如果设置了 name 属性,meta 元素提供的是文档级别(document-level)的元数据,应用于整个页面。
meta 元素的http-equiv属性
◼ 我们会发现,无论是默认创建的html页面还是王者荣耀都有如下代码:
◼ 它的作用到底是什么呢?网上众说纷纭,我们直接看官方文档的解释:
告知IE浏览器去模仿哪一个浏览器的行为;
IE=edge,告知IE8区使用最高有效模式来模仿;
meta 元素的name属性
◼ name属性的值非常多,具体的内容可以查看文档:
◼ 我们介绍几个常用的:
robots:爬虫、协作搜寻器,或者 “机器人”,对此页面的处理行为,或者说,应当遵守的规则。
author:文档作者的名字。
Copyright:版权声明;
-
description:一段简短而精确的、对页面内容的描述。
- 一些浏览器,比如 Firefox 和 Opera,将其用作书签的默认描述。
keywords:与页面内容相关的关键词,使用逗号分隔。某些搜索引擎会进行收录;
link 图标
◼ Favicon是 favorites icon 的缩写,亦被称为website icon(站点图标)、page icon(页面图标);
◼ 前面我们已经学习了它的用法:
◼ 事实上它还有很多兼容性的写法:
◼ 这里有一个疑惑?
- 为什么王者荣耀没有link元素也可以正常显示图标呢?
◼ 下面的link使用方法表示有另一个可替换的网站供选择:
CSS 样式的字符 编码
◼ 之前我们有制定过HTML页面的****编码****,但是并没有制定****CSS****样式的编码。
- 那么CSS样式的字符编码会按照什么规则来使用呢?
◼ 在样式表中有多种方法去声明字符 编码 ,浏览器会按照以下顺序尝试下边的方法(一旦找到就停止并得出结果):
-
1.文件的开头的 Unicode byte-order(字节顺序标记) 字符值。
2.由Content-Type:HTTP header 中的 charset 属性给出的值或用于提供样式表的协议中的等效值。
3.CSS@规则 @charset。
-
4.使用参考文档定义的字符编码: <link> 元素的 charset 属性。
✓ 该方法在 HTML5 标准中已废除,无法使用。
5.假设文档是 UTF-8。
◼ 开发中推荐在CSS的开头编写@charset指定编码:
额外知识补充(一)
HTML5 语义化元素
◼ 在HMTL5之前,我们的网站分布层级通常包括哪些部分呢?
- header、nav、main、footer
◼ 但是这样做有一个弊端:
我们往往过多的使用div, 通过id或class来区分元素;
对于浏览器来说这些元素不够语义化;
对于搜索引擎来说, 不利于SEO的优化;
◼ HTML5 新增了语义化的元素:
<header>:头部元素
<nav>:导航元素
<section>:定义文档某个区域的元素
<article>:内容元素
<aside>:侧边栏元素
<footer>:尾部元素
HTML5 其他新增元素
◼ Web端事实上一直希望可以更好的嵌入音频和视频, 特别是21世纪以来, 用户带宽的不断提高, 浏览器因为和视频变得非常容易.
在HTML5之前是通过flash或者其他插件实现的, 但是会有很多问题;
比如无法很好的支持HTML/CSS特性, 兼容性问题等等;
◼ HTML5 增加了对媒体类型的支持:
音频:<audio>
视频:<video>
◼ Video和Audio使用方式有两个:
一方面我们可以直接通过元素使用video和autio;
另一方面我们可以通过JavaScript的API对其进行控制;
HTML5 新增元素 - video
◼ HTML <video> 元素 用于在HTML或者XHTML文档中嵌入媒体播放器,用于支持文档内的视频播放。
◼ video常见的属性:
video支持的视频格式
◼ 每个视频都会有自己的格式, 浏览器的video并非支持所有的视频格式
video的兼容性写法
◼ 在<video>元素中间的内容,是针对浏览器不支持此元素时候的****降级****处理。
内容一:通过<source>元素指定更多视频格式的源;
内容二:通过p/div等元素指定在浏览器不支持video元素的情况, 显示的内容;
HTML5 新增元素 - audio
◼ HTML <audio> 元素用于在文档中嵌入音频内容, 和video的用法非常类似
◼ 常见属性:
audio支持的音频格式
◼ 每个音频都会有自己的格式, 浏览器的audio并非支持所有的视频格式
◼ 具体的支持的格式可以通过下面的链接查看:
◼ 在<audio>元素中间的内容,是针对浏览器不支持此元素时候的****降级****处理。
input元素的扩展内容
◼ HTML5 对 input元素 也进行了扩展,在之前我们已经学习过的其中几个属性也是HTML5的特性:
placeholder:输入框的占位文字
multiple:多个值
autofocus:最多输入的内容
◼ 另外对于input的type值也有很多扩展:
date
Time
number
Tel
Color
Email
等等...
◼ 查看MDN文档:
新增全局属性 data-*
◼ 在 HTML5 中, 新增一种全局属性的格式 data-, 用于自定义数据属性:*
data设置的属性可以在JavaScript的DOM操作中通过dataset轻松获取到;
通常用于HTML和JavaScript数据之间的传递;
◼ 在小程序中, 就是通过data-来传递数据的, 所以该全局属性必须要掌握.
CSS 属性 - white-space
◼ white-space用于设置空白处理和换行规则
normal:合并所有连续的空白,允许单词超屏时自动换行
nowrap:合并所有连续的空白,不允许单词超屏时自动换行
pre:阻止合并所有连续的空白,不允许单词超屏时自动换行
pre-wrap:阻止合并所有连续的空白,允许单词超屏时自动换行
pre-line:合并所有连续的空白(但保留换行),允许单词超屏时自动换行
CSS 属性 - text-overflow
◼ text-overflow通常用来设置文字溢出时的行为
clip:溢出的内容直接裁剪掉(字符可能会显示不完整)
ellipsis:溢出那行的结尾处用省略号表示
◼ text-overflow生效的前提是overflow不为visible ◼ 常见的是将white-space、text-overflow、overflow一起使用:
CSS 中的函数
◼ 在前面我们有使用过很多个 CSS 函数:
比如rgb/rgba/translate/rotate/scale等;
CSS函数通常可以帮助我们更加灵活的来编写样式的值;
◼ 下面我们再学习几个非常好用的 CSS 函数:
var: 使用CSS定义的变量;
calc: 计算CSS值, 通常用于计算元素的大小或位置;
blur: 毛玻璃(高斯模糊)效果;
gradient:颜色渐变函数;
CSS 函数 - var
◼ CSS 中可以自定义属性
属性名需要以两个减号(--)开始;
属性值则可以是任何有效的CSS值;
◼ 我们可以通过var函数来使用:
◼ 规则集定义的选择器, 是自定义属性的可见作用域(只在选择器内部有效)
- 所以推荐将自定义属性定义在html中,也可以使用 :root 选择器;
CSS 函数 -calc
◼ calc() 函数允许在声明 CSS 属性值时执行一些计算。
-
计算支持加减乘除的运算;
✓ + 和 - 运算符的两边必须要有空白字符。
通常用来设置一些元素的尺寸或者位置;
CSS 函数 - blur
◼ blur() 函数将 高斯模糊 应用于输出图片或者元素;
blur(radius)
radius, 模糊的半径, 用于定义高斯函数的偏差值, 偏差值越大, 图片越模糊;
◼ 通常会和两个属性一起使用:
filter: 将模糊或颜色偏移等图形效果应用于元素;
backdrop-filter: 为元素后面的区域添加模糊或者其他效果;
CSS 函数 – gradient
◼ <gradient> 是一种 <image> CSS 数据类型的子类型 ,用于表现 两种或多种颜色的过渡转变 。
CSS的<image>数据类型描述的是2D图形;
比如background-image、list-style-image、border-image、content等;
<image>常见的方式是通过url来引入一个图片资源;
它也可以通过CSS的<gradient> 函数来设置颜色的渐变;
◼ <gradient>常见的函数实现有下面几种:
linear-gradient():创建一个表示两种或多种颜色线性渐变的图片;
radial-gradient():创建了一个图像,该图像是由从原点发出的两种或者多种颜色之间的逐步过渡组成;
repeating-linear-gradient():创建一个由重复线性渐变组成的<image>;
repeating-radial-gradient():创建一个重复的原点触发渐变组成的<image>;
等等;
linear-gradient的使用
◼ linear-gradient:创建一个表示两种或多种颜色线性渐变的图片;
◼ radial-gradient:创建了一个图像,该图像是由从 原点 发出的两种或者多种颜色之间的逐步过渡组成;
浏览器前缀
◼ 有时候可能会看到有些 CSS 属性名前面带有: -o-、-xv-、-ms-、mso-、-moz-、-webkit-
◼ 官方文档专业术语叫做:vendor-specific extensions(供应商特定扩展)
◼ 为什么需要浏览器前缀了?
- CSS属性刚开始并没有成为标准,浏览器为了防止后续会修改名字给新的属性添加了浏览器前缀;
◼ 上述前缀叫做浏览器私有前缀,只有对应的浏览器才能解析使用
-o-、-xv-:Opera等
-ms-、mso-:IE等
-moz-:Firefox等
-webkit-:Safari、Chrome等
◼ 注意:不需要手动添加,后面学习了模块化****打包****工具会自动添加浏览器前缀
FC – Formatting Context
◼ 什么是 FC 呢?
◼ FC 的全称是Formatting Context,元素在标准流里面都是属于一个 FC 的;
◼ 块级元素的布局属于Block Formatting Context(BFC)
- 也就是block level box都是在BFC中布局的;
◼ 行内级元素的布局属于Inline Formatting Context(IFC)
- 而inline level box都是在IFC中布局的;
BFC – Block Formatting Context
◼ block level box都是在 BFC 中布局的,那么这个BFC在哪里呢?拿出来给我看看。
◼ MDN上有整理出在哪些具体的情况下会创建 BFC :
根元素(<html>)
浮动元素(元素的 float 不是 none)
绝对定位元素(元素的 position 为 absolute 或 fixed)
行内块元素(元素的 display 为 inline-block)
表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值),表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、
row、tbody、thead、tfoot 的默认属性)或 inline-table)
overflow 计算值(Computed)不为 visible 的块元素
弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
display 值为 flow-root 的元素
BFC 有什么作用呢?
◼ 我们来看一下官方文档对 BFC 作用的描述:
◼ 简单概况如下:
在BFC中,box会在垂直方向上一个挨着一个的排布;
垂直方向的间距由margin属性决定;
在同一个BFC中,相邻两个box之间的margin会折叠(collapse);
在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的;
◼ 那么这个东西有什么用呢?
解决margin的折叠问题;
解决浮动高度塌陷问题;
BFC 的作用一:解决折叠问题(权威)
◼ 在同一个 BFC 中,相邻两个box之间的margin会折叠( collapse )
官方文档明确的有说
The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
那么如果我们让两个box是不同的BFC呢?那么就可以解决折叠问题。
BFC 的作用二:解决浮动高度塌陷(权威)
◼ 网上有很多说法, BFC 可以解决浮动高度塌陷,可以实现清除浮动的效果。
但是从来没有给出过BFC可以解决高度塌陷的原理或者权威的文档说明;
他们也压根没有办法解释,为什么可以解决浮动高度的塌陷问题,但是不能解决绝对定位元素的高度塌陷问题呢?
◼ 事实上, BFC 解决高度塌陷需要满足两个条件:
浮动元素的父元素触发BFC,形成独立的块级格式化上下文(Block Formatting Context);
浮动元素的父元素的高度是auto的;
◼ BFC 的高度是auto的情况下,是如下方法计算高度的
1.如果只有inline-level,是行高的顶部和底部的距离;
2.如果有block-level,是由最底层的块上边缘和最底层 块盒子的下边缘之间的距离
3.如果有绝对定位元素,将被忽略;
4.如果有浮动元素,那么会增加高度以包括这些浮动元 素的下边缘
媒体查询
◼ 媒体查询是一种提供给开发者针对不同设备需求进行定制化开发的一个接口。
◼ 你可以根据设备的类型(比如屏幕设备、打印机设备)或者特定的特性(比如屏幕的宽度)来修改你的页面。
◼ 媒体查询的使用方式主要有三种:
- 方式一:通过@media和@import使用不同的CSS规则(常用);
- 方式二:使用media属性为<style>, <link>, <source>和其他HTML元素指定特定的媒体类型;
- 方式三:使用Window.matchMedia() 和MediaQueryList.addListener() 方法来测试和监控媒体状态;
◼ 比较常用的是通过@media来使用不同的CSS规则,目前掌握这个即可;
媒体查询 - 媒体类型(Media types)
◼ 在使用媒体查询时,你必须指定要使用的媒体类型。
- 媒体类型是可选的,并且会(隐式地)应用 all 类型。
◼ 常见的媒体类型值如下:
all:适用于所有设备。
print:适用于在打印预览模式下在屏幕上查看的分页材料和文档。
screen(掌握):主要用于屏幕。
speech:主要用于语音合成器。
◼ 被废弃的媒体类型:
CSS2.1 和 Media Queries 3 定义了一些额外的媒体类型(tty, tv, projection, handheld, braille, embossed, 以及 aural);
但是他们在Media Queries 4 中已经被废弃,并且不应该被使用;
aural类型被替换为具有相似效果的speech。
媒体查询 – 媒体特性(Media features)
◼ 媒体特性(Media features)描述了 浏览器、输出设备,或是预览环境的具体特征;
通常会将媒体特性描述为一个表达式;
每条媒体特性表达式都必须用括号括起来;
媒体查询 – 逻辑操作符(logical operators)
◼ 媒体查询的表达式最终会获得一个Boolean值,也就是真(true)或者假(false)。
如果结果为真(true),那么就会生效;
如果结果为假(false),那么就不会生效;
◼ 如果有多个条件,我们可以通过逻辑操作符联合复杂的媒体查询:
and:and 操作符用于将多个媒体查询规则组合成单条媒体查询
not:not运算符用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。
only:only运算符仅在整个查询匹配时才用于应用样式。
, (逗号):逗号用于将多个媒体查询合并为一个规则。
◼ 比如下面的媒体查询,表示:屏幕宽度大于500,小于700的时候,body背景颜色为红色;
常见的移动端设备
◼ 这里我们以iPhone为例:
CSS 中的单位
◼ 前面编写的CSS中,我们经常会使用px来表示一个长度(大小),比如font-size设置为18px,width设置为100px。 ◼ px是一个长度(length)单位,事实上CSS中还有非常多的长度单位。
◼ 整体可以分成两类:
绝对长度单位(Absolute length units);
相对长度单位(Relative length units);
CSS 中的绝对单位( Absolute length units )
◼ 绝对单位:
它们与其他任何东西都没有关系,通常被认为总是相同的大小。
这些值中的大多数在用于打印时比用于屏幕输出时更有用,例如,我们通常不会在屏幕上使用cm。
唯一一个您经常使用的值,就是px(像素)。
CSS 中的相对单位( Relative length units )
◼ 相对长度单位
相对长度单位相对于其他一些东西;
比如父元素的字体大小,或者视图端口的大小;
使用相对单位的好处是,经过一些仔细的规划,您可以使文本或其他元素的大小与页面上的其他内容相对应;
◼ em:
◼ rem:
◼ vw/wh
当我们聊pixel时,到底在聊些什么?
◼ 前面我们已经一直在使用px单位了,px是pixel单词的缩写,翻译为像素。
◼ 那么像素到底是什么呢?
像素是影响显示的基本单位。(比如屏幕上看到的画面、一幅图片);
pix是英语单词picture的常用简写,加上英语单词“元素”element,就得到pixel; “像素”表示“画像元素”之意,有时亦被称为pel(picture element);
像素的不同分类(一)
◼ 但是这个100个pixel到底是多少呢?
我们确实可以在屏幕上看到一个大小,但是这个大小代表的真实含义是什么呢?
我们经常说一个电脑的分辨率、手机的分辨率,这个CSS当中的像素又是什么关系呢?
◼ 这里我们要深入到不同的像素概念中,来理解 CSS 中的pixel到底代表什么含义。
◼ 像素单位常见的有三种像素名称:
设备像素(也称之为物理像素);
设备独立像素(也称之为逻辑像素);
CSS像素;
物理像素和逻辑像素
◼ 设备像素,也叫物理像素。
设备像素指的是显示器上的真实像素,每个像素的大小是屏幕固有的属性,屏幕出厂以后就不会改变了;
我们在购买显示器或者手机的时候,提到的设备分辨率就是设备像素的大小;
比如iPhone X的分辨率 1125x2436,指的就是设备像素;
◼ 设备独立像素,也叫逻辑像素。
如果面向开发者我们使用设备像素显示一个100px的宽度,那么在不同屏幕上显示效果会是不同的;
开发者针对不同的屏幕很难进行较好的适配,编写程序必须了解用户的分辨率来进行开发;
所以在设备像素之上,操作系统为开发者进行抽象,提供了逻辑像素的概念;
比如你购买了一台显示器,在操作系统上是以1920x1080设置的显示分辨率,那么无论你购买的是2k、4k的显示器,对于开发者来说,都是 1920x1080的大小。
◼ CSS 像素
CSS中我们经常使用的单位也是pixel,它在默认情况下等同于设备独立像素(也就是逻辑像素)
毕竟逻辑像素才是面向我们开发者的。
◼ 我们可以通过JavaScript中的screen.width和screen.height获取到电脑的逻辑分辨率:
DPR、 PPI 、 DPI
◼ DPR:device pixel ratio
2010年,iPhone4问世,不仅仅带来了移动互联网,还带来了Retina屏幕;
Retina屏幕翻译为视网膜显示屏,可以为用户带来更好的显示;
在Retina屏幕中,一个逻辑像素在长度上对应两个物理像素,这个比例称之为设备像素比(device pixel ratio);
我们可以通过window.devicePixelRatio获取到当前屏幕上的DPR值;
◼ PPI (了解):每英寸像素(英语:Pixels Per Inch,缩写:PPI)
通常用来表示一个打印图像或者显示器上像素的密度;
前面我们提过1英寸=2.54厘米,在工业领域被广泛应用;
CSS 编写的痛点
◼ CSS 作为一种 样式语言 , 本身用来 给HTML元素添加样式 是没有问题的.
◼ 但是目前前端项目已经越来越复杂, 不再是简简单单的几行****CSS****就可以搞定的, 我们需要几千行甚至上万行的CSS来完成页面的美化工作.
◼ 随着代码量的增加, 必然会造成很多的编写不便:
比如大量的重复代码, 虽然可以用类来勉强管理和抽取, 但是使用起来依然不方便;
比如无法定义变量(当然目前已经支持), 如果一个值被修改, 那么需要修改大量代码, 可维护性很差; (比如主题颜色)
比如没有专门的作用域和嵌套, 需要定义大量的id/class来保证选择器的准确性, 避免样式混淆;
等等一系列的问题;
◼ 所以有一种对CSS称呼是 “面向命名编程”;
◼ 社区为了解决CSS面临的大量问题, 出现了一系列的CSS预处理器(CSS_preprocessor)
CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成CSS的程序;
市面上有很多CSS预处理器可供选择,且绝大多数CSS预处理器会增加一些原生CSS不具备的特性;
代码最终会转化为CSS来运行, 因为对于浏览器来说只识别CSS;
常见的CSS预处理器
◼ 常见的预处理器有哪些呢? 目前使用较多的是三种预处理器:
◼ Sass/Scss:
2007年诞生,最早也是最成熟的CSS预处理器,拥有ruby社区的支持,是属于Haml(一种模板系统)的一部分;
目前受LESS影响,已经进化到了全面兼容CSS的SCSS;
◼ Less:
2009年出现,受SASS的影响较大,但又使用CSS的语法,让大部分开发者更容易上手;
比起SASS来,可编程功能不够,不过优点是使用方式简单、便捷,兼容CSS,并且已经足够使用;
另外反过来也影响了SASS演变到了SCSS的时代;
著名的Twitter Bootstrap就是采用LESS做底层语言的,也包括React的UI框架AntDesign。
◼ Stylus:
2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持;
语法偏向于Python, 使用率相对于Sass/Less少很多
认识Less
◼ 什么是Less呢? 我们来看一下官方的介绍:
- It's CSS, with just a little more.
◼ Less (Leaner Style Sheets 的缩写) 是一门CSS 扩展语言, 并且兼容CSS。
Less增加了很多相比于CSS更好用的特性;
比如定义变量、混入、嵌套、计算等等;
Less最终需要被编译成CSS运行于浏览器中(包括部署到服务器中);
编写Less代码
◼ 我们可以编写如下的Less代码:
less代码的编译
◼ 这段代码如何被编译成CSS代码运行呢?
◼ 方式一:下载Node环境,通过npm包管理下载less工具,使用less工具对代码进行编译;
因为目前我们还没有学习过Node,更没有学习过npm工具;
所以先阶段不推荐大家使用less本地工具来管理;
后续我们学习了webpack其实可以自动完成这些操作的;
◼ 方法二:通过VSCode插件来编译成CSS或者在线编译
◼ 方式三:引入CDN的less编译代码,对less进行实时的处理;
<script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
◼ 方式四:将less编译的js代码下载到本地,执行js代码对less进行编译;
Less语法一:Less兼容CSS
◼ Less语法一:Less是兼容CSS的
所以我们可以在Less文件中编写所有的CSS代码;
只是将css的扩展名改成了.less结尾而已;
Less语法二 – 变量(Variables)
◼ 在一个大型的网页项目中,我们****CSS****使用到的某几种属性值往往是特定的
比如我们使用到的主题颜色值,那么每次编写类似于#f3c258格式的语法;
一方面是记忆不太方便,需要重新编写或者拷贝样式;
另一方面如果有一天主题颜色改变,我们需要修改大量的代码;
所以,我们可以将常见的颜色或者字体等定义为变量来使用;
◼ 在Less中使用如下的格式来定义变量;
@变量名: 变量值;
Less语法三 – 嵌套(Nesting)
◼ 在之前的项目中,当我们需要找到一个内层的元素时,往往需要嵌套很多层的选择器
◼ Less提供了选择器的嵌套
◼ 特殊符号: & 表示当前选择器的父级
Less语法四 – 运算(Operations)
◼ 在Less中,算术运算符 +、-、、/ 可以对任何数字、颜色或变量进行运算。*
算术运算符在加、减或比较之前会进行单位换算,计算的结果以最左侧操作数的单位类型为准;
如果单位换算无效或失去意义,则忽略单位;
Less语法五 – 混合(Mixins)
◼ 在原来的CSS编写过程中,多个选择器中可能会有大量相同的代码
我们希望可以将这些代码进行抽取到一个独立的地方,任何选择器都可以进行复用;
在less中提供了混入(Mixins)来帮助我们完成这样的操作;
◼ 混合(Mixin)是一种将一组属性从一个规则集(或混入)到另一个规则集的方法。
◼ 注意:混入在没有参数的情况下,****小括号可以省略,但是不建议这样使用****;
Less语法五 – 混合(Mixins)
◼ 混入也可以传入变量(暂时了解)
◼ Less语法六:映射(Maps)
◼ 混入和 映射 结合:混入也可以当做一个自定义函数来使用(暂时了解)
less其他语法补充
◼ Less语法七:extend继承
和mixins作用类似,用于复用代码;
和mixins相比,继承代码最终会转化成并集选择器;
◼ Less语法八:Less内置函数
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。
less其他语法补充
◼ Less语法九:作用域(Scope)
在查找一个变量时,首先在本地查找变量和混合(mixins);
如果找不到,则从“父”级作用域继承;
◼ Less语法十:注释(Comments)
- 在Less中,块注释和行注释都可以使用;
◼ Less语法十一:导入(Importing)
导入的方式和CSS的用法是一致的;
导入一个 .less 文件,此文件中的所有变量就可以全部使用了;
如果导入的文件是 .less 扩展名,则可以将扩展名省略掉;
认识Sass和Scss
◼ 事实上,最初Sass 是Haml的一部分,Haml 是一种模板系统,由 Ruby 开发者设计和开发。
◼ 所以,Sass的语法使用的是类似于Ruby的语法,没有花括号,没有分号,具有严格的缩进;
◼ 我们会发现它的语法和CSS区别很大,后来官方推出了全新的语法SCSS,意思是Sassy CSS,他是完全兼容CSS的。
◼ 目前在前端学习SCSS直接学习SCSS即可:
SCSS的语法也包括变量、嵌套、混入、函数、操作符、作用域等;
通常也包括更为强大的控制语句、更灵活的函数、插值语法等;
大家可以根据之前学习的less语法来学习一些SCS语法;
◼ 目前大家掌握Less的使用即可;
什么是移动端适配?
◼ 移动互联网的快速发展,让人们已经越来越习惯于使用手机来完成大部分日常的事务。
前端我们已经学习了大量HTML、CSS的前端开发知识,并且也进行了项目实战;
这些知识也同样适用于移动端开发,但是如果想让一个页面真正适配于移动端,我们最好多了解一些移动端的知识;
◼ 移动端开发目前主要包括三类:
原生App开发(iOS、Android、RN、uniapp、Flutter等)
小程序开发(原生小程序、uniapp、Taro等)
Web页面(移动端的Web页面,可以使用浏览器或者webview浏览)
◼ 因为目前移动端设备较多,所以我们需要对其进行一些适配。
◼ 这里有两个概念:
自适应:根据不同的设备屏幕大小来自动调整尺寸、大小;
响应式:会随着屏幕的实时变动而自动调整,是一种自适应;
认识视口viewport
◼ 在前面我们已经简单了解过视口的概念了:
在一个浏览器中,我们可以看到的区域就是视口(viewport);
我们说过fixed就是相对于视口来进行定位的;
在PC端的页面中,我们是不需要对视口进行区分,因为我们的布局视口和视觉视口是同一个;
◼ 但是在移动端,不太一样,你布局的****视口****和你可见的视口是不太一样的。
这是因为移动端的网页窗口往往比较小,我们可能会希望一个大的网页在移动端可以完整的显示;
所以在默认情况下,移动端的布局视口是大于视觉视口的;
◼ 所以在移动端,我们可以将视口划分为三种情况:
布局视口(layout viewport)
视觉视口(visual layout)
理想视口(ideal layout)
◼ 这些概念的区分,事实上来自ppk,他也是对前端贡献比较大的一个人(特别是在移动端浏览器)
布局视口和视觉视口
◼ 布局视口(layout viewport)
◼ 默认情况下,一个在PC端的网页在移动端会如何显示呢?
第一,它会按照宽度为980px来布局一个页面的盒子和内容;
第二,为了显示可以完整的显示在页面中,对整个页面进行缩小;
◼ 我们相对于980px布局的这个****视口****,称之为****布局视口(layout viewport)****;
- 布局视口的默认宽度是980px;
◼ 视觉视口(visual viewport)
如果默认情况下,我们按照980px显示内容,那么右侧有一部分区域 就会无法显示,所以手机端浏览器会默认对页面进行缩放以显示到用 户的可见区域中;
那么显示在可见区域的这个视口,就是视觉视口(visual viewport)
◼ 在Chrome上按shift+鼠标左键可以进行缩放。
理想视口(ideal viewport)
◼ 如果所有的网页都按照980px在移动端布局,那么最终页面都会被缩放显示。
事实上这种方式是不利于我们进行移动的开发的,我们希望的是设置100px,那么显示的就是100px;
如何做到这一点呢?通过设置理想视口(ideal viewport);
◼ 理想视口(ideal viewport):
默认情况下的layout viewport并不适合我们进行布局;
我们可以对layout viewport进行宽度和缩放的设置,以满足正常在一个移动端窗口的布局;
这个时候可以设置meta中的viewport;
移动端适配方案
◼ 移动端的屏幕尺寸通常是非常繁多的,很多时候我们希望在不同的屏幕尺寸上显示不同的大小;
- 比如我们设置一个100x100的盒子
✓ 在375px的屏幕上显示是100x100; ✓ 在320px的屏幕上显示是90+x90+; ✓ 在414px的屏幕上显示是100+x100+;
- 其他尺寸也是类似,比如padding、margin、border、left,甚至是font-size等等;
◼ 这个时候,我们可能可以想到一些方案来处理尺寸:
- 方案一:百分比设置;
✓ 因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一;
✓ 所以百分比在移动端适配中使用是非常少的;
方案二:rem单位+动态html的font-size;
方案三:vw单位;
方案四:flex的弹性布局;
适配方案 – rem+动态html的font-size
◼ rem单位是相对于html元素的font-size来设置的,那么如果我们需要在不同的屏幕下有不同的尺寸,可以动态的修改html的 font-size尺寸。
◼ 比如如下案例:
1.设置一个盒子的宽度是2rem;
2.设置不同的屏幕上html的font-size不同;
◼ 这样在开发中,我们只需要考虑两个问题:
问题一:针对不同的屏幕,设置html不同的font-size;
问题二:将原来要设置的尺寸,转化成rem单位;
rem的font-size尺寸
◼ 方案一:媒体查询
可以通过媒体查询来设置不同尺寸范围内的屏幕html的font-size尺寸;
缺点:
✓ 1.我们需要针对不同的屏幕编写大量的媒体查询;
✓ 2.如果动态改变尺寸,不会实时的进行更新;
◼ 方案二:编写js代码
如果希望实时改变屏幕尺寸时,font-size也可以实时更改,可以通过js代码;
方法:
✓ 1.根据html的宽度计算出font-size的大小,并且设置到html上;
✓ 2.监听页面的实时改变,并且重新设置font-size的大小到html上;
◼ 方案三:lib-flexible库
- 事实上,lib-flexible库做的事情是相同的,你也可以直接引入它;
rem的单位换算
◼ 方案一:手动换算
比如有一个在375px屏幕上,100px宽度和高度的盒子; 我们需要将100px转成对应的rem值;
100/37.5=2.6667,其他也是相同的方法计算即可;
◼ 方案二:less/scss函数
rem的单位换算
◼ 方案三:postcss-pxtorem
- 目前在前端的工程化开发中,我们可以借助于webpack的工具来完成自动的转化;
◼ 方案四:VSCode插件
- px to rem 的插件,在编写时自动转化;
考拉海购设计稿
适配方案 - vw
◼ 在flexible GitHub****上已经有写过这样的一句话:
◼ 所以它更推荐使用viewport的两个单位****vw****、wh。
◼ vw的兼容性如何呢?
vw和rem的对比
◼ rem事实上是作为一种过渡的方案,它利用的也是****vw****的思想。
前面不管是我们自己编写的js,还是flexible的源码;
都是将1rem等同于设计稿的1/10,在利用1rem计算相对于整个屏幕的尺寸大小;
那么我们来思考,1vw不是刚好等于屏幕的1/100吗?
而且相对于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之前所有的优点;
◼ vw我们只面临一个问题,将尺寸换算成vw的单位即可; ◼ 所以,目前相比于rem,更加推荐大家使用vw(但是理解rem依然很重要)
vw的单位换算
◼ 方案一:手动换算
比如有一个在375px屏幕上,100px宽度和高度的盒子;
我们需要将100px转成对应的vw值;
100/3.75=26.667,其他也是相同的方法计算即可;
◼ 方案二:less/scss函数
vw的单位换算
◼ 方案三:postcss-px-to-viewport-8-plugin
- 和rem一样,在前端的工程化开发中,我们可以借助于webpack的工具来完成自动的转化;
◼ 方案四:VSCode插件
- px to vw 的插件,在编写时自动转化;