昔洛 的个人博客

Bug不空,誓不成佛

  menu
70 文章
14633 浏览
7 当前访客
ღゝ◡╹)ノ❤️

记录前端学习------CSS3 2D/3D动画即移动端布局(上)

阶段学习内容

  • CSS 2D
    • 平移 (translate)
    • 居中方案
    • 旋转 (rotate)
    • 缩放 (scale)
  • 动画
    • 属性
    • 案例
  • 前缀
  • CSS 3D 效果
    • 移动(translate3d)
    • 视距(perspective)
    • 旋转(rotate3d)
    • 缩放(scale3d)
  • 布局基础
    • 流式布局

一、CSS3 2D效果

1、平移

CSS3 支持2D 平面操作,2D 平面是由两个坐标完成即 x轴,y轴,对于浏览器(其他计算机编程大多相同)来说,它的默认平面坐标系如下所示:
image.png
原点即为浏览器左上角。

语法:

/* 写两个像素值即为 x,y轴的平移 */
transform: translate(100px,100px);
/* 写两个百分比即相对自身的宽高进行 x,y 轴的平移 */
transform: translate(50%,50%);
/* 单个写 */
transform: translateX(10px);
transform: translateY(10px);
/* 元素不会脱标 */

2、居中方案

盒子居中的方式有很多,主流的两种如下:
① 定位 + margin
代码如下:

.father {
	position: relative; /* 子绝父相 */
}
.child {
	width: 100px;
	height: 100px;
	background-color: #222;
	position: absolute;
	left: 50%;
	top: 50%;
	margin-top: -50px;
	margin-left: -50px;
}

特点:可以使元素具有行内块效果,元素脱标,需要计算移动距离,麻烦。
② 定位 + translate
代码如下:

.father {
	position: relative;
}
.child {
	width: 100px;
	height: 100px;
	background-color: #222;
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%,-50%);
}

特点:用法简单,不要要再进行距离的就算,方便快捷,但对行内元素无效。

3、旋转

语法:
transform: rotate(45deg);/*顺时针旋转*/
特点:

  • 默认:为中心点旋转
  • 扩展:伪元素
    • 伪元素:页面 HTML 结构中没有的元素,但是页面中却真实存在;
    • 常用:做小图标引用
    • 特点:
      • 行内元素
      • content 属性不能丢
      • div::before:hover写法错误,应写:div:hover::before
      • 伪元素只能用在双标签上。

小示例如下:

<style>
	.test1 {
		width: 200px;
		height: 30px;
		border: 1px solid black;
		position: relative;
	}
	.test1::after {
		content: "";
		width: 0;
		height: 0;
		border-width: 8px 8px 0 8px;
		border-color: blue transparent transparent transparent;
		border-style: solid;
		position: absolute;
		right: 0%;
		top: 30%;
		transition: 0.4s;
	}
	.test1:hover::after {
		transform: rotate(180deg);
	}
</style>
<body>
	<div class="test1">
	</div>
</body>

中心点

  • 改变中心点位置,2D(旋转、缩放)的效果不一样;
  • 语法:默认旋转的基准中心点是:50% 50%;
/* 具体 px 值 */
transform-origin: 100px 100px;
/* 百分数 */
transform-origin: 50% 50%;
/* 方位名词 */
transform-origin: left bottom;
/* 单个参数,第二个参数默认为 50% */
transform-origin: 0;

4、缩放 scale

  • 场景:鼠标悬浮,盒子放大;
  • 后面的参数为倍数;(无单位)

代码如下:

/* 长度、宽度方向 缩放 */
transform: scale(2,3);
/* 长度、宽度方向 缩放为同一个比例 */
transform: scale(2);
transform: scale(0.5);
  • 特点:
    • 会受中心点影响;
    • 下面的子元素、文字、属性会被缩放;
    • 使用场景:放大父级元素,下面的所有子元素都会跟着被放大;

2D简写

  • 更为简洁地综合起来写2D相关属性;
  • 单独多次写,不生效,因为下面会把上面的层叠掉;
transform: translate(x,y);
transform: rotate(90deg);
/* 最终效果为旋转90度,上面那个平移不生效,因为被层叠掉 */
  • 使用顺序不同,出现的效果不同,因为旋转会改变初始轴向
/* 移动在旋转前面 */
transform: translate(x,y) rotate(90deg) scale(x,y);
/* 旋转在前面 */
transform: rotate(90deg) translate(x,y) scale(x,y); /* 旋转后轴向被改变 */

二、动画 animation

页面内实现一些动画,可以循环播放,也可以播放及其,是页面丰富多彩。

1、介绍

语法:

  • 三要素:定义、调用、时间
/* 1、定义 */
@keyframes dong_hua {
	/* 开始状态 */
	from {
		transform: translateX(0px);
		background-color: red;
	}
	/* 结束状态 */
	to {
		transform: translateX(1000px);
		background-color: #222;
	}
	
	div {
		/* 调用 */
		animation-name: dong_hua;
		/* 时间 */
		animation-duration: 3s;
	}
}

重点

  • 和过度的区别:动画可以实现更多的控制,且可连续自动播放
  • 拓展思路:节点里可以写2D转化,也可以写各种 CSS 属性

2、动画序列

  • 时间节点,可以更为精确的控制动画的多个状态节点,动画的变化更为丰富;

语法

@keyframes name {
	/* 开始状态 */
	form {
	}
	/* 结束状态 */
	to {
	}
}
@keyframes name {
	/* 开始状态 */
	0% {
	}
	50% {
	}
	75% {
	}
	/* 结束状态 */
	100% {
	}
}

重点

  • 动画序列就是时间节点时的状态;
  • 动画从开始执行到经过动画节点,都是基于上一个状态进行变化;

3、动画属性

属性如下:

属性描述
@keyframes规定动画
animation所有动画属性的简写属性,除了animation-play-state属性
animation-name规定@keyframes动画的名称
animation-duration规定动画完成一个周期所花费的秒或毫秒,默认是0
animation-timing-function规定动画的速度曲线,默认是“ease”
animation-delay规定动画何时开始(延迟几秒),默认是0
animation-iteration-count规定动画播放的次数,默认是1,无穷是 infinite
animation-direction规定动画是否在下一周期逆向播放,默认是"normal",alternate 逆播放
animation-play-state规定动画是否正在运行或暂停,默认是"running",还有"pause"
animation-fill-mode规定动画结束后状态,保持forwards,回到起始backwards
  • animation-timing-function: 动画 运动 速度曲线:速度快慢的体现;
div {
	/* 匀速 */
	animation-timing-function: linear;
	/* 慢-快-慢 默认值 */
	animation-timing-function: ease;
	/* 慢-快 */
	animation-timing-function: ease-in;
	/* 快-慢 */
	animation-timing-function: ease-out;
	/* 慢-快-慢 */
	animation-timing-function: ease-in-out;
}
  • animation-timing-function: steps(n) 分步完成,实现老电影一帧一帧,多用于帧动画
  • animation-delay: 动画推迟多久执行,动画等待
  • animation-iteration-count: 循环播放次数 1 2 infinite(无限次)
div {
	/* 指定播放次数 */
	animation-iteration-count: 2;
	/* 无限次数设置 */
	animation-iteration-count: infinite;
}
  • animation-direction: 循环方向
div {
	/* 默认值 0-100 */
	animation-direction: normal;
	/* 100-0 */
	animation-direction: reverse;
	/* 0-100-0 */
	animation-direction: alternate;
	/* 100-0-100 */
	animation-direction: alternate-reverse;
}
  • animation-fill-mode: 动画等待或者结束的状态;
div {
	/* 1、动画结束后,元素样式停留在 100% 的样式 */
	animation-fill-mode: forwards;
	/* 2、在延迟等待的时间内,元素样式停留在 0% 的样式,动画结束时,回到 div 本身的样式(回到起始状态)*/
	animation-fill-mode: backwards;
	/* 3、同时设置了 forwards 和 backwards 两个属性值在动画等待时间,样式为元素样式停留在 0% 的样式,动画结束时,元素样式停留在 100% 的样式 */
	animation-fill-mode: both;
}
  • animation-play-state: 暂停和播放
div {
	/* 1 播放 */
	animation-play-state: running;
	/* 2 暂停 */
	animation-play-state: paused;
}

注意

  • 设置 animation-direction 需设置动画多次执行
  • 设置 animation-fill-mode,设置 forwards,动画不能设置无限执行。

简写
语法:动画名称 持续时间 速度曲线 等待时间 执行次数 执行的方向 动画等待或结束的状态

div {
	animation: name duration timing-function delay iteration-count direction fill-mode;
}
  • 组动画:需要用英文逗号隔开
    animation: name_1 5s linear,name_2 2s linear;

注意:animation-play-state 没有在简写内

三、前缀

  • 新特性,为了对各家浏览器更好的兼容,从这个方向想;

介绍

  • -moz-: 代表 firefox 浏览器私有属性
  • -ms-: 代表 ie 浏览器私有属性
  • -webkit-: 代表 Safari、Chrome 私有属性
  • -o-:代表 Opera 私有属性
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
  • 没有工程化工具,根据业务需要写这些前缀,解决样式的兼容;
  • 没有工程化工具,注意这些工具包的配置。webpack gulp

四、3D 效果

css3 支持 3D 空间的效果显示,首先基于浏览器的 2D 效果,在 x,y轴的基础上增加一条垂直浏览器的轴即为 z 轴,简单示例如下:
010.png

移动 translate3d

语法

div {
	/* 单独分开写 */
	transform: translateX(100px);
	transform: translateY(-100px);
	transform: translateY(100%);
	trnasform: translateZ(100px);
	/* 写在一起 */
	transform: translateX(100px) translateY(100px) translateZ(100px);
	/* 三个方向同时写的简写 x,y,z */
	transform: translate3d(100px,100px,100px);
}

注意

  1. XY 方向可以设置 px 值和 % (因为有宽高)
  2. Z 轴只能设置 px,设置 % 不生效(因为盒子没有厚度)

scale3d

可以让盒子在空间内缩放
语法:

/* 宽缩放 */
transform: scaleX(1);
/* 高缩放 */
transform: scaleY(1);
/* 厚度缩放,没有厚度没效果,有资料说用于矩阵变换 */
transform: scaleZ(1);
/* 宽、高 缩放一倍,厚度放大两倍
transform: scale3d(1,1,2);

视距 perspective

  • 视距是体现立体空间的第一步,用于设置被观测的物体的距离,有了距离就可以体现出近大远小的效果。

语法

  • 浏览器:拉开距离,保证盒子的移动能被观测到近大远小的效果
    perspective: 1000px
    013.png
  • 观测角度:不同的观测角度,透视感不同。语法加在谁上面?
    • 加在 body 上,全局形成透视感
    • 加在单个盒子上,单个盒子形成透视感
  • 值得设值:变化的距离成都不一样;
/* 父元素 */
body {
	perspective: 1000px;
}
/* 目标 */
div {
	width: 200px;
	height: 200px;
	background-color: aqua;
	margin: 100px auto;
	/* z 轴的移动 */
	transform: translateZ(0px);
}

旋转 rotate

3D 的旋转关注点:绕着哪条轴做正值顺时针旋转?
左手工具
014.png

  • 左手的大拇指指向某一轴的正方向
  • 其余手指的弯曲方向就是该元素绕着某一轴旋转的方向为顺时针正方向;
    语法:
img:hover {
	transform: rotateX(45deg);
	transform: rotateY(45deg);
	transform: rotateZ(-45deg);
}
/* 自定义轴向 */
img:hover {
	/* x,y,z 空间向量坐标,deg 为旋转度数 */
	transform: rotate3d(x,y,z,deg);
}

3D呈现 transform-style

  • 只要亲生子元素做 3D 转换,需要在其父亲上加 3D 呈现,这样子元素做的 3D 转换才能被看到;

作用:父元素控制子元素是否开启三维立体环境,让子元素做 3D 转换能有效果
语法:

/* 设置在有子元素的父级上 */
/* 默认值:不开启 */
transform-style: flat;
/* 给亲生子元素 开启 3D 环境 */
transform-style: preserve-3d;

与视距的区别:

  • 从两个方面入手:作用?加给谁?
  • 视距:
    • 近大远小,透视感;
    • body 所有的子元素、各自父亲;观测角度不同;
  • 3D 呈现:
    • 亲生子元素3D转化,课程现出来
    • 父亲上需要加 transform-style: preserve-3d;

简单3d动画案例如下:
点我查看效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>3D动态盒子旋转</title>
    <style>
        .p {
            width: 100px;
            height: 100px;
            /* 居中 */
            margin: 50px auto;
            position: relative;
            /* 让亲子元素可以进行3D效果 */
            transform-style: preserve-3d;
            /* 执行动画 */
            animation: self_rotate 2.0s linear infinite;
        }
        .son {
            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            /* 先让所有元素定位叠到一起 */
            position: absolute;
            left: 0;
            top: 0;
            font-size: 50px;
        }
        .p .son:nth-child(1) {
            background-color: red;
        }
        .p .son:nth-child(2) {
            background-color: pink;
            /* 先改变旋转轴为最左边,然后进行 y 轴顺时针旋转90度 */
            transform-origin: left;
            transform: rotateY(90deg);
        }
        .p .son:nth-child(3) {
            background-color: green;
            /* 先改变旋转轴为最右边,然后进行 y 轴逆时针旋转90度 */
            transform-origin: right;
            transform: rotateY(-90deg);
        }
        .p .son:nth-child(4) {
            background-color: blue;
            /* 让其Y轴旋转180后然后z轴负方向移动200距离 */
            transform: translateZ(-100px) rotateY(180deg);
        }
        .p .son:nth-child(5) {
            background-color: purple;
            /* 让其旋转轴为顶边,然后绕 x 轴逆时针90旋转即可盖到盒子上面 */
            transform-origin: top;
            transform: rotateX(-90deg);
        }
        .p .son:nth-child(6) {
            background-color: yellow;
            /* 让其旋转轴为底边边,然后绕 x 轴顺时针90旋转即可盖到盒子上面 */
            transform-origin: bottom;
            transform: rotateX(90deg);
        }

        /* 定义动画 */
        @keyframes self_rotate {
            from {
                transform: rotate3d(1,1,1,0);
            }
            to {
                transform: rotate3d(1,1,1,360deg);
            }
        }
    </style>
</head>
<body>
    <div class="p">
        <div class="son">1</div>
        <div class="son">2</div>
        <div class="son">3</div>
        <div class="son">4</div>
        <div class="son">5</div>
        <div class="son">6</div>
    </div>
</body>
</html>

五、流式布局

  • 流式布局是比较常用的传统的布局方式,通过对盒子的宽度用百分数的控制;
  • 移动端现状
    • 内核:国产主流手机浏览器,内核 WebKit,主要处理兼容目标。
    • 手机分辨率:碎片化太多;2K 手机等

viewport 视口

  • PC 端的页面直接放入手机屏显示,文字太小,不友好。
  • 手指缩放,可以正常看见元素,但是内容超出,不友好;

原因就是 HTML 默认的宽 980px 不合适

解决方法如下:

  • 默认:HTML 980px; 不友好
  • 目标:手机屏幕多大,HTML 宽度就设置多大
  • meta 标签 viewport 标准写法:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  • width=device-width:改变 HTML 默认的980px,设置HTML的宽度为屏幕的宽度
  • user-scalable:是否允许用户缩放屏幕值:no(0不允许) yes(1允许);
  • initial-scale: 初始化缩放比例; 1.0: 不缩放;
  • maximum-scale:用户对页面的最大缩放比例,值:比例
  • minimum-scale:用户对页面的最小缩放比例;值:比例

二倍图由来及相关概念

  • 屏幕尺寸:绝对单位,到哪里都不会变的单位

  • 物理像素点:客观存在的点,可以发光;做的越来越小,画面越来越多细腻,一个萝卜一个坑;

  • 屏幕分辨率:水平和垂直方向上物理像素点的个数;

  • 图片分辨率:水平和垂直颜色点

  • CSS像素:

    • 设置200px,在每个屏幕显示都是一样大;
    • 在640分辨率,自动算出需要提供400个物理像素点;
  • UI命名:

  • 二倍图由来

    • 设置 CSS 像素200px宽,320分辨率(200坑)、640分辨率(400坑)这样才显示一样
    • 像针对640分辨率手机屏后面需要400个物理像素点,要求设计给400*400像素图;对应我们CSS设置200px,有二倍的关系;
  • background-size 用法:

/* 图片没有设置大小,会按照自己的分辨率显示 */
background: url('./imgs/dog.jpg') no-repeat;
/* 两个参数设置背景图片大小,按照设置进行显示,不一定保证比例 */
background-size: 100px 100px;
/* 一个固定值px,设置宽度,高度自适应 */
background-size: 400px;
/* %:相对于当前盒子的宽度 */
background-size: 50%;

/* 关键字 cover:覆盖,绝对不留白 */
background-size: cover;
/* contain: 包含,绝对要显示全图片 */
background-size: contain;

二倍精灵图使用步骤

  • 步骤:
    • 在 FW 内:先等比缩小图的一半,在缩小的图内进行图标位置测量。
    • 在代码:引入图,按照刚才的测量,写入图标的坐标;
    • 设置图片大小:按照缩小一半后的宽高进行设置的。
  • 注意:测量完成后,不要保存图,不然二倍图废了

CSS3 盒子模型

魔法盒子:

/* 传统:盒子宽度 = CSS 中设置 width+border+padding */
box-sizing: content-box;
/* CSS3盒子模型:盒子的宽度=设置的 width,宽度里面包含了 border 和 padding */
box-sizing: border-box;
  • 使用场景:
    • 左侧固定,右侧随意拉伸;
    • 左右固定,中间随意拉伸;
内事不懂问百度,外事不懂问谷歌~