前端开发过程中,由于不同浏览器间的不兼容性,相同的标签在不同的浏览器中显示不同的效果。尤其在移动端开发中,安卓与iOS表单元素显示各不相共,所以在前端页面开发过程中,需要统一相关样式,前端er需要自己开发相应组件去实现对应标签功能。
知识点: css3中before与after选择器,兄弟选择器,checked选择器
本示例通过css3实现浏览器下checkbox选中与未选中效果。
![](https://img.haomeiwen.com/i7513201/ce0e512e8b6a46c5.png)
1、html结构
<div class='checkbox'>
<input type='checkbox' id='checkbox1' name='checkboox[]'>
<label for='checkbox1'>篮球</label>
</div>
结构比较简单,通过一个div,包含一个ckeckbox选择框,一个label
2、给这三个标签添加样式
.checkbox {
position: relative;
height: 30px;
}
checkbox选择框设置opacity为0,及用户不能直接感受到它的存在
.checkbox input[type='checkbox'] {
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
opacity: 0;
}
.checkbox label {
position: absolute;
left: 30px;
top: 0;
height: 20px;
line-height: 20px;
}
通过label的before与after实现圆点未选中效果,设置before为圆圈,after实现选中后对勾的效果,设置after为长方形,顺时针旋转45deg,设置右边框与下边框,色值为白色。
.checkbox label:before {
content: '';
position: absolute;
left: -30px;
top: 0;
width: 20px;
height: 20px;
border: 1px solid #ddd;
border-radius: 50%;
transition: all 0.3s ease;
-webkit-transition: all 0.3s ease;
}
.checkbox label:after {
content: '';
position: absolute;
left: -22px;
top: 3px;
width: 6px;
height: 12px;
border: 0;
border-right: 1px solid #fff;
border-bottom: 1px solid #fff;
background: #fff;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transition: all 0.3s ease;
-webkit-transition: all 0.3s ease;
}
添加input选中时的效果,设置before与after的背景色相同,由于after元素有背景色为白色的边框,即可实现相关效果
.checkbox input[type='checkbox']:checked + label:before {
background: #4cd764;
border-color: #4cd764;
}
.checkbox input[type='checkbox']:checked + label:after {
background: #4cd764;
}
上述实现的方法是使input元素透明,然后在 label 下添加伪类来做选择框。选中状态的表示就是改变伪类的背景色为绿色。
自己也实验过另一种方法,把伪类直接跟在input下,但是这种方法只能在Chrome上用,如下
.checkbox input[type='checkbox']:after {
content: url('../assets/images/unChecked.svg');
}
.checkbox input[type='checkbox']:checked:after{
content: url('../assets/images/checked.svg');
}
虽然代码是简洁了些,但是兼容不允许啊,查了下文档,emmm规范特么很含蓄的说道:
Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content. The 'content' property, in conjunction with these pseudo-elements, specifies what is inserted.
http://www.w3.org/TR/CSS21/generate.html#before-after-content
:before和:after伪元素指定了一个元素文档树内容之前和之后的内容。'content'属性,与这些伪元素联用,指定了插入的内容。这个元素是要可以插入内容的,也就是说这个元素要是一个容器。
input,img,iframe等元素都不能包含其他元素,所以不能通过伪元素插入内容。至于Chrome 中checkbox和radio可以插入,那应该是Bug了,要么就是姿势不对了。
所以以下用stylus 来实现的时候就用网友提供的方法啦。
原理都一样,就不多述了。
这里checkbox是用css自己写的。那可不可以用图片来实现呢?
用图片来实现就简单些了,因为不用自己去写○和√,直接用图片来代替,所以label的伪类我们可以只用一个,after 或 before 来插入图片,选中状态时再来改变该图片,就over了。
下面来看一个完整的例子:
1.效果图:
![](https://img.haomeiwen.com/i7513201/d3a92de58c710223.gif)
2.完整代码:
<template>
<div class="todo-wrapper">
<div v-for='todo in todos' :key='todo.id' :class="['todo-item', todo.complated ? 'complated' : '']">
<input
type="checkbox"
v-model="todo.complated"
>
<label>{{todo.content}}</label>
<button class="del" @click="deleteTodo(todo.id)"></button>
</div>
</div>
</template>
<script>
export default {
data () {
return {
todos: [
{
id: 0,
content: '排球',
complated: false
},
{
id: 1,
content: '足球',
complated: false
},
{
id: 2,
content: '篮球',
complated: true
}
]
}
},
methods: {
deleteTodo (id) {
this.todos.splice(this.todos.findIndex(item => item.id === id), 1)
}
}
}
</script>
<style lang="stylus" scoped>
.todo-wrapper
padding 20px
font-size 18px
text-align left
background #ffffff
.todo-item
position relative
height 30px
&:hover
color #000
font-weight 500
.del:after //hover todo-item 时 .del 增加一个伪类并插入内容x
content 'x'
&.complated // todo-item complated 类都存在时,设置label样式
label
color #ccc
text-decoration line-through
input[type='checkbox']
position absolute
left 0
top 0
z-index 2
width 20px
height 20px
opacity 0
label
position absolute
left 30px
top 0
height 20px
line-height 20px
&:before
content: ''
background url('../assets/images/unChecked.svg') center center no-repeat
background-size 96%
position absolute
left -30px
top 0
width 20px
height 20px
transition all .3s ease
.del
position absolute
top 0
right 10px
bottom 0
width 40px
height 40px
margin auto 0
font-size 30px
color #cc9a9a
margin-bottom 11px
transition color 0.2s ease-out
background-color transparent
appearance none
border-width 0
cursor pointer
outline none
.todo-item input[type='checkbox']:checked + label:before {
content: ''
background url('../assets/images/checked.svg') center center no-repeat
background-size 96%
}
</style>
最后看到一个比较简单的例子。
思路也大致相同:
1.清除input默认属性并设为透明
2.通过定位让用户看到的是<span>选择框
3.设置选中后的span样式,即input[type=checkbox]:checked+span
效果图:
![](https://img.haomeiwen.com/i7513201/6b5ab765724410fa.png)
<!DOCTYPE html>
<html>
<style>
/* The container */
.container {
display: block;
position: relative;
padding-left: 35px;
margin-bottom: 12px;
cursor: pointer;
}
/* Hide the browser's default checkbox */
.container input {
position: absolute;
height: 0;
width: 0;
opacity: 0;
appearance: none;/*清除默认样式*/
-webkit-appearance: none;
}
/* Create a custom checkbox */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 25px;
width: 25px;
background-color: #eee;
border-radius: 50%
}
.container input:checked + .checkmark {
background-color: #abcdef;
}
.container input:checked + .checkmark:after {
content: "";
position: absolute;
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
</style>
<body>
<label class="container">One
<input type="radio" checked="checked">
<span class="checkmark"></span>
</label>
</body>
</html>
以上是checkbox单选框的实现代码,radio也是类似 将input type定义成radio即可。
网友评论