css transition 指南
css transition 指南
在本文中,我们将深入了解 CSS transition
,以及如何使用它们来创建丰富、精美的动画。
基本原理
我们创建动画时通常需要一些动画相关的 CSS
。
下面是一个按钮在悬停时移动但没有动画的示例:
<button class="btn">Hello World
</button><style>.btn {width: 100px;height: 100px;border-radius: 50%;border: none;background: slateblue;color: white;font-size: 20px;font-weight: 500;line-height: 1;}.btn:hover {transform: translateY(-10px);}
</style>
当用户的鼠标停留在我们的按钮上时,此代码片段使用:hover
伪类指定附加的 CSS
声明,类似于js
中的onMouseEnter
中的事件。
为了向上移动元素,我们使用transform: translateY(-10px)
。 虽然我们可以用margin-top
来完成这项工作,但是transform: translate
是一种更好的方式。我们在下面会解释原因。
默认情况下,CSS
的更改会立即发生。眨眼间,我们的按钮已经传送到了新的位置!这与事物逐渐发生的自然世界规则格格不入。
我们可以指示浏览器使用transition
属性从一种状态值到另一种状态:
<button class="btn">Hello World
</button><style>.btn {width: 100px;height: 100px;border-radius: 50%;border: none;background: slateblue;color: white;font-size: 20px;font-weight: 500;line-height: 1;/* 添加transition属性 */transition: transform 2500ms;}.btn:hover {transform: translateY(-10px);}
</style>
transition
可以接受多个值,但通常只需要两个:
- 我们希望设置动画的属性的名称
- 动画的持续时间
如果我们计划对多个属性进行动画处理,则可以向其传递一个以逗号分隔的列表:
.btn {/* 设置变换和不透明度 */transition: transform 250ms, opacity 400ms;
}
.btn:hover {transform: scale(1.2);opacity: 0;
}
定时功能
当我们告诉一个元素从一个位置转换到另一个位置时,浏览器需要计算出每个“中间”帧应该是什么样子。
例如:假设我们在 1 秒的时间内从左向右移动一个元素。流畅的动画应以 60 fps 运行,这意味着我们需要在开始和结束之间存在 60 个单独的位置。
首先让它们均匀分布:
每个褪色的圆圈代表一个时刻。当圆圈从左向右移动时,这些是向用户显示的帧。
在此动画中,我们使用线性计时函数。这意味着元素以恒定的速度移动;我们的圆圈每帧移动相同的量。
CSS
中有多种计时函数可供我们使用,通过修改transition-timing-function
值就可以。
.btn {transition: transform 250ms;transition-timing-function: linear;
}
或者,我们可以将其直接传递给transition
属性:
.btn {transition: transform 250ms linear;
}
linear
平缓过渡,但是linear
并非是最好的选择——毕竟,现实世界中几乎没有什么东西是这样移动的。
ease-out
ease-out
就像一头野牛一样冲了过来,但它耗尽了能量。到最后,它就像一只昏昏欲睡的乌龟一样咕咕叫着。
如果我们要绘制元素随时间的位移图表,它看起来像这样:
这种方式最常用于当某些内容从屏幕外进入时的需求中。
ease-in
与ease-out
相反。它开始缓慢并加速。
正如我们所看到的,ease-out
对于从屏幕外进入视图的事物很有用。ease-in
自然对于相反的情况很有用:将某些内容移出视口的边界。
ease-in-out
它是前两个计时函数的组合。
这个定时函数是对称的。它具有相等的加速度和减速度。
ease
与 ease-in-out
不同的是,它不是对称的;它的特点是短暂的加速和大量的减速。
ease
是默认值。
自定义曲线
如果提供的内置选项不能满足我们的需求,还可以使用三次贝塞尔计时函数实现自定义缓动曲线。
.btn {transition:transform 250ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
}
cubic-bezier
函数需要 4 个数字,代表 2 个控制点。
本文暂时不讨论如何实现贝塞尔曲线,如果大家感兴趣可以自行查阅相关文档。
动画
之前,我们提到动画应该以 60 fps
运行。然而,当我们进行数学计算时,我们意识到这意味着浏览器只有 16.6 毫秒来绘制每一帧。时间真的不多(毕竟我们眨眼大约需要 100ms-300ms)。
如果我们的动画计算量太大,它就会显得卡顿和卡顿。由于设备无法跟上,帧将会丢失。
动画包含了非常多的知识,远远超出了本文介绍性教程的范围。但让我们可以来了解一些关键部分:
- 某些
CSS
属性的动画制作成本比其他属性高得多。例如,height
是一个非常昂贵的属性,因为它会影响布局。当一个元素的高度缩小时,会引起连锁反应;它的所有兄弟节点也需要向上移动,以填补空间! - 其他属性(例如
background-color
)动画制作成本较高。它们不会影响布局,但确实需要在每个帧上都重新涂上一层,这并不便宜。 transform
和opacity
这两个属性制作动画的成本非常低。如果动画当前调整诸如width
或left
之类的属性,则可以通过将其通过transform
来移动到极大地改进动画效果(尽管并不总是能够实现完全相同的效果)。- 需要针对低端设备进行动画测试。我们的开发环境可能比它快很多倍。
硬件加速
由于浏览器和操作系统的原因,可能会导致动画出现一些异常。
比如说下面的动图,在transition
开始和结束时文字似乎会出现轻微抖动。
发生这种情况是由于计算机的 CPU
和 GPU
之间的切换所致。
当我们使用transform
和opacity
为元素设置动画时,浏览器有时会尝试优化此动画。它将所有内容作为纹理传输到 GPU
,而不是对每一帧上的像素进行光栅化。GPU
非常擅长执行此类基于纹理的转换,因此,我们得到了非常流畅、高性能的动画。这称为“硬件加速”。
问题是:GPU
和 CPU
的渲染效果略有不同。当 CPU
将其交给 GPU
时,就会看到事情发生了轻微的变化。
不过我们可以通过添加以下 CSS
属性来解决这个问题
.btn {will-change: transform;
}
will-change
是一个属性,它允许我们向浏览器提示我们将为所选元素设置动画,并且它应该针对这种情况进行优化。
实际上,这意味着浏览器将始终让 GPU
处理该元素。CPU
和 GPU
之间不再需要切换,也不再需要“卡入到位”。
will-change
让我们有意识地了解哪些元素应该由硬件加速。浏览器对这些东西有自己的难以理解的逻辑,我们并不想让浏览器去
处理。
硬件加速其实也存在一定问题。
通过将元素的渲染委托给GPU
,它将消耗更多的视频内存,而这种资源是有限的,尤其是在低端移动设备上。
相关文章:

css transition 指南
css transition 指南 在本文中,我们将深入了解 CSS transition,以及如何使用它们来创建丰富、精美的动画。 基本原理 我们创建动画时通常需要一些动画相关的 CSS。 下面是一个按钮在悬停时移动但没有动画的示例: <button class"…...
LeetCode 面试题 02.05. 链表求和
文章目录 一、题目二、C# 题解 一、题目 给定两个用链表表示的整数,每个节点包含一个数位。 这些数位是反向存放的,也就是个位排在链表首部。 编写函数对这两个整数求和,并用链表形式返回结果。 点击此处跳转题目。 示例: 输入&a…...

一米脸书营销软件
功能优势 JOIN ADVANTAGE HOME PAGE MARKETING 公共主页营销 可同时对多个账户公共主页评论,点赞等 可批量邀请多个好友对Facebook公共主页进行评论点赞等,也可批量登录小号对自己公共主页进行点赞。 GROUP MARKETING 小组营销 可批量针对不同账户进行…...

vue 根据数值判断颜色
1.首先style样式给两种颜色 用:class 三元运算符判断出一种颜色 第一步:在style里边设置两种颜色 .green{color: green; } .orange{color: orangered; }在取数据的标签 里边 判断一种颜色 :class"item.quote.current >0 ?orange: green"<van-gri…...
Hugging Face 实战系列 总目录
PyTorch 深度学习 开发环境搭建 全教程 Transformer:《Attention is all you need》 Hugging Face简介 1、Hugging Face实战-系列教程1:Tokenizer分词器(Transformer工具包/自然语言处理) Hungging Face实战-系列教程1:Tokenize…...

国标视频云服务EasyGBS国标视频平台迁移服务器后无法启动的问题解决方法
国标视频云服务EasyGBS支持设备/平台通过国标GB28181协议注册接入,并能实现视频的实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。平台部署简单、可拓展性强,支持将接入的视频流进行全终端、全平台分发,分发的视频…...
HTML <th> 标签
实例 普通的 HTML 表格,包含两行两列: <table border="1"><tr><th>Company</th><th>Address</th></tr><tr><td>Apple, Inc.</td><td>1 Infinite Loop Cupertino, CA 95014</td></tr…...
HTTP/1.1协议中的响应报文
2023年8月30日,周三下午 目录 概述响应报文示例详述 概述 HTTP/1.1协议的响应报文由以下几个部分组成: 状态行(Status Line)响应头部(Response Headers)空行(Blank Line)响应体&a…...
TDengine函数大全-选择函数
以下内容来自 TDengine 官方文档 及 GitHub 内容 。 以下所有示例基于 TDengine 3.1.0.3 TDengine函数大全 1.数学函数 2.字符串函数 3.转换函数 4.时间和日期函数 5.聚合函数 6.选择函数 7.时序数据库特有函数 8.系统函数 选择函数 TDengine函数大全BOTTOMFIRSTINTERPLASTLAS…...
非关系型数据库Redis的安装
一、关系型数据库与非关系型数据库的区别:---------面试高频率问题 1、首先了解一下 什么是关系型数据库? 关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。 优点: 易于维护:都是使用…...
oracle 创建数据库
查询表空间的命令 select t1.name,t2.name from v$tablespace t1,v$datafile t2 where t1.ts# t2.ts#; CREATE TABLESPACE ORM_342_BETA DATAFILE /app/oracle/oradata/sysware/ORM_342_BETA.DBF size 800M --存储地址 初始大小800M autoextend on nex…...

wxWidgets从空项目开始Hello World
前文回顾 接上篇,已经是在CodeBlocks20.03配置了wxWidgets3.0.5,并且能够通过项目创建导航创建一个新的工程,并且成功运行。 那么上一个是通过CodeBlocks的模板创建的,一进去就已经是2个头文件2个cpp文件,总是感觉缺…...

【Apollo学习笔记】——规划模块TASK之SPEED_DECIDER
文章目录 前言SPEED_DECIDER功能简介SPEED_DECIDER相关配置SPEED_DECIDER流程MakeObjectDecisionGetSTLocationCheck类函数CheckKeepClearCrossableCheckStopForPedestrianCheckIsFollowCheckKeepClearBlocked Create类函数 前言 在Apollo星火计划学习笔记——Apollo路径规划算…...

【操作系统】一文快速入门,很适合JAVA后端看
作者简介: 目录 1.概述 2.CPU管理 3.内存管理 4.IO管理 1.概述 操作系统可以看作一个计算机的管理系统,对计算机的硬件资源提供了一套完整的管理解决方案。计算机的硬件组成有五大模块:运算器、控制器、存储器、输入设备、输出设备。操作…...
C++ Primer阅读笔记--allocator类的使用
1--allocator类的使用背景 new 在分配内存时具有一定的局限性,其将内存分配和对象构造组合在一起;当分配一大块内存时,一般希望可以在内存上按需构造对象,这时需要将内存分配和对象构造分离,而定义在头文件 memory 的 …...

【C++历险记】面向对象|菱形继承及菱形虚拟继承
个人主页:兜里有颗棉花糖💪 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【C之路】💌 本专栏旨在记录C的学习路线,望对大家有所帮助🙇 希望我们一起努力、成长&…...

【Locomotor运动模块】攀爬
文章目录 一、攀爬主体“伪身体”1、“伪身体”的设置2、“伪身体”和“真实身体”,为什么同步移动3、“伪身体”和“真实身体”,碰到墙时不同步的原因①现象②原因③解决 二、攀爬1、需要的组件:“伪身体”、Climbing、Climbable及Interacto…...

ELK安装、部署、调试(一)设计规划及准备
一、整体规划如图: 【filebeat】 需要收集日志的服务器,安装filebeat软件,用于收集日志。logstash也可以收集日志,但是占用的系统资源过大,所以使用了filebeat来收集日志。 【kafka】 接收filebeat的日志ÿ…...

【CSS】解决对齐的小问题
问题: 表单或者页面上可能遇到文字无法对平均分,带有冒号的文本无法左右对齐的情况 常见的解决方式: 解决如下图 仍无法解决对齐的问题,还需要考虑字数 解决 这里用css的方式解决 增加 i 标签 固定宽度,设置 i …...

【狂神】Spring5(Aop的实现方式)
今天没有偷懒,只是忘了Mybatis,所以去补课了~ ┏━━━━━━━━━━━━━━━┓ NICE PIGGY PIG.. ┗━━━━━━━△━━━━━━━┛ ヽ(・ω・)ノ | / UU 1.Aop实现方式一 1.1、什…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...