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

2017年11月28日更新

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

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

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

思路:

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

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

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

解决方法:

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

<div class="female">
<input type="radio" id="female" name="sex" />
<label for="female">女</label>
</div>
<div class="male">
<input type="radio" id="male" name="sex" />
<label for="male">男</label>
</div>

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

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

现在的样子:

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

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

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

现在的样子:

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

input[type="radio"] {
position: absolute;
clip: rect(0, 0, 0, 0);
}

现在的样子:

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

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


下面为旧内容:

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

<form action="">
<div class="sex">
<div class="female">
<label for="female">女</label>
<input type="radio" name="sex" id="female">
</div>
<div class="male">
<label for="male">男</label>
<input type="radio" name="sex" id="male">
</div>
</div>
</form>
body { margin:; }
input { padding:; margin:; border:; }
.female, .male {
position: relative;
height: 40px;
line-height: 40px;
margin-left: 40px;
}
.sex label {
display: block;
height: 40px;
width: 40px;
line-height: 40px;
font-size: 20px;
cursor: pointer;
}
.sex input {
z-index:;
position: absolute;
top:;
bottom:;
left: 40px;
margin: auto;
display: block;
width: 30px;
height: 30px;
cursor: pointer;
}

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

ie:

edge:

opera:

chrome:

firefox:

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

思路:

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

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

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

代码:

<form action="">
<div class="sex">
<div class="female">
<label for="female">女</label>
<input type="radio" name="sex" id="female">
<span class="female-custom"></span> <!-- 同下面的 span 一样作为自定义的元素 -->
</div>
<div class="male">
<label for="male">男</label>
<input type="radio" name="sex" id="male">
<span class="male-custom"></span>
</div>
</div>
</form>
body { margin:; }
input { padding:; margin:; border:; }
.female, .male {
position: relative; /* 设置为相对定位,以便让子元素能绝对定位 */
height: 40px;
line-height: 40px;
margin-left: 40px;
}
.sex label {
display: block;
height: 40px;
width: 40px;
line-height: 40px;
font-size: 20px;
cursor: pointer;
}
.sex input {
z-index:;
position: absolute;
top:;
bottom:;
left: 40px;
margin: auto; /* 这里及以上的定位,可以让该元素竖直居中。(top: 0; bottom: 0;) */
opacity:;
display: block;
width: 30px;
height: 30px;
cursor: pointer;
}
.sex span {
position: absolute;
top:;
bottom:;
left: 40px;
margin: auto;
display: block;
width: 25px;
height: 25px;
border: 1px solid #000;
border-radius: 50%;
cursor: pointer;
}
.sex span.active {
background-color: #000;
}
$("#male").click( function () {
$(this).siblings("span").addClass("active");
$(this).parents("div").siblings("div").children("span").removeClass("active");
});
$("#female").click( function () {
$(this).siblings("span").addClass("active");
$(this).parents("div").siblings("div").children("span").removeClass("active");
});

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

扩展:

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. 给父元素添加圆形的外边框,子元素设置一个稍小于父元素大小的背景。

代码:

<form action="">
<div class="fruit">
<div class="apple">
<label for="apple">苹果</label>
<input type="radio" name="fruit" id="apple">
<div class="user-defined">
<span class="circle"></span>
</div>
</div>
<div class="banana">
<label for="banana">香蕉</label>
<input type="radio" name="fruit" id="banana">
<div class="user-defined">
<span class="circle"></span>
</div>
</div>
<div class="orange">
<label for="orange">橘子</label>
<input type="radio" name="fruit" id="orange">
<div class="user-defined">
<span class="circle"></span>
</div>
</div>
</div>
</form>
* { box-sizing: border-box; }

body { padding: 50px; }

input { padding:; margin:; border:; }

.fruit:before { content: ""; display: table; }

.fruit:after { content: ""; display: table; clear: both; }

.fruit > div { position: relative; float: left; margin-right: 50px; width: 80px; height: 40px; line-height: 40px; }

.fruit > div:last-child { margin-right:; }

.fruit label { display: block; width: 50px; height: 40px; line-height: 40px; cursor: pointer; }

.fruit input { z-index:; display: block; opacity:; position: absolute; top:; bottom:; left: 50px; margin: auto; width: 30px; height: 30px; cursor: pointer; }

.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; }

.fruit .user-defined span.circle  { display: block; width: 24px; height: 24px; margin-top: 2px; margin-left: 2px; background-color: transparent; border-radius: 50%; }

.fruit .user-defined span.active  { background-color: #000; }
$("input").click(function() {
$(this).siblings("div").children("span").addClass("active");
$(this).parents("div").siblings("div").find("span").removeClass("active");
});

效果显示如下:

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

需求:

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

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

思路:

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

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

预期结果:

代码:

<div class="sex">
<span class="warning fl">性别确定后将不可更改!</span>
<div class="select fr">
<div class="male fl">
<label for="male">
<input type="radio" name="sex" id="male" checked>男
</label>
<span class="btn active">男</span>
</div>
<div class="female fl">
<label for="female">
<input type="radio" name="sex" id="female">女
</label>
<span class="btn">女</span>
</div>
</div>
</div>
/*性别*/
.sex span.warning {
font-size: 1.4rem;
color: #ccc;
}
.sex .male,
.sex .female {
position: relative;
width: 4rem;
height: 3.9rem;
z-index:;
line-height: 3.9rem;
text-align: center;
}
.sex .male label,
.sex .female label {
position: absolute;
top:;
bottom:;
left:;
width: 4rem;
height: 3.9rem;
z-index:;
opacity:;
margin: auto;
display: inline-block;
line-height: 3.9rem;
cursor: pointer;
}
.sex input {
display: inline-block;
vertical-align: middle;/*让默认的单选样式的圆圈和“男”“女”的文本没有高差,看起来在同一水平线*/
height: 2.8rem;
line-height: 2.8rem;
margin:; /*清除浏览器默认的外边距*/
}
.sex .male span.btn,
.sex .female span.btn {
position: absolute;
top:;
bottom:;
left:;
width: 4rem;
height: 2.8rem;
z-index:;
margin: auto;
display: inline-block;
line-height: 2.6rem;
text-align: center;
border: .1rem solid #fe5454;
color: #fe5454;
}
.sex .male span {
border-top-left-radius: .2rem;
border-bottom-left-radius: .2rem;
}
.sex .female span {
border-top-right-radius: .2rem;
border-bottom-right-radius: .2rem;
}
.sex .male span.active,
.sex .female span.active {
background-color: #fe5454;
color: #fff;
}

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

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

最后,做出来的效果单选原样式没有 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. [moka同学笔记]YII2中发送邮件示例(转载)

    原文:http://yiilib.com/topic/675/Yii2%E4%B8%AD%E5%8F%91%E9%80%81%E9%82%AE%E4%BB%B6%E7%A4%BA%E4%BE%8B { ...

  2. IBATIS动态SQL(转)

    直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值.参数本身和数据列都是动态SQL,通常是非常困难的.典型的解决办法就是用上一堆的IF-ELSE条件语句和一连串的字符串连接.对于这个问题,I ...

  3. js小数计算小数点后显示多位小数(转)

    首先写一个demo 重现问题,我使用的是一个js在线测试环境[打开] 改写displaynum()函数 function displaynum(){var num = 22.77;alert(num ...

  4. 开源论坛MvcForum推荐

    MvcForum算是Asp.net中开源论坛佼佼者之一.主要使用ASP.NET MVC 5 &Unity & Entity Framework 6,有较强的可撸性.是论坛开发者的不二之 ...

  5. 成熟的RosettaNet解决方案软件介绍

    RosettaNet是一套B2B标准,以标准来优化供应链管理流程,它可以缩短整个供应链各个供货周期.RosettaNet 标准为电子商务标准化提供一个健壮的.非专有的解决方案,它是免费的,通过 Ros ...

  6. Metronic 使用到的开源插件汇总

    Metronic 是一套完整的 UI 模板,但不仅仅是模板,更应该说是一个 UI 框架.它除了提供了大量网页模板,也提供了非常多的 UI 组件,并且应用了众多 jQuery 插件.通过这些资源的整合, ...

  7. API的非向后兼容性无论如何通常代表着一种比较差的设计

    不管一个类库或者工具方法实现多么的好,如果无法做到向后兼容性,通常会给用户带来很大的升级成本,很多对此的依赖如果希望在后续的升级和维护期间使用该类库的其他新增特性或者好处,将不得不推迟升级亦或是被迫接 ...

  8. mariadb connector bug

    为了解决http://www.cnblogs.com/zhjh256/p/5807086.html的问题测试mariadb connector,常规的增删改查没有问题. 这货本来是为了解决存储过程bu ...

  9. SharpGL学习笔记(十九) 摄像机漫游

    所谓的摄像机漫游,就是可以在场景中来回走动. 现实中,我们通过眼睛观察东西,身体移动带动眼睛移动观察身边的事物,这也是在漫游. 在OpenGL中我们使用函数LookAt()来操作摄像机在三维场景中进行 ...

  10. 六个字符,带你领略JavaScript (js的艺术编写)

    正文从这开始- JavaScript是一门神奇且奇妙的编程语言,我们有时候用它来写一些看似疯狂的代码,但这些代码依然可被执行且运行结果十分有趣.JavaScript 试图帮助我们将一些数据类型转化为我 ...