单选按钮动画列表

三月 14, 2024 / Mr.x / 1阅读 / 0评论/ 分类: 实用创意
单选按钮动画列表 — 荣小站

单选按钮动画列表

带有选中动画效果的 CSS 单选按钮列表,Selection 边框会跟随选中项平滑移动。

▼ 效果展示

这是一个精美的单选按钮列表动画效果。当选中某个选项时,会出现一个内阴影边框跟随选中项移动,同时单选按钮本身也会有缩放动画。整个效果完全使用 CSS 实现,无需 JavaScript。

核心特性

  • 纯 CSS 实现:无需 JavaScript,完全使用 CSS 伪类和动画
  • 平滑动画:Selection 边框跟随选中项平滑过渡移动
  • 按钮缩放:选中时单选按钮有缩放弹跳效果
  • 暗色主题:支持根据系统主题自动切换明暗模式
  • 悬停效果:未选中项悬停时也有背景色变化

完整代码

以下是完整的代码,分为 HTML、CSS 两部分,点击各部分查看:

📄 HTML 结构

<main> <form> <label> <input type="radio" name="inventor" value="bell"> <span class="truncate">选择1</span> </label> <label> <input type="radio" name="inventor" value="morse"> <span class="truncate">选择2</span> </label> <label> <input type="radio" name="inventor" value="edison"> <span class="truncate">选择3</span> </label> <div class="selection"></div> </form> </main>

🎨 CSS 样式

* { border: 0; box-sizing: border-box; margin: 0; padding: 0; } :root { --hue: 223; --bg: hsl(var(--hue),90%,90%); --fg: hsl(var(--hue),90%,10%); --primary: hsl(var(--hue),90%,50%); --trans-dur: 0.3s; --trans-timing: cubic-bezier(0.65,0,0.35,1); font-size: calc(16px + (24 - 16) * (100vw - 320px) / (2560 - 320)); } body, input { color: var(--fg); font: 1em/1.5 "DM Sans", sans-serif; } body { background-color: var(--bg); display: flex; height: 100vh; transition: background-color var(--trans-dur), color var(--trans-dur); } main { margin: auto; padding: 1.5em 0; width: 100%; } form { margin: auto; max-width: 20em; position: relative; width: calc(100% - 3em); } label, input[type="radio"] { cursor: pointer; -webkit-tap-highlight-color: transparent; } label { background-color: hsla(0,0%,100%,0); border-radius: 0.75em; display: flex; align-items: center; padding: 1.5em; transition: background-color var(--trans-dur); } input[type="radio"] { background-color: hsl(0,0%,100%); border-radius: 50%; box-shadow: 0 0 0 0.0625em hsl(var(--hue),90%,80%), 0 0.125em 0.125em 0.0625em hsla(var(--hue),90%,10%,0.3); flex-shrink: 0; margin-inline-end: 1em; outline: transparent; position: relative; width: 1.5em; height: 1.5em; transition: background-color var(--trans-dur), box-shadow var(--trans-dur); -webkit-appearance: none; appearance: none; } input[type="radio"]:before, input[type="radio"]:after { border-radius: 50%; content: ""; display: block; position: absolute; transform: scale(0); transition: transform var(--trans-dur) var(--trans-timing); } input[type="radio"]:before { box-shadow: 0 0 0 0.5em var(--primary) inset, 0 0 0 0.0625em var(--primary); top: -0.0625em; left: -0.0625em; width: calc(100% + 0.125em); height: calc(100% + 0.125em); } input[type="radio"]:after { background-color: hsl(0,0%,100%); top: 25%; left: 25%; width: 50%; height: 50%; } input[type="radio"]:checked:before, input[type="radio"]:checked:after { transform: scale(1); } label:has(input[type="radio"]:checked), label:has(input[type="radio"]:not(:checked)):hover { background-color: hsla(0,0%,100%,0.5); } .selection { border-radius: 0.75em; box-shadow: 0 0 0 0.125em var(--primary) inset; display: none; pointer-events: none; position: absolute; top: 0; left: 0; width: 100%; height: 4.5em; transition: transform var(--trans-dur) var(--trans-timing); } label:has(input[type="radio"]:checked) ~ .selection { animation: fade-in var(--trans-dur) var(--trans-timing); display: inherit; } label:nth-of-type(2):has(input[type="radio"]:checked) ~ .selection { transform: translateY(100%); } label:nth-of-type(3):has(input[type="radio"]:checked) ~ .selection { transform: translateY(200%); } .truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Dark theme */ @media (prefers-color-scheme: dark) { :root { --bg: hsl(var(--hue),90%,10%); --fg: hsl(var(--hue),90%,90%); } label { background-color: hsla(var(--hue),90%,30%,0); } label:has(input[type="radio"]:checked), label:has(input[type="radio"]:not(:checked)):hover { background-color: hsla(var(--hue),90%,30%,0.5); } input[type="radio"] { background-color: hsl(var(--hue),90%,30%); box-shadow: 0 0 0 0.0625em hsl(var(--hue),90%,50%), 0 0.125em 0.125em 0.0625em hsla(var(--hue),90%,10%,0.3); } } /* Animations */ @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

技术要点

技术点说明
:has() 伪类父选择器,根据子元素状态改变样式
CSS 自定义属性使用 CSS 变量控制主题色和动画时长
transform scale实现单选按钮选中时的缩放弹跳效果
transitioncubic-bezier 缓动函数实现弹性动画
prefers-color-scheme检测系统主题,自动切换明暗模式
box-shadow inset使用内阴影创建 selection 边框效果

使用说明

  1. 将 HTML 结构复制到你的页面中
  2. 添加对应的 CSS 样式
  3. 根据需要修改 --hue 变量调整主色调
  4. 点击选项即可看到动画效果

#单选按钮动画列表(1)

评论