用css画一个漂亮的分割线

某个baka把我的博客弄坏了,导致人家好长时间写不了博客好难受ヽ(✿゚▽゚)ノ。今天博客修好了所以赶紧上来发一篇(≖ᴗ≖๑),大家想我没~

今天说的是如何画一个分割线。从小学开始我就有个非常2B偏见,用hr元素画出来的分割线不好看,也没有优化的余地。粗浅的学过css后我试着把实线的hr做成虚线的hr,不过说到头它不还是根线……

直到有一天我大概懂了伪元素到底是怎么回事,我眼中的hr变得不一样了~

撒,先说hr元素,其实这玩意挺诡异的,哪里诡异下一小节讨论。w3school中这么说hr

标签在 HTML 页面中创建一条水平线。
水平分隔线(horizontal rule)可以在视觉上将文档分隔成各个部分。
在 XHTML 中, 必须被正确地关闭,比如 <hr />

不过我大概尝试了下,在Firefox中,譬如<hr> Hello, world! <hr/>这种诡异的写法也能被准许……不过我用w3c验证工具验证了下这段代码:

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<head>
<meta charset=”utf-8” />
<title>Hello, world!</title>
</head>
<div>
<hr> Hello, world! </hr>
</div>

没通过验证。换句话说hr元素是不存在“元素内部”这个概念的,所以这种诡异的用法是不被准许的,请老老实实的这么用:<hr />

为啥我要做这么无聊的实验呢?让我们来说说伪元素。

伪元素,MDN这么解释的:

伪元素被添加到选择器后而不用单独特殊的去描述, 他们允许你给文档的某些部分添加样式. 例如, 使用 ::first-line

伪元素会匹配由选择器中所指定的元素的第一行。

#aaa::before 就相当于向元素内部的头部插入一个元素(类似HTML中的标签,不过不太一样);#aaa::after则是向内部的后方插入。

转换成伪代码就是这样的:

1
2
3
4
<div id="aaa">
<before>content</before>
<after>content</after>
</div>

请注意……HTML中没有beforeafter这俩标签,这是我为了方便解释捏造的……只是等效而已……

伪元素中的内容是由css的content属性控制的,比如伪元素的内容是一个零宽空格的话需要这么写:content:"\feff";;没有content属性或者content的内容为空的伪元素不会被显示出来。详细内容各位可以自行去查,这不是我们要讲的内容。( (¬д¬。) 你看我多善解人意,地址都给你贴出来了……

接下来我们说说为啥我认为hr准许使用伪元素是件很诡异的事情:

理论上讲hr标签内是不准许插入内容的,我们不能像向div中插入后代一样向hr中插入后代,比如一张图片,不过它是一个空元素(感谢静琴姐指教),像img, br这样的标签都属于空元素,这些空元素是有模型盒的,所以可以勉强的塞入内容(其实不勉强……

还有另一种例子:input元素就不支持伪元素,具体细节很复杂……你可以把input理解为一个系统级控件映射在页面,是不具有模型盒的东西。具体我也不是很清楚所以就不说了,恩……(눈_눈)

不过这不是重点……既然它支持我们就用呗:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
hr{
left:50%;
width:8px;height:8px;
border:0;
border-radius:50%;
margin:30px 0 30px -14px;
background:#666;
display:block;
position:relative;
}

hr::before,hr::after{
top:1px;
content:"\200B";
width:6px;height:6px;
border:0;
border-radius:50%;
background:#999;
display:block;
position:absolute;
}

hr::before{
left:-10px;
}

hr::after{
right:-10px;
}

没了。