给文字加一条中划线

前言

这周在学习结合React使用Redux,参考TodoMVC,做个类似的demo

在实现的过程中,发现了个之前没有注意到的CSS效果, text-decoration: line-through, 先来看效果图:

图1:

单选框未选中

图2:

单选框已选中

观察单选框选中后的文字样式, 它除了颜色有变化外, 还多了一条贯穿文字的中划线, 它就是使用 text-decoration: line-through 实现的.

对此我为何会兴奋? 先来看看我以前的实现方式.

1.伪元素

第一次做这种效果的时候, 我使用的是伪元素. 思路是: 当单选框选中时,给文字添加一个伪元素, 由伪元素来画这条中划线.

假设文字的class.text, 参考CSS代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
.text {
position: relative;
}

.text::after {
content: '';
position: absolute;
display: block;
width: 100%;
height: 1px;
top: 50%;
}

这种方式是纯CSS的实现, 缺点是要写的代码比较多(跟后面的实现方式相比)

2.strike 或 del 标签

使用strikedel标签即可为文本标记添加删除线(也即本文指的中划线)

从规范上来说, strike标签已不被鼓励使用, 请使用del标签是来替代, 该标签已被所有的主流浏览器支持(IE6+, Firefox 2+, Chrome 1+ 等)

这是我后面无意中浏览文档看到的. 结合React运用到实践的话, 思路应该是: 单选框选中时, 改变组件的state, 引起组件重新render; 而render里根据不同的state渲染不同的标签

参考JSX代码如下:

1
2
3
4
5
6
7
8
9
10
render() {
const text = this.state.text;
return(
{
this.state.checked ?
<del>{text}</del> :
<span>{text}</span>
}
)
}

这是种纯Javscript的实现方式, 优点在于代码量少, 但缺点在于对DOM的操作较频繁.

为什么这么说呢? 假设单选框未选中, 此时组件渲染出来的是span; 选中单选框后, 组件重新渲染, 此时React的Virtual DOM比较两次渲染的差异, 然后会在真实的DOM中选把span标签先删除掉, 再插入del标签. 因此, 每点击一下单选框, 就会操作两次DOM.

3.text-decoration: line-through

text-decoration 是CSS2.1的就有的, 不用担心浏览器兼容性问题, 可以大胆的使用.

现假设文本元素的class.text, 单选框的下一个兄弟元素就是它, CSS参考代码如下:

1
2
3
input[type=radio]::checked + .text {
text-decoration: line-through;
}

这也是纯CSS的实现方式, 这种实现方式结合了前面二者的优点:

  1. 代码量少
  2. 不需要操作DOM

以后再遇到给文字添加中划线的需求, 请使用text-decoration: line-through吧!

Fork me on GitHub