伪类与伪元素

时间:2022-09-26 08:27:38

伪类——:active,:focus,:hover,:link,:visited,:first-child,:lang

伪元素——::before,::after,::first-letter,::first-line

今天了解了一下伪类和伪元素,然后看到一些文章叙述两者的区别,很多人普遍认为这区别在于伪元素可以创建新的元素节点,但我总觉得这样还是有点牵强,尤其是first-line和first-letter,他们也是从现有的元素中作样式的处理。

我的看法是,首先,伪类和伪元素同属于css选择器,这是不争的事实,那么这样就很容易解释了:

1、伪类就是通过属性来选择你想要的元素,这些元素都是存在于DOM结构之中的(a标签或许比较特殊吧,但我觉得这些伪类只是不同的状态,不会影响到DOM结构),想要获取这些元素我们可以设置相应的属性值来筛选,而伪类就是简化了这一过程;

2、伪元素是无需改变DOM就能进行筛选的一种选择器,如果没有这一方法,我们必然会改动DOM结构,比如我们要让首字母大写,那就不得不在“a”字母旁加上span从而来控制样式,这样就会改变其DOM结构,有了伪元素,这样就方便了很多。(伪元素在ie8以下是用的“:”,所以在实际使用时建议统一用“:”)

<p>a fall into the pit, a gain in your wit.</p>

 

下面讨论一下具体的伪类和伪元素

 1、first-child(last-child、nth-child(n)、nth-last-child(n)也差不多)的用法还是蛮奇葩的,比如 div p:first-child{},

<div class="content">
<h1>第一个子元素</h1>
<p>第一个p</p>
<p>其他</p>
<p>其他</p>
</div>

一开始我还以为这代表着的是父元素div下的第一个p元素,后来我发现我错了,这个选择器其实是这样解释的,先按照前面的选择器规则选出所有p,比如上面就是选出div下面的所有p元素,然后对这些p进行判断,如果某一个p是父元素下面的第一个子元素,那么该p就入围了;只是这样一来,限制的条件更强了,大家或许会觉得这个选择器有点鸡肋(下面的小结是我看好这个选择器的想法),因为我们通常并不在意p前面是否有其他元素,我们只需要选择出满足前面选择条件的第一个p,那么这样又该如何解呢?

2、nth-of-type(n),这时候就要靠这个伪类选择器了,它就可以选择出第n个满足前置条件的元素,如果要倒过来数的话可以用nth-last-of-child(n);

3、与前面类似的还有only-child——选出所有div下的p,如果p的父元素div下没有其他子元素,那么该p就入围了;only-of-type——选出所有div下的p,如果p元素同一层级下没有其他p,那该p就出线了;

小结:上述伪类选择器大多用于li标签上,这样的话两者基本上就没有区别,而在性能方面first-child只要在前面选择条件下做一次DOM结构下的判断就可以了,这样对网页的加载负担稍稍小一点(还有一点也可能在于浏览器方面:first-child ie7+,而nth-of-type ie9+),所以可以发现虽然nth-of-type很强大,但大家还是用first-child居多;当然如果作用于普通的非列表标签元素下,想要通过伪类来选择,nth-of-type(n)还是无法替代的。

 


 

:link       默认样式

:visited  已访问

:hover   鼠标移至元素上方,且该元素未被激活(选择器可用于所有元素,不仅是链接)。

:active   按下左键释放之前

对于a标签,:hover 必须位于 :link 和 :visited 之后!

 


 

 

:empty                  满足前置条件且元素内为空

:not(selector)        多一种判断方法(但是这种反向选择方法一般都可以通过正向选择来替代)

:root                    选择document的根目录(一般等同于html标签)

:target                 这个伪类选择器可以实现a标签点击后执行相应的效果(a标签中href属性指向的是当前页面中某个id),乍一看似乎就相当于js中的onclick事件,但实际上差别不小。比如按照下面代码,点击之后会执行href跳转,然而在跳转的时候,视窗位置也会跳转到目标位置,所以一旦事件需要绑定多个效果,那么target还是只能退居二线。

:lang()                 该选择器是用来向带有指定 lang 属性开始的元素添加样式,而lang属性一般用来定义当前文档显示的语言,单独的用于文本元素中,或许也是对span标签的一种替换方案吧。

 


 

 

剩下的伪类选择器都是和表单元素相关的了,不过我测试了以后,发现和属性选择器产生的效果没什么差别:一个是:required ,还有一个是input[required='required'];两者都能准确的找到相应的元素,刚刚发现一个问题,那就是属性选择器适用于确定的值的情况,有些需要用户提供数据的话再进行判断就显得很复杂了,比如说要选出所有用户输入数值在指定范围内的元素,还是用伪类:in-range方便很多,遗憾的是ie对这方面不怎么支持。

【ie9+支持的】:checked——选中的        :focus——触发焦点的          :disabled——禁用的                 :enabled——启用的

【ie10+支持的】:valid——有效的           :invalid——无效的               :optional——不是必要的           :required——必需的      

【ie不支持的】:in-range——在范围内的(一般对<input type=number min=‘1’ max=‘10’ value=‘7’>进行定义,在用户键入数值后再进行判断筛选)        :out-of-range——超出范围的            :read-only——只读的           :read-write——可以读写的       


 

 

最后还剩4个伪元素:

::first-line   这是对文本的首行设置特殊样式【该伪类只能作用于块状元素,可应用的属性有:

  • font properties
  • color properties 
  • background properties
  • word-spacing
  • letter-spacing
  • text-decoration
  • vertical-align
  • text-transform
  • line-height
  • clear        】
<div>
<p>这里是中文的一句话aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
    *{margin: 0; padding: 0; border: 0;}
div
{width: 200px;}
p:first-line
{
color
: #f00;
font-variant
: small-caps;
}

伪类与伪元素

这个伪元素的效果确实是可以的,可是为何它会自己换行???我网上在线测试也是如此,真是百思不得其姐。

搞了半天,才想起来浏览器把这些a搞成了一个单词。。。真是醉了。

 

::first-letter    用于向文本的首字母设置特殊样式【该伪类只能作用于块状元素,可应用的属性相比于::first-line多了margin和padding选项】

 

::before和::after    向选择的元素后部添加样式,但是DOM结构不会因此受到影响.

<div>这是before和after作用的元素</div>
    *{margin: 0; padding: 0; border: 0;}
div
{margin-left: 300px; width: 200px; height: 200px; background: #f00;}
div::before
{content: '.'; width: 100px; height: 100px; background: #00f; }
div::after
{content: '.'; display: block; width: 100px; height: 100px; background: #0ff;}

 

首先,必须要有content属性,否则什么都不会有,然后是设置块状元素,如果没有,则默认为行内元素,正如上面::before一般,不知大家注意到没,在框中出现了'.'(.的位置也是正常文本中标点应该出现的地方),其实设置content:“”也是可以的。

最关键的一点是::before和::after都处于作用元素div的内部。

利用::before和::after可以省去很多不必要的标签,现在利用css绘制图形大多都是利用的这个方法,例:css巧用:before和:after

另外,现在比较流行的是利用::after 来清除浮动

.fix{*zoom:1;}
.fix:after
{content:"clear"; display:block; height:0; clear:both; visibility:hidden;}

相比于overflow:hidden/auto,::after可以在需要有滚动条的时候也能清除浮动。

 

总结:当然,伪类和伪元素还有很多本文没有考虑到的功能,这些功能只能以后慢慢去探索了。


 

发现一个有趣的使用方法,就是伪类和伪元素配合使用。比如

.text:after{content:''; display:block; width:100px; height:100px; border:1px solid #d0d0d0;
}
.text:after:hover
{border:3px solid #555;}

是不是很强大?

只不过在实际的使用过程中,伪元素的使用除了清除浮动外,用的并不多,这关键还是和他的性质有关,伪元素因为不是实际的dom元素,所以无法直接用js操作其样式,只能用其他样式来取代之,也就是说伪元素一般就是需要写死的,改动起来很麻烦。(不过伪元素有一个不错的使用方法,就是让content:attr(href),这样就能附上元素的连接地址,而无需额外添加html元素了)