1. CSS 定位
(1) div分层
- 布局是屏幕上面的(x y轴),定位是垂直于屏幕的(z轴)
- 内联子元素 > 浮动元素 > 块级元素 > border > background
(2) position
- static 当前元素在文档流中(默认值)
- relative 当前元素在文档流中,所占位置不变,但显示位置相对偏移(相对于自己),用来给absolute元素做父级元素
- absolute 绝对定位必须要有父元素,必须知道基准于哪个元素,父级元素加
position: relative;
(它会找祖先元素中最近的一个不是static定位的元素,可以相对于"爷爷元素"定位)
Example: 鼠标提示
button {
position: relative;
}
button span {
position: absolute;
white-space: nowrap; /*不换行*/
bottom: calc(100% + 2px); /*在100%的基础上再+2px*/
left: 50%; /*从基准元素50%位置开始*/
transform: translateX(-50%); /*相对基准元素居中*/
}
button span {
display: none;
}
/*鼠标悬浮button位置显示span*/
button:hover span{
display: inline-block;
}
- fixed 相对于视口定位(页面可视区域)-> 用于锁死广告位置
ps.
a. 如果父元素有transform属性,fixed定位将产生bug
b. 手机页面最好不用fixed,很多bug - sticky 原位置文档流,快要超出可视范围时粘住顶端,但兼容性很差 -> 适合导航栏
(3) 层叠上下文
-
当position为非static时,其成为定位元素,根据下图z-index确定位置,正数在内联子元素上,负数在background下
-
z-index 默认值为auto,auto计算出来的值为0,z-index越大越在上层 (但如果其所在父元素的z-index比另外元素的父元素z-index低,则按父元素z-index大小层叠),不要写
z-index: 9999;
要学会管理z-index
创建层叠上下文的属性:MDN 文档
需要记忆:z-index/flex/opacity/transform
【补充知识】透明度background alpha和opacity的区别:
background影响元素背景,opacity影响整个元素
csdn 解释
1、首先先看要比较的两个元素是否处于同一个层叠上下文中: 1.1如果是,谁的层叠等级大,谁在上面(怎么判断层叠等级大小呢?——看“层叠顺序”图)。 1.2如果两个元素不在统一层叠上下文中,请先比较他们所处的层叠上下文的层叠等级。 2、当两个元素层叠等级相同、层叠顺序相同时,在DOM结构中后面的元素层叠等级在前面元素之上。负z-index可能因父元素产生层叠上下文的属性而失效
2. CSS 动画
2.1 先导
(1) 概念
- 每个静止的画面都叫帧
- 播放速度:每秒24帧(影视)或每秒30帧(游戏)
(2) 简单例子 - 矩形框的移动
- 改变left
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
position: relative;
left: 0;
}
var n = 1
/* 计时器 */
var id = setInterval(() => {
console.log(n)
if (n <= 100) {
demo.style.left = n / 100 * 300 + 'px'
n = n + 1
}else{
clearInterval(id) /*停止计时器*/
}
}, 1000 / 30) /*30帧,此处为间隔的时间*/
- 用transform渲染,性能更高,不需要repaint
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
transition: all 1s linear;
}
#demo.end{
transform: translateX(300px);
}
setTimeout(()=>{
demo.classList.add('end') /*加上end类*/
},0)
(3) 查看渲染性能
开发者工具 -> Console -> Rendering -> 勾选Paint flashing
(4) 浏览器渲染过程
(5) 一般用JS来更新样式
-
div.style.background = 'red'
改变背景色 -
div.style.display = 'none'
使元素消失 -
div.classList.add = 'red'
给元素增加类(推荐,比改变style更快 每个类可包含多个style) -
div.remove()
删除节点
(6) 三种更新方式
-
三步重新进行,Layout > Paint > Compose
如div.remove()跳过Layout,进行Paint > Compose
如改变背景色跳过Layout和Paint,只进行Compose
如transform
(7) CSS 动画优化
- Google全文
- JS优化:使用 requestAnimationFrame 代替 setTimeout 或 setInterval
- CSS优化:使用 will-change 或 translate
2.2 transform
(1) transform 完整语法:MDN
(2) 常用功能
- 设置动画的时间:
transition: all 1s;
- 组合效果用空格隔开:
transform: effect1 effect2;
A. translate 位移(X Y Z 轴), 参数为长度或百分数(基于元素自己宽度的百分比)
translateX(Npx)
translateY(Npx)
translateZ(Npx)
【开启Z轴需要增加视点】在父元素添加属性:
.wrapper{
perspective: 1000px; /*视点设置为正中心1000像素*/
}
- 简写
a. 移动X, Y轴:translate(N1px, N2px)
b. 移动X, Y, Z轴:translate3d(N1px, N2px, N3px)
- 通常用
translate(-50%, -50%)
使子元素居中
transform: translate(-50%, -50%);
<=>transform: translateX(-50%) translateY(-50%);
.wrapper {
position: relative;
}
#demo {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
B. scale 缩放
-> 用的较少,容易出现模糊
- scale(倍数1, 倍数2)
- scaleX(倍数)
- scaleY(倍数)
C. rotate 旋转
- rotate(Ndeg) deg度数(正数顺时针)
- rotateX(Ndeg) 沿X轴旋转
- rotateY(Ndeg) 沿Y轴旋转
- rotate3d 很复杂
D. skew 倾斜变形
-> 矩形变平行四边形
- skewX(Ndeg) 沿X轴倾斜
- skewY(Ndeg) 沿Y轴倾斜
(3) 实践:跳动的心
- 思路先做心形,再放动画
- 心形可由一个旋转45度的正方形和两个圆组成
- http://js.jirengu.com/yecib/1/edit?html,css,output
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
* {margin: 0; padding:0; box-sizing: border-box;}
#heart {
position: relative;
display: inline-block;
transition: all .5s; /*0.5s可以写成.5s*/
}
# heart:hover {
transform: scale(1.5);
}
#heart > bottom {
width: 50px;
height: 50px;
background: red;
position: absolute;
transform: rotate(45deg);
}
#heart > left {
width: 50px;
height: 50px;
background: red;
border-radius: 50% 0 0 50%; /*做两个圆角*/
position: absolute;
bottom: 100%;
right: 100%;
transform: rotate(45deg) translateX(31px); /*向右下移动*/
}
#heart > right {
width: 50px;
height: 50px;
background: red;
border-radius: 50% 50% 0 0;
position: absolute;
bottom: 100%;
left: 100%;
transform: rotate(45deg) translateY(31px);
}
2.3 transition
(1) 作用:添加中间帧
-
transition: width 1s;
如果width变化,则添加1秒过渡动画
(2) 语法: transition: 属性名 时长 过渡方式 延迟;
A. 属性名
- all 表所有属性
B. 时长:动画持续时间
- 时间单位可以为ms或s
C. 过渡方式
- linear 匀速变化
- ease 先快后慢
- ease-in 淡入
- ease-out 淡出
- ease-in-out 淡入淡出
D. 延迟:过多久开始动画
- 时间单位可以为ms或s
(3) Example: 元素慢慢消失,调透明度
或调visibility,从visible => hidden
# demo {
width: 100px;
height: 100px;
border: 1px solid red;
transition: all 1s;
opacity: 1;
}
/*这里也可用hover演示*/
# demo.end {
width: 200px;
height: 200px;
opacity: 0;
}
x.onlick = () => {
demo.classList.add('end')
setTimeout(() => { demo.remove() }, 1000) /*定时器 1s以后删除元素,防止其占位置*/
}
(4) 有中间帧情况需要设置多个类进行多次transform
.a ==> transform ==> .b ==> transform ==> .c
x.onlick = () => {
demo.classList.add('b')
setTimeout(() => {
demo.classList.remove('b')
demo.classList.add('c')
}, 1000)
}
2.4 animation
(1) 用法
- 将关键帧写入keyframes里(注意下一个关键帧transform效果要叠加上一个关键帧效果实现连续的动画) => keyframes挂载在元素的一个类的属性animation中并设置动画时间 => 通过js挂载类启动
- keyframes也可以写成
from{ } to{ }
的形式 - animation加上forwards可以停滞在最后一帧:
animation: bubble 1.0s forwards;
Example:
demo.a {
animation: xxx 1.5s; /*keyframes xxx已定义在下面*/
}
/*百分数表示动画进程百分比*/
@keyframs xxx {
0% {
transform: none;
}
66% {
transform: translateX(200px);
}
100% {
/*叠加60%的effects*/
transform: translateX(200px) translateY(200px);
}
}
button.onlick = () => {
demo.classList.add('a')
}
(2) animation语法
(3) 动画暂停与恢复
- 设置元素的
animationPlayState
属性
/*暂停动画*/
button1.onlick = () => {
demo.style.animationPlayState = 'paused'
}
/*恢复动画*/
button2.onlick = () => {
demo.style.animationPlayState = 'running'
}
(4) 实践:使刚才的红心跳动
#heart {
position: relative;
animation: jump 800ms infinite alternate;
}
@keyframes jump {
from {transform: scale(1.0);}
to{transform: scale(1.5);}
}