纯CSS实现有趣emoji切换开关

news2024/12/23 23:07:53

这是一个纯CSS创建的动画切换开关,它不仅能够在视觉上吸引用户,还能通过交互提供即时反馈。本文将解析源码的核心实现逻辑,这个项目的核心是使用CSS变量、3D变换和过渡效果来实现一个动态的、响应式的用户界面元素。

关键技术点

  1. CSS变量:用于动态调整样式。
  2. 3D变换:用于创建翻转动画效果。
  3. 过渡效果:用于平滑地改变元素的样式。
  4. emoji:并不是真正的emoji而是通过CSS绘制。

实现步骤

1. HTML

首先需要创建一个基本的HTML结构,包括一个表单元素(checkbox)和一个用于显示Emoji的元素。这里的switch__emoji-face即是开关上面的两个emoji表情。

<div class="switch">
  <input type="checkbox" class="switch__input" id="toggle">
  <label for="toggle" class="switch__label">Toggle</label>
  <div class="switch__wrapper">
    <div class="switch__emoji">
      <div class="switch__emoji-face"></div>
      <div class="switch__emoji-face"></div>
    </div>
  </div>
</div>
2. CSS

接下来,我们使用CSS来设计这个切换开关的样式。这段CSS代码主要用来实现以下几个目标:

  1. 统一的颜色主题

    • 通过定义 --hue 变量,可以在整个网站中统一色调,使得颜色方案更加一致。
    • --bg--fg 分别定义了背景色和前景色,使得文本和背景之间有良好的对比度,提高可读性。
  2. 动态响应的字体大小

    • 使用 calc() 函数和视口宽度单位 vw,可以根据屏幕大小动态调整字体大小,实现响应式设计。
  3. 平滑的过渡动画

    • --trans-dur 定义了过渡动画的持续时间,使得元素的显示和隐藏更加平滑自然。
    • --trans-timing1--trans-timing2 使用贝塞尔曲线定义了动画的缓动效果,使得动画变化更加符合物理规律和视觉习惯。
  4. 易于维护和扩展

    • 通过使用CSS变量,可以在一个地方修改值,而在整个文档中生效,提高了代码的可维护性。
    • 同时这些变量也可以在其他样式规则中被引用,方便进行样式的扩展和复用。
:root {
  --hue: 223;
  --bg: hsl(var(--hue),10%,90%);
  --fg: hsl(var(--hue),10%,10%);
  --trans-dur: 0.5s;
  --trans-timing1: cubic-bezier(0.65,0,0.35,1);
  --trans-timing2: cubic-bezier(0.65,0,0.35,1.5);
  font-size: calc(56px + (120 - 56) * (100vw - 280px) / (3840 - 280));
}

Emoji 的绘制主要依赖于 .switch__emoji 相关的 CSS 代码块。这段代码通过使用 CSS 的 transform 属性和一些伪元素来创建一个可动的 Emoji 效果。以下是核心代码部分的解释:

.switch__emoji {
  $hue: 48;
  $sat: 90%;
  $radius: 0.5em;

  box-shadow: 0.25em 0.25em 0.125em hsl(0,0%,0%,0.3);
  overflow: hidden;
  pointer-events: none;
  top: 0.25em;
  left: 0.25em;
  width: 1em;
  height: 1em;

  /* ...其他样式... */

  &:before,
  &:after,
  &-eye,
  &-mouth,
  &-face {
    display: block;
    position: absolute;
  }

  /* ...其他样式... */
}
  • 伪元素 &:before&:after
    用于绘制 Emoji 的脸的上半部分和下半部分,通过 border-radius 属性设置为圆形,并通过 box-shadow 为 Emoji 添加眼睛和嘴巴。

  • &-eye
    用于绘制 Emoji 的眼睛。通过 border 属性创建一个有边框的圆,并利用 transform 属性调整位置和倾斜角度。

  • &-mouth
    用于绘制 Emoji 的嘴巴。通过 background-image 属性使用渐变和径向渐变来创建嘴巴的形状。

  • &-face
    用于绘制 Emoji 的脸部,通过 transform-style: preserve-3d 属性来保留 3D 空间中的子元素位置。

  • 3D 转换
    使用 transform 属性的 rotateYtranslateZ 函数来创建翻转效果。

  • 过渡效果
    使用 transition 属性来平滑地变换 Emoji 的表情。

下面是绘制 Emoji 表情的核心部分,接下来就是3D动画变换:

.switch__emoji-eye {
  border: 0.0625em solid hsl(var(--hue),10%,10%);
  border-radius: 50%;
  top: 50%;
  left: 50%;
  width: 0.25em;
  height: 0.25em;
  transform: translate(-50%,-50%) rotateY(-22.5deg) translateZ($radius) rotateZ(45deg);
}

.switch__emoji-mouth {
  background-image: ...;
  top: 50%;
  left: 50%;
  width: 0.5em;
  height: 0.5em;
  transform: translate(-50%,-50%) rotateX(-15deg) translateZ($radius);
}
3. 3D变换和过渡

为了实现Emoji的翻转效果,我们使用CSS的3D变换和过渡属性。点击切换动画的主要部分涉及到 .switch__input 这个 checkbox 输入元素以及与之相关的 .switch__emoji 元素。当 checkbox 被选中时,会触发 .switch__emoji 的状态变化,从而执行动画。

这里对于从右到左(如阿拉伯语或希伯来语)的语言,还实现了相反方向的滑动。👍

以下是实现点击切换动画的核心代码:

.switch__input:checked + .switch__emoji {
  transform: translateX(100%);
}

[dir="rtl"] .switch__input:checked + .switch__emoji {
  transform: translateX(-100%);
}

.switch__input:checked + .switch__emoji .switch__emoji-face {
  transform: rotateY(179.99deg);
}

[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face {
  transform: rotateY(-179.99deg);
}

.switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face {
  transform: rotateY(0);
}

[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face {
  transform: rotateY(-360deg);
}

代码解析

  1. .switch__input:checked + .switch__emoji

    • .switch__input 被选中(即被勾选)时,与其相邻的 .switch__emoji 元素会执行 transform: translateX(100%); 动画,即沿着 X 轴移动自身宽度的 100%,从而实现滑块开关的效果。
  2. [dir="rtl"] .switch__input:checked + .switch__emoji

    • 对于从右到左(如阿拉伯语或希伯来语)的语言,使用 translateX(-100%); 来实现相反方向的滑动。
  3. .switch__input:checked + .switch__emoji .switch__emoji-face

    • .switch__input 被选中时,.switch__emoji-face 元素会执行 rotateY(179.99deg); 动画,即围绕 Y 轴旋转 179.99 度,接近 180 度的旋转使得 Emoji 翻转。
  4. [dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face

    • 对于从右到左的语言,使用 rotateY(-179.99deg); 来实现相反方向的翻转。
  5. .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face

    • .switch__input 被选中时,第二个 .switch__emoji-face 元素会执行 rotateY(0); 动画,即恢复到原始状态。
  6. [dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face

    • 对于从右到左的语言,使用 rotateY(-360deg); 来实现相反方向的旋转。

动画效果的实现

核心动画效果是通过 CSS 的 transition 属性来实现的,确保变换是平滑的。

.switch__emoji-face {
  transform-style: preserve-3d;
  transition: transform var(--trans-dur) var(--trans-timing2);
}
  • transform-style: preserve-3d; 确保子元素在 3D 空间中的位置得以保留。
  • transition: transform var(--trans-dur) var(--trans-timing2); 定义了变换的持续时间和缓动函数,使得动画效果更加平滑自然。

通过这些代码,点击切换按钮时,Emoji 会沿着一个轴翻转,同时滑块也会移动,从而实现了一个有趣的切换动画效果。

响应式设计

为了确保这个按钮在不同设备上以及暗色场景下都能良好显示,源码使用了CSS媒体查询和相对单位。

@media (prefers-color-scheme: dark) {
  :root {
    --bg: hsl(var(--hue),10%,10%);
    --fg: hsl(var(--hue),10%,90%);
  }
  .switch__input {
    background-color: hsl(var(--hue),10%,20%);
    box-shadow: 0.0625em 0.0625em 0.0625em hsl(var(--hue),10%,25%) inset, -0.0625em -0.0625em 0.0625em hsl(var(--hue),10%,20%) inset, 0 0 0 0.125em hsl(var(--hue),10%,30%) inset, 0.25em 0.25em 0.125em hsla(0,0%,0%,0.3) inset, 0.0625em 0.0625em 0.0625em hsla(0,0%,0%,0.3);
  }
}

总结

通过使用CSS变量、3D变换和过渡效果,创建了一个既美观又功能丰富的Emoji Toggle按钮。这个交互效果极大了增强了用户体验。希望这篇文章能激发你探索更多CSS的可能性,感兴趣的可以尝试看看~

在线预览:https://code.juejin.cn/pen/7419571759471165455


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2178280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Python学习日记-31] Python 中的函数

[Python学习日记-31] Python 中的函数 简介 语法定义 函数的参数 简介 引子&#xff1a; 你是某公司的一个高级程序员&#xff0c;现在老板让你写一个监控程序&#xff0c;需要24小时全年无休的监控公司网站服务器的系统状况&#xff0c;当 CPU、Memory、Disk 等指标的使用…

基于SpringBoot+Vue+MySQL的体育商城系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。体育用品市场作为其中的一个重要分支&#xff0c;也逐渐向线上转移。基于SpringBootVueMySQL的体育商城系统应运而生&#xff0c;旨在通过构建…

如何使用ssm实现基于Java的高校物业工程报修系统

TOC ssm736基于Java的高校物业工程报修系统jsp 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握相关的专…

一行命令将Cmder添加到系统右键菜单中----配置环境

第一步&#xff0c;去官网下载一个简版的文件 ** 第二步&#xff0c;将下载的文件解压后如图&#xff0c;找到Cmder.exe右键以管理员身份运行 第三步&#xff0c;在窗口输入cmder /register all然后回车 第四步&#xff0c;OK!不管在哪里都可以使用了&#xff0c;直接右键即可

vscode环境迁移

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 vscode环境迁移 Setting 即可打开settings.json {"python.pythonPath": "/Users/apple/opt/anaconda3/bin/python","cmake.cmakePath": "/usr/local/bin/cmake",&qu…

[c++高阶]模版进阶

1.前言 在我们学习c的时候&#xff0c;常常会遇见要使用函数重载的情况。而当使用函数重载时&#xff0c;通常会使得我们编写很多重复的代码&#xff0c;这样就显得非常臃肿&#xff0c;并且效率非常的低下。 重载的函数仅仅只是类型不同&#xff0c;代码的复用率比较低&#x…

浮点数的这些特性你了解吗

问题1:下面的代码&#xff0c;输出结果是什么&#xff1a; public class CaclTest{public void test1(){float f 1.0F / 0.0F;System.out.println("f:" f)}public static void main(String[] args){CaclTest ct new CaclTest();ct.test1();}} A. 运行抛出异常:j…

7.数据结构与算法-循环链表

如果经常对首位元素进行操作&#xff0c;用尾元素更方便更快捷 两个循环链表合并

信息安全工程师(21)安全协议

前言 安全协议是建立在密码体制基础上的一种交互通信协议&#xff0c;它运用密码算法和协议逻辑来实现认证、密钥分配、数据机密性、完整性和抗否认性等安全目标。 一、定义与目的 安全协议旨在确保网络环境中信息交换的安全性&#xff0c;通过密码技术和协议逻辑来保护数据的机…

第八届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)

一.题目分析 &#xff08;1&#xff09;.题目 &#xff08;2&#xff09;.题目分析 1.按键功能分析----过程控制 a. 选择按键按下的个数和目标层数&#xff08;每个按键都要在一秒之内按下&#xff0c;否则就结束&#xff09; b. 当升降机到达目标平台&#xff0c;LED灯熄灭 c.…

负载均衡(Load Balancing)是一种计算机技术,用于在网络应用中分配工作负载,以优化资源使用、最大化吞吐量、减少响应时间以及避免过载。

负载均衡&#xff08;Load Balancing&#xff09;是一种计算机技术&#xff0c;用于在网络应用中分配工作负载&#xff0c;以优化资源使用、最大化吞吐量、减少响应时间以及避免过载。通过将任务均匀地分布在多个组件上&#xff0c;如服务器、网络链接、CPU、硬盘等&#xff0c…

【AG 创新工坊】探索存内计算的未来,共话 AGI 时代

目录 ⚛️1. 会议详情 ☪️2. 会议回顾 ♋2.1 多模态时代&#xff0c;存内计算架构的应用与发展 ♏2.2 分布式环境下深度学习任务的高效可靠执行研究 ♐2.3 IGZO在后道单片三维集成中的机遇与挑战 ♑2.4 witin-nn:神经网络算法模型在存内开发板上的应用开发 ♉2.5 茶歇交…

讯飞星火编排创建智能体学习(一)最简单的智能体构建

目录 开篇 智能体的概念 编排创建智能体 创建第一个智能体 ​编辑 大模型节点 测试与调试 开篇 前段时间在华为全联接大会上看到讯飞星火企业级智能体平台的演示&#xff0c;对于拖放的可视化设计非常喜欢&#xff0c;刚开始以为是企业用户才有的&#xff0c;回来之后查…

X86架构(九)——保护模式的进入

全局描述符表 全局描述符表(Global Descriptor Table,GDT)是保护模式下非常重要的一个数据结构。 在保护模式下&#xff0c;对内存的访问仍然使用段地址和偏移地址&#xff0c;在每个段能够访问之前&#xff0c;必须先行设置好 GDT 的地址&#xff0c;并加载全局描述符表寄存…

推荐4款2024年大家都在用的高质量翻译器。

翻译器在我们的生活中有着很重要的作用&#xff0c;不管是我们在学习还是工作&#xff0c;生活娱乐&#xff0c;出国旅游等场合都会派上用场&#xff0c;它是我们解决沟通的障碍&#xff0c;提高阅读效率的好帮手。我自己使用的翻译器有很多&#xff0c;可以给大家列举几款特别…

依赖倒置原则(学习笔记)

抽象不应该依赖细节&#xff0c;细节应该依赖抽象。简单的说就是要求对抽象进行编程&#xff0c;不要对实现进行编程&#xff0c;这样就降低了客户与实现模块间的耦合。 依赖倒转原则是基于这样的设计理念&#xff1a;相对于细节的多变性&#xff0c;抽象的东西要稳定的多。 以…

了解输出电源优先级

主要又SUB&#xff0c;SBU以及USB三种模式。 调试10kW逆变器存在的输出电源优先级的问题&#xff0c;当优先级为SUB时&#xff0c;利用电压源模拟电池&#xff0c;当电池电压超过58.4V&#xff0c;即过压&#xff0c;在接入市电&#xff0c;市电继电器仍然闭合&#xff0c;仍然…

pyboard405意外故障,micropython OLED例程无法运行,折腾了大半天。

thonny报告&#xff1a; Traceback (most recent call last): File "<stdin>", line 3, in <module> RuntimeError: name too mode # main.py -- put your code here! from machine import I2C,Pin #从machine模块导入I2C、Pin子模块 from ss…

javascript:监听浏览器页签切换

监听页面的可见性变化&#xff0c;在很多场景下非常实用&#xff0c;比如跟踪用户行为、节省资源、优化性能等。 1 代码示例 document.addEventListener("visibilitychange", () > {if (document.visibilityState "visible") {alert("当前页面已…

上交所系统被股民买崩了?原因竟然是...

在A股市场迎来久违的牛市之际&#xff0c;上海证券交易所&#xff08;上交所&#xff09;却在关键时刻遭遇了技术挑战。9月27日&#xff0c;上交所的交易系统出现了罕见的宕机现象&#xff0c;持续时间长达两个小时&#xff0c;导致投资者在火热的交易期间无法正常进行交易操作…