浅谈css的伪元素::after和::before

css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁。但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何使用他们?什么时候应该使用他们?笔者总结了一些对伪元素的理解和使用经验。

一、概念:

1.定义

The CSS ::before(::after) pseudo-element matches a virtual first(last) child of the selected element. It is typically used to add cosmetic content to an element by using the content CSS property. This element is inline by default.

从定义我们知道::before和::after匹配一个虚拟元素,主要被用于为当前元素增加装饰性内容的。他显示的内容是其自身的“content”属性,默认是内联元素。

其实::after和::before被引入css中,最核心的目的,还是为了实现语义化。在我们实际开发时候经常有这样的经历,为了实现一些效果,在文档中创建了一些没有实际内容的节点,或者加入辅助样式的文本,如:

<style>
    ul{
        list-style: none;
    }
    li{
        display: inline;
    }
</style>
<nav>
    <ul>
        <li>HTML 5</li>
        <li>|</li>
        <li>CSS3</li>
        <li>|</li>
        <li>JavaScript</li>
    </ul>
</nav>

显示的时候是这样子的:

很明显,例子中的“|”仅是显示时候用的间隔符,没有实际的意义,而他所在的li元素仅是为了装饰才被创建的,本是不应该被创建在文档内的。那么能不能由样式(css)去创建出节点把他们代替掉呢?

出于这样的需求,就诞生了::after和::before,这两个伪元素相当于是对当前元素的装潢,他们并不是节点,不会出现在dom树中,但是在显示上具备节点的效果。我们使用::after和::before重构一下上边的代码:

<style>
    ul{
        list-style: none;
    }
    li{
        display: inline;
    }
    li:not(:last-child)::after{
        content: "|";
    }
</style>
<nav>
    <ul>
        <li>HTML 5</li>
        <li>CSS3</li>
        <li>JavaScript</li>
    </ul>
</nav>

显示效果没有变化,但是文档结构变得清晰了多了。

2.使用

::after和::before的使用很简单,可以认为其所在元素上存在一前一后的两个的元素,这两个元素默认是内联元素,但我们可以为其增添样式。::after和::before使用的时候一定要注意,必须设置content,否则这两个伪元素是无法显示出来的。而content属性,会作为这两个伪元素的内容嵌入他们中。如:

<style>
    p:before{
        content: "H";
    p:after{
        content: "d";
    }
  </style>
  <p>ello Worl</p>

显示为完整的Hello World。

::after和::before是虚拟元素,不会影响真正元素的所在文档的位置,对:first-child或者:last-child这种伪类选择不会造成影响。

3.操作

::after和::before是虚拟节点,而不是正在的节点,不在documont里面找到对应Node对象,在之前的例子中,我们执行下列js代码:

console.log( document.querySelector("ul").childNodes);

得到的是一个只有3个节点的NodeList对象,而两个伪元素并不在对象中。因为::after和::before不是真正的节点,所以我们取不到他们,也不发设置点击等用户事件。::after和::before虽然是不能设置事件,但还会捕获用户事件,并把事件“冒泡”到伪元素所在的元素上。之所以“冒泡”二字加了引号,是因为他不是真的冒泡,更准确的说::after和::before帮所在元素去捕获去事件,事件的srcElement对象是伪元素所在的元素,而不是伪元素本身。

document不能获取到::after和::before所对应的节点对象,但是可以通过css的接口获取其样式属性,如:

window.getComputedStyle(
    document.querySelector(‘li‘), ‘:before‘
)

返回是个CSSStyleDeclaration对象,可以获取当前的style值。

二、分享一些::after和::before使用的经验

以下例子多数是在特定平台上使用过的,未做兼容处理,建议在chrome下浏览

1.间隔符用法

如文章最开始的例子,使用::after伪元素做间隔符,并使用伪类:not排除掉最后一个元素。

例子

2.做border三角图标

很多开发者都用过border做的三角图标,本身三角符号就不属于文档,使用伪元素做三角符最合适了。

例子

3.字符图标

最近笔者在开发微信小程序,因为微信小程序不支持svg和背景图,于是笔者大量使用字符图标,感觉字符图标非常方便,就是受设备系统字体库限制。

例子

4.webfont的图标

现在webfont图标的最佳实践就是使用i标签和::after或者::before,实现这种图标最佳实践的工具非常多,比如http://fontello.com/,从这个网站我们可以下载svg的图标库。这种例子太多了,这里就不再列举。

5.做单位、标签、表单必填标准

笔者一直认为表单输入框的必填标记(往往是红色的“*”字符),不应该放到文档当中,使用::before可以很优雅地解决这个问题(其实就是字符图标的进一步应用)。

对于单位和前(后)置标签,也可以这样做。但是多数情况下不推荐这种做法,因为单位和标签应该是文档的一部分。

例子

6.做一些效果

可以参考《理解伪元素 :before 和 :after》这篇文章的效果,笔者曾经在实际项目中使用过“迷人的阴影”效果,也曾在微场景开发中实现过一些类似的动画。

例子

7.实现一些标签对placeholder的支持

只有几个标签支持placeholder,而且如<input type=‘date‘ />虽然是input但是也不支持。使用::before可以让一部分标签也实现对placeholder属性的支持。

例子

8.实现文字图片居中对齐

优雅地实现张鑫旭老师的inline-box居中方法,使用一个高度为100%的::before将自身的对齐线移动到自己的中线,这样里面的所有内联元素都居中对齐了。

例子

9.清除浮动

这个很常用,bootstrap的clearfix类就是使用这个方法。

例子

10.使用pointer-events消除伪元素事件

之前提到过,伪元素::after和::before会替所在元素捕获用户事件,有时候这并非我们想要的,因为这样会影响被::after和::before覆盖的子节点或者兄弟节点捕获用户事件,使用pointer-events可以消除这种问题。

例子

简单就分享这么多,总之使用伪元素的核心是更利于语义化,这是我们活用::after和::before的前提,否则就是胡乱使用了。总体可以分为四种用法:

1.用css创建装饰性元素

2.用css创建用于布局的元素,实现特殊布局的特殊需要

3.做显示图标的实现手段

4.配合attr显示属性值

参考:

http://www.webhek.com/pseudo-element/

http://www.cnblogs.com/ys-ys/p/5092760.html

https://developer.mozilla.org/en-US/docs/Web/CSS/::after

时间: 2024-10-20 23:10:54

浅谈css的伪元素::after和::before的相关文章

浅谈CSS的伪类与伪元素

本文向大家展示了CSS的伪类与伪元素,介绍的非常全面,这里推荐给大家参考下. 伪类 伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,而不是元素的id.class.属性等静态的标志.由于状态是动态变化的,所以一个元素达到一个特定状态时,它可能得到一个伪类的样式:当状态改变时,它又会失去这个样式.由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类. 伪类选择器:CSS中已经定义好的选择器,不能随便取名 :link 伪类将应用于未被访问过的链接,与:v

浅谈css中一个元素如何在其父元素居中显示

css如何垂直居中一个元素的问题已经是一个老生常谈的问题了.不管对于一个新手或者老手,在面试过程中是经常被问到的.前两天在看一个flex的视频教程,当中提到了有关元素的居中问题,所以今天小编就来扒一扒几种常见的方式.不足之处请大家批评指正(所有的代码都是自己亲手敲过可用的) 1.水平居中(margin:0 auto;) 关于这个,大家应该是最不陌生的,不管是在培训班还是自己自学的话 .这个应该是老师讲的第一个方法了(水平方向上),但是其有一个前提,就是被包裹的元素不能有浮动的属性.否则的话这个属

浅谈CSS优先级机制(一)

初次写随笔,如果有哪个地方不足还望大神指点改正,下面我来谈谈我对于CSS优先级的了解吧. CSS优先级,通俗的理解就是你给元素等一堆属性描述,然后最后到底是哪个描述作为最终显示的效果的规则或机制(个人理解).以下我将分为几个点来谈谈优先级的确定. 1.引入方式: CSS引入的方式,我目前只知道四种:内联式.内嵌式.导入式.链接式(当然网上的说法名称不一,理解就好). 各种引入方式的用法我在这里就不再多说了.以上我所按顺序罗列的四个方式是理论上的优先级顺序,也就是说,我使用内联式引入的css代码作

转:浅谈CSS在前端优化中一些值得注意的关键点

前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加载时间,但其实性能不仅仅是指加载时间,还包括浏览器性能.网络性能.开发效率.在Web前端开发中,性能是一个非常重要的需要考虑的点.本文将介绍一些开发原则和性能准则,这些都是提高Web前端性能的基础. 1. 开发原则 1.1 编写符合当代浏览器性能的代码如果想提高前端性能,就必须理解浏览器的工作原理,

浅谈CSS盒子模型

[摘要]盒子模型是CSS中的一个重要概念,虽然CSS中没有盒子这个单独的属性对象,但它却是CSS中无处不在的一个重要组成部分.掌握盒子模型的原理和使用方法可以极大地丰富HTML元素的表现效果,同时对于整个HTML文档的布局也会产生很大的帮助和促进.本文尝试在介绍CSS盒子模型基本概念和组成元素属性的基础上,结合个人学习经验对其在网页制作中的实际应用谈一谈自己浅显的观点和看法.[关键词]盒子模型:表现效果:网页布局: CSS是Cascading Style Sheets的缩写,中文意思是层叠样式表

【转】浅谈 CSS 清除浮动的 6 种方法

转载:浅谈 CSS 清除浮动的 6 种方法 在开发网页的时候经常需要用到各种浮动,此时便需要及时的清除浮动,否则将会导致布局出现问题 引出问题: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .outer{ border: 1px solid black;

[CSS]利用伪元素实现一些特殊图形

给定的html代码是: <div class='square'></div> 平常实现我们常是通过添加小的icon来实现,不仅需要添加图片资源,还需要改动html结构. CSS伪元素 css中伪元素有四个,分别是:first-line,:first-letter,:before,:after.其中前两个分别选择的是目标元素内第一行文本和第一个字母,可以为其添加多余样式. 而最常用的就是:before和:after,这两个伪元素与前两个的用法不同,而用处也更大. :before,:a

[CSS]利用伪元素实现一些特殊图形 from baidu校招

最近在博客园看到某人发的baidu校招题目,说是要用一行html代码实现下面的这个图形: 给定的html代码是: <div class='square'></div> -----------------------以上为背景------------------------------ 正方形当然很好做,但是右侧突出来的小角标就得自己想办法了.所以,既然没有到有,自然是用上了CSS中的伪元素. 这个形状跟我们平时经常遇到的小气泡和下拉栏差不多 平常实现我们常是通过添加小的icon来实

HTML和CSS设置动态导航以及CSS中伪元素的简单说明

HTML页面代码: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test</title> 5 <meta charset="utf-8"> 6 <link rel="stylesheet" type="text/css" href="style.css"> 7 <script type=&qu