对于表单,input[type="radio"] 的样式总是不那么友好,在不同的浏览器中表现不一。

2017年11月28日更新

对单选按钮自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :checkbox 来实现。

如果直接对单选按钮设置样式,那么这个伪类并不实用,因为没有多少样式能够对单选按钮起作用。不过,倒是可以基于单选按钮的勾选状态借助组合选择符来给其他元素设置样式。

很多时候,无论是为了表单元素统一,还是为了用户体验良好,我们都会选择 label 元素和 input[type="radio"] 一起使用。当<label>元素与单选按钮关联之后,也可以起到触发开关的作用

思路:

1. 可以为<label>元素添加生成性内容(伪元素),并基于单选按钮的状态来为其设置样式;

2. 然后把真正的单选按钮隐藏起来;

3. 最后把生成内容美化一下。

解决方法:

1. 一段简单的结构代码:

  1. <div class="female">
  2. <input type="radio" id="female" name="sex" />
  3. <label for="female"></label>
  4. </div>
  5. <div class="male">
  6. <input type="radio" id="male" name="sex" />
  7. <label for="male"></label>
  8. </div>

2. 生成一个伪元素,作为美化版的单选按钮,先给伪元素添加一些样式:

  1. input[type="radio"] + label::before {
  2. content: "\a0"; /*不换行空格*/
  3. display: inline-block;
  4. vertical-align: middle;
  5. font-size: 18px;
  6. width: 1em;
  7. height: 1em;
  8. margin-right: .4em;
  9. border-radius: 50%;
  10. border: 1px solid #01cd78;
  11. text-indent: .15em;
  12. line-height:;
  13. }

现在的样子:

原来的单选按钮仍然可见,但是我们先给单选按钮的勾选状态添加样式:

3. 给单选按钮的勾选状态添加不同的样式:

  1. input[type="radio"]:checked + label::before {
  2. background-color: #01cd78;
  3. background-clip: content-box;
  4. padding: .2em;
  5. }

现在的样子:

4. 现在把原来的单选按钮隐藏:

  1. input[type="radio"] {
  2. position: absolute;
  3. clip: rect(0, 0, 0, 0);
  4. }

现在的样子:

隐藏原来的单选按钮时,如果使用 display: none; 的话,那样会把它从键盘 tab 键切换焦点的队列中完全删除。

于是可采用剪切的方式,让剪切后的尺寸为零,这样就隐藏了原来的单选按钮。


下面为旧内容:

为了最大程度的显示出它们的差别,并且为了好看,首先定义了一些样式:

  1. <form action="">
  2. <div class="sex">
  3. <div class="female">
  4. <label for="female"></label>
  5. <input type="radio" name="sex" id="female">
  6. </div>
  7. <div class="male">
  8. <label for="male"></label>
  9. <input type="radio" name="sex" id="male">
  10. </div>
  11. </div>
  12. </form>
  1. body { margin:; }
  2. input { padding:; margin:; border:; }
  3. .female, .male {
  4. position: relative;
  5. height: 40px;
  6. line-height: 40px;
  7. margin-left: 40px;
  8. }
  9. .sex label {
  10. display: block;
  11. height: 40px;
  12. width: 40px;
  13. line-height: 40px;
  14. font-size: 20px;
  15. cursor: pointer;
  16. }
  17. .sex input {
  18. z-index:;
  19. position: absolute;
  20. top:;
  21. bottom:;
  22. left: 40px;
  23. margin: auto;
  24. display: block;
  25. width: 30px;
  26. height: 30px;
  27. cursor: pointer;
  28. }

然后在各个浏览器中观察,会发现有很大的差别:

ie:

edge:

opera:

chrome:

firefox:

对于 firefox 浏览器,即便是设置了宽和高,依然是没有效果,input[type="radio"] 的那个圆圈还是初始状态那么大。其它浏览器的表现也不一致,为了达到一致的效果,我们需要做兼容处理。

思路:

1. 将 input[type="radio"] 隐藏, opacity: 0; 置于上层,当我们点击它时,就能正确的响应原本的事件。

2. 自定义一个圆圈,置于下层,模拟原本相似的样式;

3. 用 js 实现选中 input[type="radio"] 时,在其下层的自定义的元素改变原来的背景颜色。

代码:

  1. <form action="">
  2. <div class="sex">
  3. <div class="female">
  4. <label for="female"></label>
  5. <input type="radio" name="sex" id="female">
  6. <span class="female-custom"></span> <!-- 同下面的 span 一样作为自定义的元素 -->
  7. </div>
  8. <div class="male">
  9. <label for="male"></label>
  10. <input type="radio" name="sex" id="male">
  11. <span class="male-custom"></span>
  12. </div>
  13. </div>
  14. </form>
  1. body { margin:; }
  2. input { padding:; margin:; border:; }
  3. .female, .male {
  4. position: relative; /* 设置为相对定位,以便让子元素能绝对定位 */
  5. height: 40px;
  6. line-height: 40px;
  7. margin-left: 40px;
  8. }
  9. .sex label {
  10. display: block;
  11. height: 40px;
  12. width: 40px;
  13. line-height: 40px;
  14. font-size: 20px;
  15. cursor: pointer;
  16. }
  17. .sex input {
  18. z-index:;
  19. position: absolute;
  20. top:;
  21. bottom:;
  22. left: 40px;
  23. margin: auto; /* 这里及以上的定位,可以让该元素竖直居中。(top: 0; bottom: 0;) */
  24. opacity:;
  25. display: block;
  26. width: 30px;
  27. height: 30px;
  28. cursor: pointer;
  29. }
  30. .sex span {
  31. position: absolute;
  32. top:;
  33. bottom:;
  34. left: 40px;
  35. margin: auto;
  36. display: block;
  37. width: 25px;
  38. height: 25px;
  39. border: 1px solid #000;
  40. border-radius: 50%;
  41. cursor: pointer;
  42. }
  43. .sex span.active {
  44. background-color: #000;
  45. }
  1. $("#male").click( function () {
  2. $(this).siblings("span").addClass("active");
  3. $(this).parents("div").siblings("div").children("span").removeClass("active");
  4. });
  5. $("#female").click( function () {
  6. $(this).siblings("span").addClass("active");
  7. $(this).parents("div").siblings("div").children("span").removeClass("active");
  8. });

这样处理后,在浏览器中展示效果全部一样了:

扩展:

1. 对于代码中出现的定位,对父元素使用 position: relative; 给子元素使用 position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; 能实现让子元素相对于父元素居中(满足水平居中和竖直居中)显示。如果只是需要竖直居中,则不需要添加 right: 0; 和 left: 0; 的样式。

2. 有时当我们不容易确定子元素的高度时,可以这样设置:对父元素 position: relative; 对子元素 position: absolute; top: 10px; bottom: 10px; margin: auto; 这样一来,子元素的高度就是父元素的高度减去20px后的值了,同样,top 和 bottom 支持百分数,可扩展性更强。

优化更新:

需求:

1. 有时候我们需要内联的单选样式;

2. 选中的按钮内的小圆圈不需要占满整个外圈的大小。

思路:

1. 让每一个包裹选择的 div 左浮动;

2. 给父元素添加圆形的外边框,子元素设置一个稍小于父元素大小的背景。

代码:

  1. <form action="">
  2. <div class="fruit">
  3. <div class="apple">
  4. <label for="apple">苹果</label>
  5. <input type="radio" name="fruit" id="apple">
  6. <div class="user-defined">
  7. <span class="circle"></span>
  8. </div>
  9. </div>
  10. <div class="banana">
  11. <label for="banana">香蕉</label>
  12. <input type="radio" name="fruit" id="banana">
  13. <div class="user-defined">
  14. <span class="circle"></span>
  15. </div>
  16. </div>
  17. <div class="orange">
  18. <label for="orange">橘子</label>
  19. <input type="radio" name="fruit" id="orange">
  20. <div class="user-defined">
  21. <span class="circle"></span>
  22. </div>
  23. </div>
  24. </div>
  25. </form>
  1. * { box-sizing: border-box; }
  2.  
  3. body { padding: 50px; }
  4.  
  5. input { padding:; margin:; border:; }
  6.  
  7. .fruit:before { content: ""; display: table; }
  8.  
  9. .fruit:after { content: ""; display: table; clear: both; }
  10.  
  11. .fruit > div { position: relative; float: left; margin-right: 50px; width: 80px; height: 40px; line-height: 40px; }
  12.  
  13. .fruit > div:last-child { margin-right:; }
  14.  
  15. .fruit label { display: block; width: 50px; height: 40px; line-height: 40px; cursor: pointer; }
  16.  
  17. .fruit input { z-index:; display: block; opacity:; position: absolute; top:; bottom:; left: 50px; margin: auto; width: 30px; height: 30px; cursor: pointer; }
  18.  
  19. .fruit .user-defined { z-index:; position: absolute; top:; bottom:; left: 50px; margin: auto; width: 30px; height: 30px; border: 1px solid #000; border-radius: 50%; cursor: pointer; }
  20.  
  21. .fruit .user-defined span.circle { display: block; width: 24px; height: 24px; margin-top: 2px; margin-left: 2px; background-color: transparent; border-radius: 50%; }
  22.  
  23. .fruit .user-defined span.active { background-color: #000; }
  1. $("input").click(function() {
  2. $(this).siblings("div").children("span").addClass("active");
  3. $(this).parents("div").siblings("div").find("span").removeClass("active");
  4. });

效果显示如下:

优化更新: (2016年11月07日)

需求:

1. 有时候我们的选择只有两种,比如性别;

2. 这种选择希望能像手机系统设置里的切换一样。

思路:

1. 让每一个包裹选择的 div 左浮动;

2. 让当前子元素添加区别的背景。

预期结果:

代码:

  1. <div class="sex">
  2. <span class="warning fl">性别确定后将不可更改!</span>
  3. <div class="select fr">
  4. <div class="male fl">
  5. <label for="male">
  6. <input type="radio" name="sex" id="male" checked>
  7. </label>
  8. <span class="btn active"></span>
  9. </div>
  10. <div class="female fl">
  11. <label for="female">
  12. <input type="radio" name="sex" id="female">
  13. </label>
  14. <span class="btn"></span>
  15. </div>
  16. </div>
  17. </div>
  1. /*性别*/
  2. .sex span.warning {
  3. font-size: 1.4rem;
  4. color: #ccc;
  5. }
  6. .sex .male,
  7. .sex .female {
  8. position: relative;
  9. width: 4rem;
  10. height: 3.9rem;
  11. z-index:;
  12. line-height: 3.9rem;
  13. text-align: center;
  14. }
  15. .sex .male label,
  16. .sex .female label {
  17. position: absolute;
  18. top:;
  19. bottom:;
  20. left:;
  21. width: 4rem;
  22. height: 3.9rem;
  23. z-index:;
  24. opacity:;
  25. margin: auto;
  26. display: inline-block;
  27. line-height: 3.9rem;
  28. cursor: pointer;
  29. }
  30. .sex input {
  31. display: inline-block;
  32. vertical-align: middle;/*让默认的单选样式的圆圈和“男”“女”的文本没有高差,看起来在同一水平线*/
  33. height: 2.8rem;
  34. line-height: 2.8rem;
  35. margin:; /*清除浏览器默认的外边距*/
  36. }
  37. .sex .male span.btn,
  38. .sex .female span.btn {
  39. position: absolute;
  40. top:;
  41. bottom:;
  42. left:;
  43. width: 4rem;
  44. height: 2.8rem;
  45. z-index:;
  46. margin: auto;
  47. display: inline-block;
  48. line-height: 2.6rem;
  49. text-align: center;
  50. border: .1rem solid #fe5454;
  51. color: #fe5454;
  52. }
  53. .sex .male span {
  54. border-top-left-radius: .2rem;
  55. border-bottom-left-radius: .2rem;
  56. }
  57. .sex .female span {
  58. border-top-right-radius: .2rem;
  59. border-bottom-right-radius: .2rem;
  60. }
  61. .sex .male span.active,
  62. .sex .female span.active {
  63. background-color: #fe5454;
  64. color: #fff;
  65. }

如果用 jQuery 来写切换的功能的话,很简单的几行代码:

  1. $(".select label").click(function() {
  2. $(this).siblings("span").addClass("active");
  3. $(this).parent().siblings("div").find("span").removeClass("active");
  4. });

最后,做出来的效果单选原样式没有 opacity: 0; 隐藏时:

单选原样式 opacity: 0; 隐藏时:

自定义input[type="radio"]的样式的更多相关文章

  1. 自定义input[type="radio"]的样式(支持普通浏览器,IE8以上)

    对于表单,input[type="radio"] 的样式总是不那么友好,在不同的浏览器中表现不一. 对单选按钮自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :c ...

  2. 自定义input[type="radio"]

    对于表单,input[type="radio"] 的样式总是不那么友好,在不同的浏览器中表现不一. 对单选按钮自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :c ...

  3. 原生javascript自定义input[type=radio]效果

    2018年6月27日 更新 找到最为简单的仅仅使用css3的方案 <!DOCTYPE html> <html lang="en"> <head> ...

  4. 自定义input[type="file"]的样式

    input[type="file"]的样式在各个浏览器中的表现不尽相同: 1. chrome: 2. firefox: 3. opera: 4. ie: 5. edge: 另外,当 ...

  5. 自定义input[type="checkbox"]的样式

    对复选框自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :checkbox 来实现. 如果直接对复选框设置样式,那么这个伪类并不实用,因为没有多少样式能够对复选框起作用.不过,倒是可 ...

  6. 纯css兼容个浏览器input[type='radio']不能自定义样式

    各个浏览器对于表单input[type='radio'].input[type='checkbox']的样式总是各有差异   //html <div class="remember-a ...

  7. input[type="radio"]自定义样式

    input为radio时,虽然会有默认选中的样式,但是并不符合大多数项目的需求,我们的目标是可以随心所欲自定义它的样式.怎么做呢?其实很简单,只要抓住3点.分别是1.label 2.隐藏自带样式 3. ...

  8. 如何更改 iOS 和安卓浏览器上的 input[type="radio"] 元素的默认样式?

    Safari 上的默认样式是这样的, 背景颜色可以使用background-color改变,但中间那个点始终无法去掉. 我查了一些jQuery插件,如iCheck.js,但是那说明写得我都看不明白,根 ...

  9. 定制 input[type="radio"] 和 input[type="checkbox"] 样式

    表单中,经常会使用到单选按钮和复选框,但是,input[type="radio"] 和 input[type="checkbox"] 的默认样式在不同的浏览器或 ...

随机推荐

  1. 论httpclient上传带参数【commons-httpclient和apache httpclient区别】

    需要做一个httpclient上传,然后啪啪啪网上找资料 1.首先以前系统中用到的了commons-httpclient上传,找了资料后一顿乱改,然后测试 PostMethod filePost = ...

  2. c语言笔试题(带答案)

    填空: 1,short int a[10]={123, 456, 789}; sizeof(a)= 对于64位机来说,指针为8字节表示.其中 sizeof是一运算符,返回编译器为其分配的数组空间大小, ...

  3. u-boot移植总结(一)start.S分析

    本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定 ...

  4. DoTween小结

    using UnityEngine; using System.Collections; using DG.Tweening; public class GetStart : MonoBehaviou ...

  5. AI - Ideas

    Idea: Comprehend code and re-factory code to more readable. The AI program can comprehend source cod ...

  6. [python学习笔记]Day2

    摘要: 对象 对于python来说,一切事物都是对象,对象基于类创建: 注:查看对象相关成员 var,type,dir 基本数据类型和序列 int内部功能 class int(object): def ...

  7. Windows程序控件升级==>>构建布局良好的Windows程序

    01.菜单栏(MenuStrip) 01.看看这就是menuStrip的魅力: 02.除了一些常用的属性(name.text..)外还有: 03.有人会问:上图的快捷键: 方法: 方式一:1.设置菜单 ...

  8. ssh 客户端远程vi文本文件中文乱码(亲测)

    由于是生产环境,且非笔者控制,为了避免影响系统全局,仅对本session有效 export LANG="zh_CN.UTF-8"export LANG="zh_CN.GB ...

  9. 【GOF23设计模式】建造者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]建造者模式详解类图关系 建造飞船 package com.test.Builder; public class AirShi ...

  10. CMD和AMD

    CMD是国内玉伯在开发SeaJS的时候提出来的,属于CommonJS的一种规范,此外还有AMD,其对于的框架是RequireJS. 二者的异同之处: 二者都是异步(Asynchronuous Modu ...