前言: 这篇笔记的内容, 学习自 webMaster https://house/26812.html 的电子书 web 开发实战 http://www.kancloud.cn/dennis/javascriptmethod
脑子笨, 看书没看懂, 书本的源码看的晕晕乎乎的, 只好把各个例子剥离出来一个个敲, 花了不少时间才明白实现原理
浏览器自带的单选框 / 复选框很丑, 美化单选框 UI 是有必要的. 纯 CSS3 修改样式其实很简单. 明白原理之后模仿了 3 个样式, 先上一个效果
html 代码
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- body{
- font-family: "微软雅黑";
- }
- /* 隐藏自带的单选框 */
- .icheck-radio> input {
- display: none;
- }
- /* 为容器设置 felx 布局 */
- .icheck-radio{
- display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ 无前缀不兼容 safari, 这个必须 */
- display: -moz-box; /* Firefox 17- 没必要 */
- display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */
- display: -moz-flex; /* Firefox 18+ 现在版本都 50 + 了, 这个可以删除了 */
- display: -ms-flexbox; /* IE 10 */
- display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */
- }
- .icheck-radio{
- padding: 5px 0;
- cursor:pointer;
- /* 字与选框平行对齐 */
- -webkit-box-align:center;/*box 布局的垂直居中属性 */
- align-items: center;/*flex 布局的垂直居中属性 */
- -webkit-align-items: center;/*safari*/
- }
- .icheck-media{
- position: relative;/* 重要, 伪类生成的原点, 设置绝对定位以其自身为参照, 所以自身设置相对定位 */
- width: 22px;
- height: 22px;
- margin-right: 5px;
- color: #fff;
- border:1px solid #d9d9d9;/* 未选中时的灰色边框线 */
- }
- .icheck-radio .icheck-media{
- border-radius: 50%;
- }
- /* 鼠标悬停, border 变色 */
- .icheck-radio:hover .icheck-media
- {
- border-color: #009a61;/* 鼠标悬停时的 border 变成绿色 */
- }
- /* 伪类画中心原点 */
- .icheck-radio .icheck-media:after{
- content: "";
- /* 使用绝对定位 让圆点居中与单选框 */
- position: absolute;
- top: 4px;
- left:4px;
- /* 圆点大小 */
- width: 14px;
- height: 14px;
- border-radius: 50%;
- background: #009A61;/* 圆点绿色背景 */
- /*scale(0) 将原点缩小为 0, 实现隐藏 */
- -webkit-transform:scale(0) ;/*safair*/
- -moz-transform:scale(0) ;
- -ms-transform:scale(0) ;/*ie9*/
- transform:scale(0) /*ie10+*/;
- /* 过渡效果 */
- transition:.3s ease;
- -webkit-transition: .3s ease;
- }
- .icheck-radio> input:checked + .icheck-media{
- border-color: #009A61;/* 圆心边框变为绿色 */
- background: #fff;
- }
- .icheck-radio> input:checked + .icheck-media:after{
- /* 选中后 原本缩小为 0 倍而隐藏的原点 , 变回 1 倍正常大小显示 */
- -webkit-transform:scale(1);
- -moz-transform:scale(1);
- transform: scale(1);
- }
- </style>
- </head>
- <body>
- <div class="box">
- <label for="radio3" class="icheck-radio">
- <input type="radio" id="radio3" name="sex1" checked> <!-- 自带的 input 会被隐藏 -->
- <div class="icheck-media"></div><!-- 自定义 UI 的容器 这个类必须紧跟 input 利用 相邻兄弟选择器 "+" 选中 -->
- <div class="icheck-inner">
- <div class="icheck-title"> 男 </div>
- </div>
- </label>
- <label for="radio4" class="icheck-radio">
- <input type="radio" id="radio4" name="sex1">
- <div class="icheck-media"></div>
- <div class="icheck-inner">
- <div class="icheck-title"> 女 </div>
- </div>
- </label>
- </body>
- </html>
原理: 每个组件都装在 < label > 标签中, input 用 display:none 隐藏, 这样隐藏后不占位置. .check-media 这个类是自定义样式的容器, 位置必须跟在 input 之后, 从而可以用相邻兄弟选择器 "+" 选中.
这是重点 [backcolor=#000000] .icheck-radio> input:checked + .icheck-media[/bgcolor]
其中绿色圆点是用 icheck-media 的伪类 画成了, 在未选中时, 用 transform:scale(0) 把这个圆点 缩小为 0 倍, 达到了隐藏的效果, 单选框被选中时 [backcolor=#000000] .icheck-radio> input:checked + .icheck-media:after[/bgcolor] 变为 transform:scale(1) 1 倍, 正常的显示大小
第二个效果
原理还是一样, 不同的是自定义 UI 样式里用了 2 个伪类 after,before, 其中 after 伪类画外边框, before 画左右滑动的圆点, 原点用绝对定位固定位置, 其参考是设置了相对定位的自身. switch-label. 未选中时原点 left 值为 4px, 选中后设置为 left:21px 从而实现滑动
html 代码
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- .switch {
- display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ 无前缀不兼容 safari, 这个必须 */
- display: -moz-box; /* Firefox 17- 没必要 */
- display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */
- display: -moz-flex; /* Firefox 18+ 现在版本都 50 + 了, 这个可以删除了 */
- display: -ms-flexbox; /* IE 10 */
- display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */
- align-items: center;/* 字体平行居中边框 */
- cursor: pointer;
- }
- /* 隐藏默认选框 */
- .switch> input {
- display: none;
- }
- .switch .switch-media{
- width: 40px;
- height: 25px;
- margin-right: 10px;
- padding: 5px 0;
- }
- .switch-media> .switch-label{
- /* 重要 样式伪类位置以其为参考点 */
- position: relative;
- }
- /*after 伪类画外框 */
- .switch-media> .switch-label:after{
- content: "";
- position: absolute;
- width: 40px;
- height: 22px;
- /* 未选中时的灰色边框 */
- border: 2px solid #b9b9b9;
- /* 百分比的值 不能实现上下直线, 左右半圆的效果, 必须为 pxem/rem*/
- border-radius: 200px;
- }
- .switch-media:hover .switch-label:after{
- /* 鼠标悬停时, 边框由灰色变为绿色 */
- border:2px solid #009A61;
- }
- /*before 伪类画圆点 */
- .switch-media> .switch-label:before{
- position: absolute;
- content: "";
- /* 圆点大小 */
- width: 18px;
- height: 18px;
- top: 4px;
- /* 选中时, 将 left 值由 4px 变为 21px 实现过渡动画 */
- left:4px;
- /* 未选中时的灰色背景色 */
- background-color: #b9b9b9;
- border-color: #b9b9b9;
- border-radius: 50%;
- /* 过渡效果 */
- transition: .3s ease;
- /* 圆点阴影, 很模糊 */
- box-shadow: 2px 2px 2px #EBEBEB;
- }
- .switch> input:checked + .switch-media>.switch-label:after{
- /* 选中时 边框变为绿色 */
- border:2px solid #009A61;
- }
- .switch> input:checked + .switch-media>.switch-label:before{
- /* 选中时 圆点位移, 背景变色 */
- left:21px;
- background-color: #009A61;
- }
- </style>
- </head>
- <body>
- <div class="box">
- <label class="switch switch-3" for="switch1">
- <input type="checkbox" id="switch1" checked>
- <div class="switch-media">
- <span class="switch-label"></span>
- </div>
- <div class="switch-inner">switch1</div>
- </label>
- <label class="switch" for="switch2">
- <input type="checkbox" id="switch2">
- <div class="switch-media">
- <span class="switch-label"></span>
- </div>
- <div class="switch-inner">switch2</div>
- </label>
- </div>
- </body>
- </html>
第三个效果, 原理也是一样的, 变的只有 div 效果容器的代码
html 代码
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- .checkbox{
- display: -moz-box;
- display: -webkit-box;
- display: -ms-flexbox;
- display: -webkit-flex;
- display: flex;
- -webkit-box-align: center;
- -webkit-align-items: center;
- align-items: center;
- cursor: pointer;
- position: relative;
- }
- .checkbox> input {
- display: none;
- }
- .input-helper{
- width: 20px;
- height: 20px;
- margin-right: 5px;
- padding: 5px 0;
- }
- .input-helper:after{
- position: absolute;
- content: "";
- width: 20px;
- height: 20px;
- border:1px solid #B9B9B9;
- opacity: 1;
- }
- .input-helper:before{
- position: absolute;
- content: "";
- width: 25px;
- height: 9px;
- border-left:2px solid #009A61;
- border-bottom: 2px solid #009A61;
- opacity: 0;
- filter: alpha(opacity=0);
- transition: .3s ease;
- }
- .checkbox> input:checked + .input-helper:after{
- opacity: 0;
- }
- .checkbox> input:checked + .input-helper:before{
- transform: rotate(-50deg);
- -ms-transform:rotate(-50deg); /* IE 9 */
- -moz-transform:rotate(-50deg); /* Firefox */
- -webkit-transform:rotate(-50deg); /* Safari 和 Chrome */
- opacity: 1;
- filter: alpha(opacity=100);
- }
- </style>
- </head>
- <body>
- <div class="box">
- <label class="checkbox checkbox-inline">
- <input type="checkbox" value="option1">
- <i class="input-helper"></i>
- checkbox
- </label>
- <label class="checkbox checkbox-inline">
- <input type="checkbox" value="option1">
- <i class="input-helper"></i>
- checkbox
- </label>
- </div>
- </body>
- </html>
当然还能有更多炫酷的效果
来源: http://www.qdfuns.com/article/31180/984fdd38afc2f375c19be11446888d7d.html