纯css添加div
2021年05月13日240 次阅读1 人喜欢
技术css
所属合集
今天接到一个需求:在贴片图片的左下角加一段文字,表明“广告”二字。乍一听挺简单,后来拿到源码发现不对劲。
html
<script type='text/javascript' charset='utf-8' src='http://adv.scriot....'></script>
<div style="display: none;">
<script type="text/javascript" src="https://v1.cnzz.com/z_stat.php...."></script>
</div>
源码只有这一段。贴片广告的素材来自第一段的 script 标签,由它动态创建一个 div,里面再放图片链接。问题出在三个地方:
- div 的 class 和 id 由厂商提供,不固定。 今天是这个名字,明天换个投放可能就变了,按选择器去抓是抓不住的。
- 图片是可替换的配置项,由厂商提供。 厂商不会给你在素材上加字,改图片这条路走不通。
- 图片尺寸不固定。 只能依赖“格式相对固定、大小也是相对”这一点来定位。
既然动不了 HTML 和图片,那就只能在样式层想办法。脑筋一动,用纯 CSS 实现了:
css
body>div:first-of-type::before {
position: absolute;
bottom: 0;
left: 5px;
display: block;
content: '广告';
color: #fff;
pointer-events: none;
}
思路是:不去找那个名字不固定的 div,而是用 ::before 伪元素在它上面“贴”一个角标。content: '广告' 生成文字,bottom: 0; left: 5px 把它钉在左下角,pointer-events: none 让这个角标不拦截点击——用户点到的还是下面的广告图片,不会因为多了一层文字就点不动。
为什么选这个方案,而不是 JS?
- JS 方案要等厂商 script 执行完、div 生成后再去找节点,还要处理 class/id 变化,时序和选择器都不可靠。
- CSS 方案不依赖节点名字,只依赖“它是 body 下第一个 div、格式相对固定”这个结构假设,改动最小,也不会被厂商下一次换素材破坏(只要结构不变)。
- 标识本身就是展示层的东西,用样式层解决,职责也对得上。
注意事项(用之前先确认这两点)
body>div:first-of-type这个选择器很“赌结构”:页面里一旦在它前面多出一个 div,或者厂商改了插入位置,角标就会贴错地方。如果页面结构允许,更稳妥的做法是给贴片容器包一层自己可控的父级,再对父级用position: relative+::after,把角标的定位基准收敛到这个父级里。position: absolute的参照是最近的定位祖先。原文没有给父级加position: relative,实际效果依赖当时页面的结构,照搬到别的页面前要先验证角标有没有跑偏。- 字色
#fff是按当时的深色贴片底色选的,换成浅色素材时要同步改颜色或加半透明底,否则“广告”二字会看不清——而标识不清就失去了加它的意义。