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

发布时间 2023-09-23 23:05:11作者: jack_Meng

css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁。

但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何使用他们?什么时候应该使用他们?笔者总结了一些对伪元素的理解和使用经验。

一、概念:

1.定义

从定义我们知道::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'
)

:before和:after在css1中就有了,但是在css3中写法改为了::before 和 ::after以便于和之前做区别,用哪种方式无所谓,但是IE8只支持 :after这种写法,所以我平常多用单冒号这种主要能够实现功能有

1.用来做小三角或者小箭头之类的

具体实现代码

2.为一段儿文字添加代码块

 甚至我们能够设置鼠标hover时候的效果

3.hover时的特效

特效1

具体实现代码如下

4.清除浮动

关于浮动的原理和造成的影响,大家可以看此链接,这里只讨论用伪元素after来清除浮动的影响

 

5.分割线

 

6.css计数器

css计数器是由css维护的变量,这些变量可能根据CSS规则增加以跟踪使用次数

 

html结构

 

关于css计数器的更具体的用法如下

7.画平行四边形

我们发现,里面的字体也变倾斜了,那么如何避免呢?

在div里面嵌套一层也能完全避免

另外一种就是采用:after和:before来写了

咱们先看一下边框设置为20px宽高为0的div长什么样子

 

【出处】:https://www.cnblogs.com/yuer20180726/p/11150213.html

=======================================================================================

css中::before ::after的用法

一、介绍

::before和::after是伪元素,(css3中为了与伪类做区别,伪元素采用双冒号的写法;但因为兼容性的问题,所以现在大部分还是统一的单冒号,比如:first-line、:first-letter、:before、:after等,但新的在CSS3中引入的伪元素就不允许用单冒号的写法。)

“:before” 伪元素可以在元素的内容前面插入新内容。
“:after” 伪元素可以在元素的内容之后插入新内容。

::before或::after都必须和content属性结合使用,content不能没有,内容至少为空;伪元素的display默认为inline,可以自己改.

二、用法

1.利用content的值:
(1)content:“字符串”;

可以统一在字前面或后面加一些字符
在这里插入图片描述

p:after{~~删除线格式~~ 
		content:":";
}
	
<body>
	<p>请输入姓名</p>
	<p>请输入年龄</p>
	<p>请输入性别</p>
</body>

(2)content:url(…)

可以在字前面加一些小的图标,通过定位把位置调合适
在这里插入图片描述

p::before{
			content:url(footer3.png);
			position: relative;
			top:17px;
		}
<body>
	<p>微信</p>
</body>

(3)通过attr()属性调用当元素的属性,比如将图片alt提示文字或者链接的href地址显示出来。

attr() 函数返回选择元素的属性值。
在这里插入图片描述

a::after{
			content:"(" attr(href) ")";
		}
p:after{
			content:attr(class);
		}
<p><a href="https://wx.qq.com/">微信</a></p>
<p class="hello"></p>

2.实现三角形
在这里插入图片描述

#top-triangle{
			width:0px;
			height:0px;
			border:20px solid transparent;
			border-bottom:20px solid pink;
		}
#right-triangle{
			width:0px;
			height:0px;
			border:20px solid transparent;
			border-left:20px solid pink;
		}
#bottom-triangle{
			width:0px;
			height:0px;
			border:20px solid transparent;
			border-top:20px solid pink;
		}
#left-triangle{
			width:0px;
			height:0px;
			border:20px solid transparent;
			border-right:20px solid pink;
		}


<body>
	<div id="top-triangle"></div>
	<p></p>
	<div id="bottom-triangle"></div>
	<div id="right-triangle"></div>
	<div id="left-triangle"></div>
</body>

3.实现对话框效果:
在这里插入图片描述

		.left,.right{
			position: relative;    /*后面移动会盒子位置*/
			display: table;
			min-height: 40px;
			text-align: center;
			background-color: #9EEA6A;
			margin: 0;
			border-radius: 7px;
		}
		.left{
			left:10px;
		}
		.left::before,.right::after{
			position: absolute;
			display: inline-block;
			content: "";
			width: 0px;
			height: 0px;
			border: 8px solid transparent;
			top: 15px;		/*移到中间*/
		}
		.left::before{
			border-right-color: #9EEA6A;
			left: -16px;
		}
		.right::after{
			border-left-color: #9EEA6A;
			right: -16px;
		}
		.left p,.right p{
			padding:0px 10px;
		}
		.right{
			right:-150px;
		}

    <div class="left">
        <p>你好啊</p>
    </div>
    <div class="right">
        <p>好久不见~</p>
    </div>

4.实现箭头
在这里插入图片描述

		.box{
			position: relative;
			width: 200px;
			height: 50px;
			background-color: pink;
		}
		.box::before{
			position: absolute;
			content:"";
			width: 12px;
			height: 12px;
			border: 1px solid black;
			border-bottom-color: transparent;
			border-right-color: transparent;
			transform: translate(-50%, -50%) rotate(-45deg);
			left: 20px;
			top: 50%;
		}
<body>
	<div class="box"></div>
</body>

5.清除浮动
原理:利用:after和:before在元素内部插入两个元素块,从而达到清除浮动的效果。

.outer:after { 
		clear:both; 	/*清除浮动*/
		content:'';
		display:block; /*显示伪元素*/
		width:0;		
		height:0;		/*不占位置*/
		visibility:hidden; 	/*允许浏览器渲染它,但是不显示出来*/
}

6.画分割线:画一条分割线
在这里插入图片描述

<style>
    * {
      padding: 0;
      margin: 0;
    }
    .spliter::before, .spliter::after {
      content: '';
      display: inline-block;
      border-top: 1px solid black;
      width: 200px;
      margin: 5px;
    }
  </style>
</head>
<body>
  <p class="spliter">分割线</p>
</body>

 

【出处】:https://blog.csdn.net/ladream/article/details/104828444