- 前端
【免费下载链接】30-seconds-of-css
Short CSS code snippets for all your development needs
本篇技术指南以开源仓库 30-seconds-of-css 中的 button-hover-shrink-animation 片段为蓝本,完整讲解“悬停时按钮缩小”这一经典交互效果的实现原理与写法。你将掌握transition与:hover的组合用法、transform: scale()的缩放语义与取值细节,以及如何在此基础上扩展出放大、描边、填充等一整套按钮 hover 动画方案。
效果概览:一段 HTML 加一段 CSS
该片段的核心思路极其简洁:给元素设置合适的transition,再用:hover伪类把transform改为scale(0.8),即可在鼠标悬停时让按钮整体缩小到原来的 80%。
完整代码如下(原样取自 button-hover-shrink-animation.md):
<button class="button-shrink">Submit</button>.button-shrink { color: #65b5f6; background-color: transparent; border: 1px solid #65b5f6; border-radius: 4px; padding: 0 16px; cursor: pointer; transition: all 0.3s ease-in-out; } .button-shrink:hover { transform: scale(0.8); }只需把这两段分别放进页面的<body>和<style>(或外部样式表)中即可直接运行,不需要任何 JavaScript。这是一个纯 CSS 的交互效果,由“默认态样式 + 悬停态变换 + 过渡动画”三部分组成。
原理拆解:transition与:hover如何协同工作
该片段由两个关键机制协同完成:
transition: all 0.3s ease-in-out:声明元素上所有可动画属性发生变化时,用 0.3 秒、ease-in-out缓动曲线平滑过渡。0.3s是持续时间,ease-in-out是缓动函数(先慢后快再慢),让缩放过程观感自然。:hover伪类 +transform: scale(0.8):当鼠标悬停到按钮上时,:hover规则生效,把按钮的transform改为scale(0.8)。由于transform的变化被transition捕获,浏览器会在 0.3 秒内把缩放比例从1(原始大小)平滑插值到0.8;鼠标移出后,transform回到默认值,按钮同样平滑恢复原大小。
这里有一个值得注意的细节:transition: all会同时覆盖color、background-color、border、transform等所有属性。因此如果后续为按钮追加新的 hover 效果(例如同时改变背景色),也会自动获得同样的过渡节奏,不必逐一声明。若只想动画transform,可以收窄为transition: transform 0.3s ease-in-out;,这样更利于性能与可预测性(见下文“性能与最佳实践”)。
参数解读:scale()与可调细节
scale()的取值语义
transform: scale(0.8)表示把元素沿 X、Y 两个轴等比缩放为原始尺寸的 0.8 倍:
scale(1)等价于原始大小,即不缩放;- 取值在
(0, 1)之间为缩小,如scale(0.8)、scale(0.5); - 取值大于
1为放大,如scale(1.1); - 也可写成双参数形式
scale(sx, sy)分别控制 X、Y 轴,例如scale(1, 0.5)表示横向不变、纵向压扁。
缩放的基准点是元素的中心点(默认transform-origin: center),因此缩小后按钮会围绕自身中心收缩,视觉上保持居中。若想改成从左上角收缩,可通过transform-origin: top left调整原点。
三个常用可调旋钮
| 参数 | 本片段取值 | 作用与常见取值范围 |
|---|---|---|
transition持续时间 | 0.3s | 动画时长,常见0.2s~0.5s,过短显生硬、过长显拖沓 |
| 缓动函数 | ease-in-out | 可选ease、linear、ease-out、cubic-bezier(...)等,ease-out适合“快速响应、缓慢结束”的悬停反馈 |
scale()缩放比 | 0.8 | 缩小的常见范围0.8~0.95,缩放幅度过大会影响可读性与点击命中面积 |
把transition的时长与缓动函数按需调整,即可得到不同“手感”的动画——例如用transition: transform 0.2s ease-out;会得到更敏捷的反馈。
同仓库对照:放大、缩小与更多 hover 动画变体
30-seconds-of-css 仓库的snippets目录下存放着大量同类动画片段,与本片段构成完整的“按钮 hover 动画家族”,可相互对照理解:
- button-hover-grow-animation:与本文几乎同构,唯一的实质差异是
:hover中改为transform: scale(1.1),实现悬停放大。两条片段共享同一套样式骨架(color、透明背景、1px边框、border-radius: 4px、cursor: pointer),只是缩放方向相反。由此可知:该系列的核心模式是“相同骨架 + 不同transform取值”。 - button-hover-fill-animation:不依赖
transform,而是通过:hover交换background与color,配合transition: 0.3s all ease-in-out实现背景填充效果,展示了另一种“状态切换 + 过渡”的实现思路。 - button-border-animation:利用
::before/::after伪元素在悬停时把width从24px延伸到100%,实现上下描边展开动画,属于依赖伪元素的更复杂变体。
此外,hover-shadow-box-animation 与 hover-underline-animation 分别演示了box-shadow扩散与scaleX()下划线展开,同样值得对照学习。从源码结构看,这些片段全部遵循 snippet-template.md 的统一格式(frontmatter 元数据 + 简述列表 + HTML/CSS 代码块),便于在官网与仓库间自动化发布。
实战进阶:在缩小动画之上叠加更多状态
基础的缩小动画可以直接投入生产,但在真实项目中通常还需要处理以下场景:
1. 结合:active与:focus覆盖更多交互状态
.button-shrink:hover, .button-shrink:active, .button-shrink:focus { transform: scale(0.8); }:focus保证键盘 Tab 聚焦时也有视觉反馈,:active让按下瞬间同样缩小,提升可访问性与操作一致性(该模式可参考 hover-shadow-box-animation 中同时使用:hover、:focus、:active的写法)。
2. 缩小同时叠加阴影,强化“按压”感
.button-shrink:hover { transform: scale(0.8); box-shadow: 0 2px 8px rgba(101, 181, 246, 0.4); }由于transition: all的存在,阴影也会同步淡入淡出;若只希望阴影“瞬现”,可将transition收窄为transition: transform 0.3s ease-in-out;。
3. 适配prefers-reduced-motion(无障碍建议)
@media (prefers-reduced-motion: reduce) { .button-shrink { transition: none; } }用户系统开启“减少动态效果”时直接禁用过渡动画,避免缩放闪烁引发不适。这是通用无障碍实践,并非该片段自带行为,建议按项目需要自行补充。
4. 注意移动端与命中面积
缩小动画会临时减小按钮的点击/触摸命中区域,若按钮本身偏小(如低于 44px 触控目标),建议缩小幅度保持保守(如scale(0.9)),或仅对非核心按钮使用。
性能与最佳实践
transform与opacity是浏览器合成器(compositor)层面处理的属性,动画化时通常不会触发布局(layout)与重绘(paint),因此优先动画transform而不是width/height/top/left等布局属性,可以显著减少主线程压力。这也是该片段选择transform: scale()作为核心手段的原因——与 button-border-animation 动画width的实现相比,缩放方案在复杂页面中更不易引起重排。
实际操作建议:
- 若按钮只需缩放动画,将
transition: all 0.3s ease-in-out收窄为transition: transform 0.3s ease-in-out;,避免不必要的属性监听; - 保持
:hover规则只声明需要变化的属性(本片段中仅transform),默认态样式尽量精简; - 动画时长与缓动函数全局统一,保证整个站点的交互“手感”一致。
在仓库中查看与使用
本片段位于仓库的snippets目录,该目录聚合了全部 CSS 技巧片段(完整列表见 snippets 目录)。仓库本身定位为“Short CSS code snippets for all your development needs”,所有片段均按 snippet-template.md 的固定格式编写,每条片段由 frontmatter(标题、类型、标签、作者、修改日期)与“效果描述 + 实现要点 + HTML/CSS 示例”组成,便于直接复制使用,也便于后续维护与官网发布。
如需为本仓库贡献新的动画片段,可参考 CONTRIBUTING.md:只需在snippets目录下基于模板复制一份新文件、按命名规范命名并填写完整 frontmatter 即可,片段应足够抽象、能解决真实问题。安装或运行层面,该仓库以文档型片段为主,无需构建步骤,将示例代码直接嵌入自己的页面即可生效。
小结
button-hover-shrink-animation用最少的代码展示了 CSS 交互动画的经典范式:transition负责“怎么动”,:hover负责“何时动”,transform: scale()负责“动到什么程度”。在此基础上,只需调整scale()的方向与幅度,就能在同一骨架下衍生出放大、缩小、填充、描边等一整套按钮反馈方案,是日常开发中性价比极高的通用技巧。
- 前端
【免费下载链接】30-seconds-of-css
Short CSS code snippets for all your development needs
相关推荐
30-seconds-of-code:用 CSS transform 与 transition 实现图片悬停旋转缩放效果
30 seconds of code:用 CSS transform 与 transition 实现图片悬停旋转缩放效果 图片悬停时平滑放大并轻微旋转,是一种极
教程文档30-seconds-of-css 系列:用 :focus 伪类与 transform 实现按钮聚焦摆动动画
30 seconds of css 系列:用 :focus 伪类与 transform 实现按钮聚焦摆动动画 导读 本文讲解 30 seconds of css
前端30 Seconds of Code 实战:用 CSS 伪类实现悬停时淡出兄弟元素(Sibling Fade)
30 Seconds of Code 实战:用 CSS 伪类实现悬停时淡出兄弟元素(Sibling Fade) 导读 本文围绕 30 Seconds of Co
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考