马黑黑 发表于 2022-10-21 12:20

一帖搞懂伪元素::before和::after

本帖最后由 马黑黑 于 2022-10-21 12:58 编辑 <br /><br /><style>
#papa { width: 100%; }
#papa > p, #papa > pre { padding: 8px 0; }
.mnBox {
        width: 400px;
        height: 200px;
        border: 1px solid gray;
        position: relative;
}
.pseudo1::before {
        position: absolute;
        content: '伪元素 ::before';
        width: 150px;
        height: 50px;
        left: 10px;
        top: 10px;
        background: olive;
        color: orange;
        padding: 10px;
}

.pseudo2::after {
        position: absolute;
        content: '伪元素 ::after';
        width: 150px;
        height: 150px;
        left: 100px;
        top: 50px;
        background: teal;
        color: orange;
        padding: 10px;
}
</style>

<div id="papa">

<p>关于元素的 ::before 和 ::after 伪元素,我们接触过不少,但基本都是零零星星的,这里有必要梳理一下。</p>

<p>我们先做个简单一点的元素,然后再依次给它加上两个伪元素:</p>
<pre>
&lt;style&gt;

<span style='color: red;'>.mnBox </span>{
&nbsp; &nbsp;<span style='color: blue;'>width</span>: 400px;
&nbsp; &nbsp;<span style='color: blue;'>height</span>: 200px;
&nbsp; &nbsp;<span style='color: blue;'>border</span>: 1px solid gray;
&nbsp; &nbsp;<span style='color: blue;'>position</span>: relative;
}

<span style='color: green'>/* 这里添加伪元素代码 */</span>

&lt;/style&gt;

&lt;<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"mnBox"</span>&gt;&lt;<span style='color: darkred'>/div</span>&gt;

效果:

</pre>

<div class="mnBox"></div>

<p>这个真的简简单单,没什么要解释的,唯独要强调的是 mnBox 盒子的 position 属性,要定位,一般建议相对定位,即,position: relative;,特殊需要时也可以采用其他定位,如绝对定位(absolute)。因为只有父元素定位了,将来子元素所做的定位才会以父元素做参照,而前述两个伪元素,我们以前反复提及,它们是特殊的子元素。</p>
<p>下面我们先加入 ::before 伪元素,CSS代码放在 .mnBox {} 之后:</p>
<pre>
<span style='color: red;'>.<span style='color: blue;'>mnBox</span>:<span style='color: blue;'></span>:before </span>{
&nbsp; &nbsp;<span style='color: blue;'>position</span>: absolute;
&nbsp; &nbsp;<span style='color: blue;'>content</span>: <span style='color: magenta'>'伪元素 <span style='color: blue;'></span>:<span style='color: blue;'></span>:before'</span>;
&nbsp; &nbsp;<span style='color: blue;'>width</span>: 150px;
&nbsp; &nbsp;<span style='color: blue;'>height</span>: 50px;
&nbsp; &nbsp;<span style='color: blue;'>left</span>: 10px;
&nbsp; &nbsp;<span style='color: blue;'>top</span>: 10px;
&nbsp; &nbsp;<span style='color: blue;'>background</span>: olive;
&nbsp; &nbsp;<span style='color: blue;'>color</span>: orange;
&nbsp; &nbsp;<span style='color: blue;'>padding</span>: 10px;
}
</pre>

<p>绝对定位(position: absolute;)是强烈建议的,这么做,配合父元素的 relative 定位,伪元素就会以父元素为自己的定位参照,不至于找不着北;content 属性是必须的,否则伪元素渲染不出来,其值可以为空字串、实字串,也可以是相关变量(我们后面会简单谈到 attr 变量)。其他方面,从代码中可以看到,和元素的属性设置没有区别,拥有常规元素的一切属性,可以设置尺寸、物理位置、内边距、前景色和背景色等等。</p>
<p>html代码无需改变,效果就出来了:</p>

<div class="mnBox pseudo1"></div>

<p>加 ::after 伪元素道理同 ::before,下面的代码加在 CSS 里面,习惯上放在 *::before {} 之后:</p>
<pre>
<span style='color: red;'>.<span style='color: blue;'>mnBox</span>:<span style='color: blue;'></span>:after </span>{
   <span style='color: blue;'>position</span>: absolute;
   <span style='color: blue;'>content</span>: <span style='color: magenta'>'伪元素 <span style='color: blue;'></span>:<span style='color: blue;'></span>:after'</span>;
   <span style='color: blue;'>width</span>: 150px;
   <span style='color: blue;'>height</span>: 150px;
   <span style='color: blue;'>left</span>: 100px;
   <span style='color: blue;'>top</span>: 50px;
   <span style='color: blue;'>background</span>: teal;
   <span style='color: blue;'>color</span>: orange;
   <span style='color: blue;'>padding</span>: 10px;
}

效果:

</pre>

<div class="mnBox pseudo1 pseudo2"></div>

<p><br>上面效果,我们看到,伪元素 ::after 的盒子溢出了父盒子。这是正常现象:伪元素隶属于父元素,但它可以拥有自己的尺寸和位置,其物理位置和尺寸最终导致它身居何处,但这一切,由于有了父子关系的 position 配套定位的约束,我们在设计的时候就都可以预见得到,因为,在我们营造的环境里,伪元素的定位总是以父元素为参照,参照点是父元素的左上角的 xy坐标 {0,0}。同时,请观察一下 ::before 和 ::after 的层级关系:后者总是后来者居上(不论CSS代码中两个伪元素谁先谁后)。</p>
<p>请特别注意:伪元素必须使用 content 属性,单词是“内容”之意,它用来表明伪元素的内容,如我们前例伪元素显示的文本(不需要伪元素文本的,请用空字串表示,即 '')。伪元素要显示的文本,可以在 CSS 里设定,也可以在 HTML 代码中指定,这时,CSS伪元素代码中,需要使用 attr 变量:</p>
<p><span style='color: blue;'>content</span>: attr(data-mytext);</p>
<p>data- 是规定好的标准前缀,使用其他的字串替代 data 在一些编辑器中会被警告,但浏览器会支持。data- 之后紧跟着自定义的字串,可以是语义化的。然后,在HTML主元素代码中设定待输出内容:</p>
<p>&lt;<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"mnBox"</span> data-mytext="我是伪元素"&gt;&lt;<span style='color: darkred'>/div</span>&gt;</p>
<p>还可以通过JS读取和写入 attr 数据:</p>
<pre>
&lt;script&gt;

<span style='color: blue'>let</span> ele = <span style='color: red'>document</span>.querySelector(<span style='color: magenta'>'.mnBox'</span>); <span style='color: green'>//获得 mnBox 操作句柄</span>
<span style='color: blue'>let</span> dataStr = ele.dataset.mytext; <span style='color: green'>//读取伪元素内的文本</span>
console.log(dataStr); <span style='color: green'>//控制台显示读取内容</span>
ele.dataset.mytext = <span style='color: magenta'>'我的文本修改了'</span>; <span style='color: green'>//修改伪元素文本内容</span>
dataStr = ele.dataset.mytext; <span style='color: green'>//再次读取伪元素内的文本</span>
console.log(dataStr); <span style='color: green'>//控制台显示新读取内容</span>

&lt;/script&gt;
</pre>
<p>dataset方法正是我们做模拟逐字同步歌词显示模块所用到的,虽然大家可能不怎么留意到该模块中JS的实现细节。</p>
<p>关于伪元素的一些扩展知识:</p>
<p>① 不是所有的HTML容器(元素)都拥有伪元素,一般说来,绝大多数双标签的容器都有伪元素,但也有例外,如 iframe 就没有伪元素;绝大多数的单标签容器没有伪元素,img 是个例外。</p>
<p>② 伪元素首先是假的,假在,常规方法在 DOM 树里面遍历不到它;同时它又是真真切切的元素,我们从上面的演示中可以感知到他的真实存在。总而言之,伪元素是一个伪造的元素,它真实存在但在 DOM 树种遍历不到它。</p>
<p>③ 伪元素和伪类的主要区别:概念和功能上,伪元素是对其所寄生的主元素的伪造,而伪类不伪造元素,而是用于制定主元素的特殊效果,亦即赋予元素一个自身不能制定的样式(如鼠标悬停在元素上面是改变文本颜色);写法上,CSS3规定,伪类有一个小角冒号引导(:hover),伪元素用的引导符号是一对小角冒号(::first-letter)。</p>
<p>④ 其他伪元素:CSS中常用到的共有四个伪元素,除了业已介绍的 ::before 和 ::after,还有:</p>
<pre>
        ::first-letter - 首字母相关
        ::first-line - 首行相关
</pre>

</div>

起个网名好难 发表于 2022-10-21 12:27

前排听讲{:5_106:}

马黑黑 发表于 2022-10-21 12:31

起个网名好难 发表于 2022-10-21 12:27
前排听讲

这个,俺多不好意思,你是实实在在的高手,来批评指导差不多{:5_106:}

起个网名好难 发表于 2022-10-21 12:46

马黑黑 发表于 2022-10-21 12:31
这个,俺多不好意思,你是实实在在的高手,来批评指导差不多

哪敢啊,每天来转转不就为了学点新东西吗。

马黑黑 发表于 2022-10-21 12:48

起个网名好难 发表于 2022-10-21 12:46
哪敢啊,每天来转转不就为了学点新东西吗。

学无止境,希望多指点

起个网名好难 发表于 2022-10-21 12:51

马黑黑 发表于 2022-10-21 12:48
学无止境,希望多指点

确实是学无止境,但指点是万万不敢的。

马黑黑 发表于 2022-10-21 12:53

起个网名好难 发表于 2022-10-21 12:51
确实是学无止境,但指点是万万不敢的。

牵须了不是

起个网名好难 发表于 2022-10-21 13:19

马黑黑 发表于 2022-10-21 12:53
牵须了不是

须不够长啊{:5_106:}

起个网名好难 发表于 2022-10-21 13:49

本帖最后由 起个网名好难 于 2022-10-21 19:16 编辑 <br /><br />真正的“前”和“后”<br>
<style>

.mnTxt {
   border: 1px solid gray;
   font-size:4em;
}

/* 这里添加伪元素代码 */
.mnTxt::before {
   content: '\260E :';
   background: olive;
   color: orange;
   font-size:0.5em;
}
.mnTxt::after {
   content: ' : \2709';
   background: teal;
   color: orange;
   font-size:0.5em;
}</style>

<span class="mnTxt">860188669999</span>

马黑黑 发表于 2022-10-21 18:11

起个网名好难 发表于 2022-10-21 13:19
须不够长啊

扯扯能长

起个网名好难 发表于 2022-10-21 18:16

本帖最后由 起个网名好难 于 2022-10-21 18:18 编辑

马黑黑 发表于 2022-10-21 18:11
扯扯能长
无处抓手{:5_106:}所以不牵须

小辣椒 发表于 2022-10-21 18:46

这个就是以前加的效果,发帖后跑帖子外面了,有了绝对地址可以控制在自己运行的空间内

马黑黑 发表于 2022-10-21 18:57

小辣椒 发表于 2022-10-21 18:46
这个就是以前加的效果,发帖后跑帖子外面了,有了绝对地址可以控制在自己运行的空间内

父子元素,父要定位,子也要定位。一般的配套是父相对(relative)、子绝对(absolute)。

马黑黑 发表于 2022-10-21 18:59

起个网名好难 发表于 2022-10-21 18:16
无处抓手所以不牵须

额,都刮光了

红影 发表于 2022-10-23 20:01

来学习了,最后面提到的两个首字母和首行的,倒是从来没见到过呢{:4_187:}

马黑黑 发表于 2022-10-23 20:30

红影 发表于 2022-10-23 20:01
来学习了,最后面提到的两个首字母和首行的,倒是从来没见到过呢

也不常用,报纸类可以用用

红影 发表于 2022-10-24 17:00

马黑黑 发表于 2022-10-23 20:30
也不常用,报纸类可以用用

哦哦,不常用的就不理了,常用的还学不会呢{:4_173:}

马黑黑 发表于 2022-10-24 17:44

红影 发表于 2022-10-24 17:00
哦哦,不常用的就不理了,常用的还学不会呢

需要用时,查查资料就好

红影 发表于 2022-10-24 21:09

马黑黑 发表于 2022-10-24 17:44
需要用时,查查资料就好

一点不会的东东查资料都没用{:4_173:}

马黑黑 发表于 2022-10-24 22:18

红影 发表于 2022-10-24 21:09
一点不会的东东查资料都没用

查了就会的
页: [1] 2 3
查看完整版本: 一帖搞懂伪元素::before和::after