css3实现的switch开关按钮

10年服务1亿前端开发工程师

上周分享了一个适合移动端的checkbox,很多微博上的朋友作了很多测试,给了我很多建议,再次感谢。问题主要集中在单标记的input元素是否可以使用伪类(:before:after)上。

本身我做这一个ui的目的是支持移动端的页面,而webkit上也正好支持单标记的input元素是使用伪类(:before:after),所以我没做更多的支持和优化,我只是想尽量的保持html干净,所以没用其他元素做模拟。如果你要使用在桌面应用上,或支持其他浏览器,可以自己稍微修改一下,反正我是没测试过。

今天继续分享一个iOS风格的switch开关按钮,样子也非常常见,如图:

6B2FD175-2E05-4B2A-B98F-B485C9B46882

主要是使用了<input ?type="checkbox">来模拟实现,具体的HTML:

<label><input class="mui-switch" type="checkbox"> 默认未选中</label>
<label><input class="mui-switch" type="checkbox" checked> 默认选中</label>
<label><input class="mui-switch mui-switch-animbg" type="checkbox"> 默认未选中,简单的背景过渡效果,加mui-switch-animbg类即可</label>
<label><input class="mui-switch mui-switch-animbg" type="checkbox" checked> 默认选中</label>
<label><input class="mui-switch mui-switch-anim" type="checkbox"> 默认未选中,过渡效果,加 mui-switch-anim
类即可</label>
<label><input class="mui-switch mui-switch-anim" type="checkbox" checked> 默认选中</label>

在实际的使用中后来又增加了两个过渡效果,分别加?mui-switch-animbgmui-switch-anim?类即可,具体效果查看下面的demo页面。

CSS代码(SCSS导出的,排版有些奇怪):

.mui-switch {
  width: 52px;
  height: 31px;
  position: relative;
  border: 1px solid #dfdfdf;
  background-color: #fdfdfd;
  box-shadow: #dfdfdf 0 0 0 0 inset;
  border-radius: 20px;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  background-clip: content-box;
  display: inline-block;
  -webkit-appearance: none;
  user-select: none;
  outline: none; }
  .mui-switch:before {
    content: '';
    width: 29px;
    height: 29px;
    position: absolute;
    top: 0px;
    left: 0;
    border-radius: 20px;
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
    border-bottom-left-radius: 20px;
    border-bottom-right-radius: 20px;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); }
  .mui-switch:checked {
    border-color: #64bd63;
    box-shadow: #64bd63 0 0 0 16px inset;
    background-color: #64bd63; }
    .mui-switch:checked:before {
      left: 21px; }
  .mui-switch.mui-switch-animbg {
    transition: background-color ease 0.4s; }
    .mui-switch.mui-switch-animbg:before {
      transition: left 0.3s; }
    .mui-switch.mui-switch-animbg:checked {
      box-shadow: #dfdfdf 0 0 0 0 inset;
      background-color: #64bd63;
      transition: border-color 0.4s, background-color ease 0.4s; }
      .mui-switch.mui-switch-animbg:checked:before {
        transition: left 0.3s; }
  .mui-switch.mui-switch-anim {
    transition: border cubic-bezier(0, 0, 0, 1) 0.4s, box-shadow cubic-bezier(0, 0, 0, 1) 0.4s; }
    .mui-switch.mui-switch-anim:before {
      transition: left 0.3s; }
    .mui-switch.mui-switch-anim:checked {
      box-shadow: #64bd63 0 0 0 16px inset;
      background-color: #64bd63;
      transition: border ease 0.4s, box-shadow ease 0.4s, background-color ease 1.2s; }
      .mui-switch.mui-switch-anim:checked:before {
        transition: left 0.3s; }

/*# sourceMappingURL=mui-switch.css.map */

SCSS代码:

@mixin borderRadius($radius:20px) {
  border-radius: $radius;
  border-top-left-radius: $radius;
  border-top-right-radius: $radius;
  border-bottom-left-radius: $radius;
  border-bottom-right-radius: $radius;
}

$duration: .4s;
$checkedColor: #64bd63;
.mui-switch {
  width: 52px;
  height: 31px;
  position: relative;
  border: 1px solid #dfdfdf;
  background-color: #fdfdfd;
  box-shadow: #dfdfdf 0 0 0 0 inset;
  @include borderRadius();
  background-clip: content-box;
  display: inline-block;
  -webkit-appearance: none;
  user-select: none;
  outline: none;
  &:before {
    content: '';
    width: 29px;
    height: 29px;
    position: absolute;
    top: 0px;
    left: 0;
    @include borderRadius();
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
  &:checked {
    border-color: $checkedColor;
    box-shadow: $checkedColor 0 0 0 16px inset;
    background-color: $checkedColor;
    &:before {
      left: 21px;
    }
  }
  &.mui-switch-animbg {
    transition: background-color ease $duration;
    &:before {
      transition: left 0.3s;
    }
    &:checked {
      box-shadow: #dfdfdf 0 0 0 0 inset;
      background-color: $checkedColor;
      transition: border-color $duration, background-color ease $duration;
      &:before {
        transition: left 0.3s;
      }
    }

  }
  &.mui-switch-anim {
    transition: border cubic-bezier(0, 0, 0, 1) $duration, box-shadow cubic-bezier(0, 0, 0, 1) $duration;
    &:before {
      transition: left 0.3s;
    }
    &:checked {
      box-shadow: $checkedColor 0 0 0 16px inset;
      background-color: $checkedColor;
      transition: border ease $duration, box-shadow ease $duration, background-color ease $duration*3;
      &:before {
        transition: left 0.3s;
      }
    }

  }
}

发现问题欢迎微博上@,带上截图,机型,浏览器版本等,感激不尽!

demo页面:https://www.css88.com/b-mui/switch.html

demo二维码扫一扫:

qrcode

兼容更多PC浏览器的美化请查看:美化单选框 radio 、多选框 checkbox 和 switch开关按钮

赞(2) 打赏
未经允许不得转载:WEB前端开发 » css3实现的switch开关按钮

评论 8

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #-49

    好强大···

    优狐网4年前 (2015-07-02)回复
  2. #-48

    为什么我照着做的,确实一个点击选择的出现对号的button

    白白3年前 (2016-07-12)回复
  3. #-47

    不支持火狐

    张三2年前 (2016-12-08)回复
  4. #-46

    你好 在demo中 我的鼠标没有在按钮上,在按钮的周围点击也会触发按钮的动效

    小杰2年前 (2017-01-07)回复
    • 应该是和label有关,在label范围内点击都会有效

      tianhui1年前 (2017-09-22)回复
  5. #-45

    不兼容火狐浏览器

    TAT8个月前 (05-24)回复

前端开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏