一帖搞懂伪元素::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>
<style>
<span style='color: red;'>.mnBox </span>{
<span style='color: blue;'>width</span>: 400px;
<span style='color: blue;'>height</span>: 200px;
<span style='color: blue;'>border</span>: 1px solid gray;
<span style='color: blue;'>position</span>: relative;
}
<span style='color: green'>/* 这里添加伪元素代码 */</span>
</style>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"mnBox"</span>><<span style='color: darkred'>/div</span>>
效果:
</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>{
<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>:before'</span>;
<span style='color: blue;'>width</span>: 150px;
<span style='color: blue;'>height</span>: 50px;
<span style='color: blue;'>left</span>: 10px;
<span style='color: blue;'>top</span>: 10px;
<span style='color: blue;'>background</span>: olive;
<span style='color: blue;'>color</span>: orange;
<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><<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="我是伪元素"><<span style='color: darkred'>/div</span>></p>
<p>还可以通过JS读取和写入 attr 数据:</p>
<pre>
<script>
<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>
</script>
</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> 前排听讲{:5_106:} 起个网名好难 发表于 2022-10-21 12:27
前排听讲
这个,俺多不好意思,你是实实在在的高手,来批评指导差不多{:5_106:} 马黑黑 发表于 2022-10-21 12:31
这个,俺多不好意思,你是实实在在的高手,来批评指导差不多
哪敢啊,每天来转转不就为了学点新东西吗。 起个网名好难 发表于 2022-10-21 12:46
哪敢啊,每天来转转不就为了学点新东西吗。
学无止境,希望多指点 马黑黑 发表于 2022-10-21 12:48
学无止境,希望多指点
确实是学无止境,但指点是万万不敢的。 起个网名好难 发表于 2022-10-21 12:51
确实是学无止境,但指点是万万不敢的。
牵须了不是 马黑黑 发表于 2022-10-21 12:53
牵须了不是
须不够长啊{:5_106:} 本帖最后由 起个网名好难 于 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 13:19
须不够长啊
扯扯能长 本帖最后由 起个网名好难 于 2022-10-21 18:18 编辑
马黑黑 发表于 2022-10-21 18:11
扯扯能长
无处抓手{:5_106:}所以不牵须 这个就是以前加的效果,发帖后跑帖子外面了,有了绝对地址可以控制在自己运行的空间内 小辣椒 发表于 2022-10-21 18:46
这个就是以前加的效果,发帖后跑帖子外面了,有了绝对地址可以控制在自己运行的空间内
父子元素,父要定位,子也要定位。一般的配套是父相对(relative)、子绝对(absolute)。 起个网名好难 发表于 2022-10-21 18:16
无处抓手所以不牵须
额,都刮光了 来学习了,最后面提到的两个首字母和首行的,倒是从来没见到过呢{:4_187:} 红影 发表于 2022-10-23 20:01
来学习了,最后面提到的两个首字母和首行的,倒是从来没见到过呢
也不常用,报纸类可以用用 马黑黑 发表于 2022-10-23 20:30
也不常用,报纸类可以用用
哦哦,不常用的就不理了,常用的还学不会呢{:4_173:} 红影 发表于 2022-10-24 17:00
哦哦,不常用的就不理了,常用的还学不会呢
需要用时,查查资料就好 马黑黑 发表于 2022-10-24 17:44
需要用时,查查资料就好
一点不会的东东查资料都没用{:4_173:} 红影 发表于 2022-10-24 21:09
一点不会的东东查资料都没用
查了就会的