分类
代码

任意网站注入自定义 CSS 样式

需求来源

有些网站的广告元素很容易找,想直接把它 display:none 掉,或者把某些带背景图像的元素隐藏或更换背景图片。
然后找到了一个 Chrome 插件 Stylus 也能用但感觉没有必要单独装一个插件,还很复杂的样子。
想着油猴脚本应该有很多类似的,结果搜了一下都是针对特定网站的(比如百度/B站/知乎美化),于是就自己写了这个油猴插件。

效果图

使用方式

需要先安装用户脚本管理器 Tampermonkey (即俗称的油猴插件)或者 Violentmonkey (中文名 暴力猴 ),然后点击 这里 安装脚本,点击 这里 预览脚本(见 Gist 地址 )。
对油猴脚本开发感兴趣的同学,可以参考之前的文章:如何编写一个油猴脚本

实现原理

一个 URL 正则表达式对应一条 CSS 规则,将所有规则保存起来(油猴提供了两个 API GM_getValue / GM_setValue 供存取设置内容)。
然后在每个页面加载后,遍历所有规则,找到所有对本页适用的规则,直接注入到页面中。
本着一个脚本做一件事的原则,这个脚本只提供注入 CSS 功能,而不提供注入 JS 的功能。

局限性

在浏览 GNU 的 ftp 站点 时发现规则没有生效。然后认识了一个 HTTP 响应头 Content-Security-Policy
该站点的此响应头是这样设置的:

Content-Security-Policy: default-src 'self'; img-src data: 'self' https://static.fsf.org https://gnu.org; object-src 'none'; frame-ancestors 'none'; child-src 'self' https://static.gnu.org https://static1p.gnu.org https://static1p.fsf.org;script-src 'unsafe-eval' 'self'

报错信息如下:

Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.

这个 header 对应的值是多个分号分隔的部分,指定了页面支持哪些来源的资源。
第一个 default-src 指定默认的资源来源是 self 即当前域名。
根据报错信息提示,浏览器拒绝应用注入的样式,因为内容安全策略设置的 default-src 指定了只接受同域名的样式,而没有接受行内样式 unsafe-inline ,也没有指定可执行的样式的 hash, nonce 值。
因为没有指定 style-src 所以使用的是 default-src 规则。
更多内容安全策略的相关知识,大家可以参考 MDN 文章 内容安全策略( CSP )Content-Security-Policy ,以及阮一峰的博文 Content Security Policy 入门教程

分享一些规则

找到了广告元素后,可以直接使用 display: none 将其隐藏,另外插件还注入了一个水印层, class 是 .inject-watermark ,也可以用来添加自定义水印~

body > div:empty {
  /* body 的空的子元素去除背景 */
  background: transparent !important;
}

.inject-watermark {
  /* 插件注入的元素,覆盖整个页面。可以添加自定义水印 */
  background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Ctext x='50%25' y='50%25' font-size='14' fill='%23a2a9b6' fill-opacity='0.5' font-family='system-ui, sans-serif' text-anchor='middle' dominant-baseline='middle' transform='rotate(-45 50 50)'%3Eyouthlin.com%3C/text%3E%3C/svg%3E")
}

svg 可以作为背景水印,如何将文本写在 svg 上,可以参考菜鸟教程 SVG <text> 。 从教程的 尝试一下 按钮可以进入 svg 在线编辑器。
另外再推荐张鑫旭的几篇相关文章:
如何让文字作为CSS背景图片显示?
如果想要将文字倾斜,还可以看下 svg 中如何旋转
理解SVG transform坐标变换
最后为了把 svg 放在背景上,通常可以使用 base64 编码 svg 后放在 background-image 的 url 中,
不过,还有另一种可读性更好的方式
学习了,CSS中内联SVG图片有比Base64更好的形式


“任意网站注入自定义 CSS 样式”上的1条回复

div:not([class]) > div:not([class]) > div:not([class]) > div:not([class]) > div:only-child[class^=w] {
    display: none !important;
}

可以隐藏这样的结构:

<div>
 <div>
  <div>
   <div>
    <div class="wxxx">
回复 回复时对方会收到邮件通知

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

[/鼓掌] [/难过] [/调皮] [/白眼] [/疑问] [/流泪] [/流汗] [/撇嘴] [/抠鼻] [/惊讶] [/微笑] [/得意] [/大兵] [/坏笑] [/呲牙] [/吓到] [/可爱] [/发怒] [/发呆] [/偷笑] [/亲亲]