整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

聊聊 CSS 隐藏元素的 10 种实用方法

聊聊 CSS 隐藏元素的 10 种实用方法

SS 隐藏元素的方法你能说出来几种?

这是一个在 web 前端面试中常会提及的基础问题,聊这个话题不仅仅只是讨论“茴”字有几种写法,更是能从一个简单的问题中体现出你的 CSS 边界能力,本文提炼了十种最实用的方法,希望对你有所帮助。

常规方法

display: none;

结构消失,会触发回流重绘Reflow & Repaint)。

opacity: 0;

结构保留,占据空间,可以正常触发事件,因触发硬件加速所以不发生回流和重绘

visibility: hidden;

结构保留,占据空间,仅触发重绘,不会触发事件(无法选中)。

content-visibility: hidden;

设置元素内容可见性,设置的元素本身不受影响。hidden 隐藏效果与 display: none 类似,但实际浏览器只是跳过了内容的渲染,还保留着内容的渲染状态,性能上有优势。

注意:该属性目前还处于实验性阶段,使用时需要考虑浏览器兼容性问题。

逃逸视窗

position+left/top

利用绝对定位 position 设置 absolutefixed,同时 lefttop 设置 -9999px

超大负边距会将元素抛出视图,因为定位本身脱离了文档流所以不占据空间。

translate(-9999px)

利用偏移抛出视图,空间会占据,不过元素实际不在视窗内所以无法交互。

transform: translate(-9999px);

注意:此方法对行内元素无效

这两种方法并不使元素本身消失,只是看不见了而已。

移行变换

scale(0) / skew(90deg)

通过2D变换来达到隐藏,占据空间,不可交互。

transform: scale(0);

transform: skew(90deg);

注意:此方法对行内元素无效

circle(0px)

利用裁剪创建元素的可显示区域,区域外会隐藏,占据空间,不可交互(这里我用 circle 是因为它参数最少)

clip-path: circle(0px);

z-index

层叠上下文在合适的情况下可以遮挡住元素,也算是一种隐藏方式。

压缩空间

height: 0; width: 0;

宽高都为 0 时不占据空间,不可交互。需要处理边距等样式,还需设置 overflow: hidden; 否则子元素可能不会隐藏,注意还会被display影响,所以这个方法本身并不实用,但是可以充分体现对盒模型的理解。

width: 0;
height: 0;
padding: 0;
margin: 0;
border: none;
overflow: hidden;

总结

或许还有其它“障眼法”可以让元素不可见,以上整理的十种方法都独具代表性,且比较实用。

以上就是文章的全部内容,感谢看到这里!本人知识水平有限,如有错误望不吝指正,如果觉得写得不错,对你有所帮助或启发,可以点赞收藏支持一下,也欢迎关注,我会更新更多实用的前端知识与技巧。我是茶无味de一天(公众号: 品味前端),希望与你共同成长~

现实中,我们时常需要在网页中展示你的联系方式,其中Email邮件地址通常需要提供在页面上。但是在网络机器人泛滥的互联中,如果直接显示你邮件,则很可能被他们识别并拷贝,然后对你的邮件地址实施邮件轰炸。为了避免这个问题,需要利用技术手段来保护你的地址,使其只能被人眼看到,并且支持直接链接发送邮件,但是不能被网络机器人识别到,一般常用的方法是通过JS,Html,CSS对地址隐藏,但是编写代码有点繁琐,可能还要引入额外的JS库才能实现,而且还有一个缺点就是对一些限制级别的设备上,浏览器可能会禁用掉JS功能,这样会导致页面不能正常工作。此处给大家介绍一种基于SVG方法的邮件地址保护技术,可以极大程度的保护你免受机器人骚扰以及保证在浏览器禁用JS情况下仍然可以正常工作。

优点

在JavaScript禁用的情况下工作

主要优点 这种基于SVG的电子邮件保护方法没有用的任何的JavaScript代码。

因此,即使访问者浏览器禁用了JavaScript,页面上显示的电子邮件地址仍然可用、可访问和受到保护,同时保持安全并免受垃圾邮件机器人的攻击。

允许标准mailto:链接

与其他不需要JavaScript的方法(例如,通过插入不可见的HTML注释或插入可见元素并随后通过CSS隐藏它们来混淆电子邮件地址)不同,这基于SVG的方法 允许标准 mailto:链接。主要区别是:mailto:链接存在于外部 SVG文档内部,而不是 内部引用的HTML文档。

像图像一样隐藏内容,像文本一样可复制

第三个优点是嵌入式SVG类似于图像,但不是图像。作为嵌入超文本文档中的替换元素,SVG可以像图像一样有效地隐藏垃圾邮件地址的电子邮件地址。

但严格来说,SVG是图形文档,而非实际图像。

因此,与图像不同,人类访问者仍然可以通过右键单击电子邮件地址来复制电子邮件地址 <text>嵌入SVG中的元素。这对于传统图像方法来说,无法多做到手动复制地址(但是可以使用图像文本识别OCR技术来实现)。

基本方法

我们以一个最简单的Emil链接地址共享为例。示例中由两个两个文件组成:其中SVG图形文档通过<object>标签方式嵌入到主HTML页面中,基本语法如下:

<object data="svg-email-protection.svg" type="image/svg+xml" /></object>。

注意,同一个SVG图形文档支持在多个地方,进行嵌入。主页面HTML(main.htm)源代码如下,一个很简单的页面:

<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>SVG Email Protection</title>
<style>
.cc {
width: 180px;
height: 24px;
vertical-align: middle;
}
</style>
</head>
<body>
<p>请邮件联系我: <object class="cc" data="svg-email-protection.svg" type="image/svg+xml"></object></p>
</body>
</html>

SVG文档(svgprot-chongchong)代码:

<svg xmlns="http://www.w3.org/2000/svg"
lang="en-GB"
aria-labelledby="title"
viewBox="0 0 200 24">
<title id="title"> SVG Email Protection</title>
<defs>
<style type="text/css"><![CDATA[
rect {
width: 200px;
height: 24px;
fill: rgb(255, 255, 255);
}
a:focus rect,
rect:hover {
rx: 4px;
ry: 4px;
fill: rgb(0, 0, 255);
}
text {
font-size: 16px;
fill: rgb(0, 0, 255);
pointer-events: none;
}
a:focus text,
rect:hover + text {
fill: rgb(255, 255, 255);
font-weight: 900;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2);
text-decoration: underline 1px solid rgb(255, 255, 255);
text-underline-offset: 5px;
}
]]></style>
</defs>
<a href="mailto:chongchong[at]ijz.me" aria-label="点击发邮件">
<rect />
<text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle"> chongchong[at]ijz.me</text>
</a>
</svg>

将以上两个文件放到同意目录,然后用浏览器打开主页面main.hm就可以看到效果了

总结

本文给大家介绍了一种基于SVG文档的优雅的邮件保护方法,可以极大的免受网络机器人窃取你的邮件地址进行骚扰攻击,同时支持emailto链接,支持无JS浏览器下正常工作,支持手动邮件复制等优点,当然该方法也是只能抵挡一般性规模化工作的Web机器人攻击,如果遇到高级机器人,比如可以模仿真人访问行为的,可以分析语法找到SVG文件进行获取地址的高级机器人则无防御能力。

览器加载一个js脚本,会在devtools中留下各种痕迹,elements中的script元素,console中的日志,source中的代码,network中的网络请求等

elements

这个比较简单,插入js的时候设置好id,在js中删掉自身就好了

<script id="xxx">
    // todo
    document.getElementById("xxx").remove();
</script>

对于引用js

<script id="xxx" src="a.js"></script>
// a.js
document.getElementById("xxx").remove()

对于动态加载的js也是一样的

<script>
    let e=document.createElement("script");
    e.id="xxx";
    e.src="a.js";
    document.head.appendChild(e);
</script>
// a.js
document.getElementById("xxx").remove()

或者也可以这样

<script>
    let e=document.createElement("script");
    e.src="a.js";
    document.head.appendChild(e);
    e.remove();
</script>

虽然看起来很奇怪,但a.js确实能执行,似乎是加载a.js时阻塞了脚本执行,执行完a.js之后再remove

console

clear就好了

console.clear()

source

直接引用和动态加载都会在source中出现

<script src="a.js"></script>
<script>
    let e=document.createElement("script");
    e.src="a.js";
    document.head.appendChild(e);
</script>

这样都是不行的,经过测试发现动态插入js代码时不会被记录在source中

<script>
    fetch("a.js").then(resp=> {
        return resp.text()
    }).then(text=> {
        let e=document.createElement("script");
        e.innerHTML=text;
        document.head.appendChild(e);
    })
</script>

这样a.js就不会出现在source里了

network

常规HTTP/WebSocket都会被记录,无法绕过,但是WebRTC不会,WebRTC可以基于UDP/TCP传输,WebRTC提供createDataChannel API,可以用于传输文本,那么就可以实现network隐藏加载

考虑WebRTC需要传递offer和icecandidate,还是得通过HTTP/WebSocket传输,而且复杂网络环境下还需要使用或部署STUN/TURN服务器,稳定性有待考虑

WebRTC技术可以参考学习我最近看的几篇文章透明日报20200801期

其他的方法我还没有找到,技术不行就社会工程

一个思路是可以伪装成其他流量混过去,比如png

<script>
    fetch("a.png").then(resp=> {
        return resp.text()
    }).then(text=> {
        let e=document.createElement("script");
        e.innerHTML=text;
        document.head.appendChild(e);
    })
</script>

然后在delvtools里也看不出来

另外一个思路是devtools目前只在打开的时候记录network数据,那么只要在devtools关闭的时候加载资源,打开就不加载,这样就不会出现在network里了

新的问题又出现了,如何检测devtools的状态,网上已经有不少公开技巧了

https://github.com/sindresorhus/devtools-detect

https://github.com/AEPKILL/devtools-detector

最后

还可以在哪里找到加载和执行痕迹呢

还有什么方法可以隐藏这些痕迹呢

如果你现在也想学习前端开发技术,在学习前端的过程当中有遇见任何关于学习方法,学习路线,学习效率等方面的问题,你都可以申请加入我的Q群:前114中6649后671还有大牛整理的一套高效率学习路线和教程与您免费分享,还有许多大厂面试真题。希望能够对你们有所帮助。