🔥一个有质感的拟态开关

前言

​ 最近在小红书冲浪的时候,看到一个拟态按钮的figma设计很有意思,效果如下

这种拟态风格,主要是通过修改内外阴影来实现的,考察box-shadown属性的时候到了

最终效果

这是实现的最终效果,除了背景动画有点生硬,大致效果是有了.

实现思路

整体设计
  • 分层容器 :使用三层嵌套结构(toggle__warpper > toggle > toggle__btn)构建立体感
  • 定位策略 :通过 position: absolute 实现按钮的精准定位滑动
  • 尺寸控制:固定尺寸容器(664px/184px)确保视觉稳定性
拟态视觉实现
  • 阴影体系(核心拟态效果):

    scss 复制代码
    box-shadow: 
      inset 0px 4px 13px 0 rgba(#000, 0.5), // 内凹阴影
      inset 0px -4px 13px 0 rgba(255, 255, 255, 1); // 高光提亮
  • 多层渐变背景

    scss 复制代码
    background: linear-gradient(#fff, #828a9a); // 容器基础渐变
    background: linear-gradient(170deg, #ffffff, #f4f7fd 20%, #afb5c1, #929caf); // 按钮复杂渐变
  • 伪元素投影

    scss 复制代码
    &::after {
      background: rgba(#192d55, 0.19);
      filter: blur(16px); // 模糊投影增强立体感
    }
交互逻辑实现
vue 复制代码
<script setup>
import { ref } from 'vue'
const toggleStatus = ref(false)
const toggleBtn = ref(null)
const onToggleClick = () => {
  const btnDom = toggleBtn.value
  btnDom.style.left = toggleStatus.value ? '-12px' : '346px'
  toggleStatus.value = !toggleStatus.value
}
</script>

完整代码

vue 复制代码
<template>
  <main class="container">
    <div class="toggle__warpper">
      <div
        class="toggle"
        :class="{
          'toggle--active': toggleStatus
        }"
        @click="onToggleClick"
      >
        <div class="toggle__btn" ref="toggleBtn">
          <div class="toggle__btn--after"></div>
          <div class="toggle__btn--before"></div>
        </div>
      </div>
    </div>
  </main>
</template>

<script setup>
import { ref } from 'vue'
const toggleStatus = ref(false)
const toggleBtn = ref(null)
const onToggleClick = () => {
  const btnDom = toggleBtn.value
  btnDom.style.left = toggleStatus.value ? '-12px' : '346px'
  toggleStatus.value = !toggleStatus.value
}
</script>

<style lang="scss" scoped>
.container {
  background: linear-gradient(#fff, #a7adbb);
}
.toggle {
  position: relative;
  width: 600px;
  height: 120px;
  border-radius: 64px;
  background: linear-gradient(#fff, #828a9a);
  box-shadow:
    inset 0px 4px 13px 0 rgba(#000, 0.5),
    inset 0px -4px 13px 0 rgba(255, 255, 255, 1);
  display: flex;
  align-items: center;
  &--active {
    animation: bgAnimation 0.35s linear 0.35s forwards;
  }

  &__warpper {
    border-radius: 120px;
    width: 664px;
    height: 184px;
    box-shadow:
      inset 0px 4px 13px 0 rgba(25, 45, 85, 0.5),
      inset 0px -4px 13px 0 rgba(255, 255, 255, 1);
    display: flex;
    align-items: center;
    justify-content: center;
  }
  &__btn {
    position: absolute;
    border-radius: 120px;
    left: -12px;
    width: 268px;
    height: 160px;
    background: linear-gradient(170deg, #ffffff, #f4f7fd 20%, #afb5c1, #929caf);
    padding: 24px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
    cursor: pointer;
    box-shadow: 14px 33px 20px -15px rgba(25, 45, 85, 0.45);
    transition: all ease-in-out 0.35s;
    &--after {
      width: 100px;
      height: 115px;
      background: linear-gradient(101deg, #cfd5dd, #f9f9f9);
      border-radius: 50%;
    }
    &--before {
      width: 100px;
      height: 115px;
      background: linear-gradient(112deg, #969fb0, #ffffff);
      border-radius: 50%;
    }
    &::after {
      position: absolute;
      content: '';
      left: 53px;
      bottom: -58px;
      width: 250px;
      height: 174px;
      background: rgba(#192d55, 0.19);
      border-radius: 120px;
      filter: blur(16px);
      z-index: 999;
      display: block;
    }
  }
}
// 背景渐变动画
@keyframes bgAnimation {
  0% {
    background: linear-gradient(#fff, #828a9a);
  }
  100% {
    background: linear-gradient(#9cff8c, #0b4f00);
  }
}
</style>

遇到的问题

我想要弄一个让这个开关切换状态的时候,这个背景变化应该是要有一点过渡的,但是用css的动画去实现,发现背景的变化永远都是瞬间的,没有过渡效果,如果想要背景也有渐变就需要用js或者别的方式去实现.

总的来说效果还是有的.

相关推荐
哟哟耶耶1 小时前
npm-npm init与npm init -y区别与作用(初始化一个新的node.js项目)
前端·npm·node.js
计算机毕设定制辅导-无忧学长6 小时前
HTML 新手入门:从零基础到搭建第一个静态页面(二)
前端·javascript·html
luckyext6 小时前
Postman用JSON格式数据发送POST请求及注意事项
java·前端·后端·测试工具·c#·json·postman
烛阴7 小时前
JavaScript 函数对象与 NFE:你必须知道的秘密武器!
前端·javascript
px52133447 小时前
Solder leakage problems and improvement strategies in electronics manufacturing
java·前端·数据库·pcb工艺
eli9607 小时前
node-ddk,electron 开发组件
前端·javascript·electron·node.js·js
老K(郭云开)7 小时前
最新版Chrome浏览器加载ActiveX控件技术--allWebPlugin中间件一键部署浏览器扩展
前端·javascript·chrome·中间件·edge
老K(郭云开)7 小时前
allWebPlugin中间件自动适应Web系统多层iframe嵌套
前端·javascript·chrome·中间件
银之夏雪8 小时前
Vue 3 vs Vue 2:深入解析从性能优化到源码层面的进化
前端·vue.js·性能优化