侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用CSS实现页面复选框的方法

前端  /  管理员 发布于 7年前   179

产品篇

在我们的后台中,需要设置广告精准投放的区域,也就是要在全国31个省、自治区、直辖市中选择。那么,出现下面这幅景象也就理所应当了:

这样做有几个问题:

    选项很多,没有规律,找起来很累
    如果是一个已经选择了部分选项的广告,修改时仍然需要用肉眼寻找,无法一眼看出来投放到哪些省份
    选完一个,再选下一个,还要从头找,甚至会被已经选过的影响

于是我想,首先应该把所有选项分为“已选中”和“未选中”两批,解决第2个问题,减轻第3个问题;其次复选框本身的价值不大,可以被替换为其它样式;唯一可能引入的问题,就是点选时,用户的预期是看到复选框里出现一个小对勾,表示选中,如果我把它移开放到“已选中”组里,用户可能会迷惑,需要一些时间学习。

于是我跟某产品经理朋友聊了聊这个想法,他表示确实可能造成用户迷惑,不过如果能加入动画效果,那么基本没问题。嗯,开始动手。
技术实现篇

近日flexbox规范定案,各浏览器相继支持display:flex;,同时传来一条好消息,新实现比老实现display:box;快很多。这次我打算用flexbox来解决问题,因为里面有一个很重要的属性:order(之前叫box-ordinal-group),它可以改变布局中元素的排列顺序,配合CSS3新增的选择器,应该可以满足需要。
第一步 分拆选中/未选中

(关于flexbox的知识,可以通过Google了解,虽然搜到的多是上一个版本,不过和最终版差别不大,只是叫法不同。本文不再过多讲解,我就当大家都会了)

<input type="checkbox">本身的样式不能修改,所以我们必须借助的帮助;实现选中/未选中区分,那自然就要用到伪类:checked;选择器一定是从外到内、从前到后的,没法选择父级元素,所以不能用<label>去包<input>,那么最终布局就只能是:

CSS Code复制内容到剪贴板
  1. <div>   
  2.     <input type="checkbox" name="q[]" id="q1" />   
  3.     <label for="q1">小宝3225</label>   
  4.     <input type="checkbox" name="q[]" id="q2" />   
  5.     <label for="q2">王老白白白</label>   
  6.     <input type="checkbox" name="q[]" id="q3" />   
  7.     <label for="q3">空夫31</label>   
  8.     <input type="checkbox" name="q[]" id="q4" />   
  9.     <label for="q4">谷大白话</label>   
  10.     <input type="checkbox" name="q[]" id="q5" />   
  11.     <label for="q5">Meathill</label>   
  12.     <input type="checkbox" name="q[]" id="q6" />   
  13.     <label for="q6">一毛不拔大师</label>   
  14. </div>  

很简单哈,不解释了。CSS3新增了“下一节点”选择器 +,用来选择某节点的下一个节点,结合:checked伪类就可以将选中的<input>和它临近的<label>通过改变order属性移到前面去:

CSS Code复制内容到剪贴板
  1. #container {   
  2.   display:flex;   
  3.   flex-direction:row;   
  4.   flex-wrap:wrap;   
  5. }   
  6. #container input,   
  7. #container label {   
  8.   order: 2; //所有选项、label顺序为2   
  9. }   
  10. input[type=checkbox]:checked,   
  11. input[type=checkbox]:checked + label {   
  12.   order: 0; // 越小越靠前   
  13. }  

不过这样只是把选中的内容提前,视觉上没有真正的分割。所以我决定再加入一根分割线,上面是选中的,下面是未选的。这个时候我们需要用到 ~ 这个选择器,选择某节点后面的节点:

CSS Code复制内容到剪贴板
  1. hr {   
  2.   display:none; // 默认情况下,没选任何选项,分割线隐藏   
  3.   order: 1; // 分割线顺序为1   
  4.   width:100%; // 保证独霸一行   
  5. }   
  6. input[type=checkbox]:checked ~ hr {   
  7.   display:block; // 有选项被选中后才会显示分割线   
  8. }  

http://jsfiddle.net/meathill/fPN3p/5/embedded/result/

这样基础功能实现了。不过视觉上,排版仍然不整齐,选中的选项和未选中的选项区分不算太明显,所以下一步我准备美化下checkbox。
第二步,美化CHECKBOX

做法与前面类似,也要用到CSS3新增的选择器。前面为了实现<label>提前,没有用它包裹<input>,所以在选项很多很长导致换行的时候,可能出现复选框和标签脱离的尴尬状况。好在复选框的价值可以用别的样式取代,所以先把小方框隐藏起来,转而将<label>作为操作目标,再来点边框底色圆角(参考自Bootstrap 3),就可以了:

CSS Code复制内容到剪贴板
  1. input[type=checkbox] {   
  2.   display: none;   
  3. }   
  4. label {   
  5.   min-width: 120px;   
  6.   border: 1px solid #CCC;   
  7.   padding: 2px 8px;   
  8.   text-align: center;   
  9.   margin: 0 5px 5px 0;   
  10.   background: #FFF;   
  11.   color: #333;   
  12.   border-radius: 3px;   
  13.   box-sizing: border-box;   
  14. }   
  15. label:hover {   
  16.   border-color: #ADADAD;   
  17.   background: #EBEBEB;   
  18.   cursor: pointer;   
  19. }   
  20. input[type=checkbox]:checked + label {   
  21.   order: 0;   
  22.   background-color: #5cb85c;   
  23.   border-color: #4cae4c;   
  24.   color: #FFF;   
  25. }   
  26. input[type=checkbox]:checked + label:hover {   
  27.   background-color: #47a447;   
  28.   border-color: #398439;   
  29. }  

这样看起来还有上升空间,如果加上几个图标响应用户操作,那么学习成本会更低,对操作后的预期也会更准确。于是引用CDN上的font-awesome,使用:before伪类加上小图标,就得到了最终效果

。

http://jsfiddle.net/meathill/fPN3p/4/embedded/result/

我无意中发现,这样批量添加删除时,鼠标可以常点不动,应该也是个意外的收获吧。
第三步,加入动画教育用户(失败)

至此功能基本做好了,不过由于修改了行为,可能导致用户迷惑,所以准备加个动画帮助用户理解这个交互。

可惜作为一个新功能,浏览器的支持尚不完善,虽然规范中规定“animatable: yes”,但是实测在Chrome v.30下也无法工作:

http://jsfiddle.net/meathill/Ka66W/1/

看来只有等新版浏览器发布后再去完善了。
兼容性

使用纯CSS做组件,几乎不用担心兼容性问题,因为浏览器本身就做了很好的向下兼容,代码最多不生效,一般不会错。

具体到这个组件,因为只针对视觉效果,没有增删改任何浏览器行为,所以兼容性也没有任何问题。不过最终效果呢,只有支持flexbox和CSS3选择符的浏览器才能正常渲染。

我的环境是Window 8 + Chrome v.30,以及小米2 + Chrome v.30,测试通过。
后记

如今CSS很强,纯CSS可以实现很多功能,希望今后能做出更多有价值的东西。分享这个组件的实现,希望对大家有用。


  • 上一条:
    使用icon fonts来辅助CSS处理图片
    下一条:
    使用clrs.cc来进行炫酷的CSS调色
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客