rgba(0,0,0,0) 和透明有啥区别?

Posted

技术标签:

【中文标题】rgba(0,0,0,0) 和透明有啥区别?【英文标题】:What's the difference between rgba(0,0,0,0) and transparent?rgba(0,0,0,0) 和透明有什么区别? 【发布时间】:2015-12-05 09:37:47 【问题描述】:

在 one of my other questions 中,解决渲染问题的解决方案是使用值rgba(255, 255, 255, 255) 而不是transparent. 我们使用rgba(0, 0, 0, 0) 进行测试,这仍然纠正了问题,这意味着它是@987654334 的定义@ 导致错误。但是,查看transparent 的W3C CSS3 Specification(和MDN reference)会发现rgba(0, 0, 0, 0)transparent 应该相等:

透明

完全透明。这个关键字可以被认为是 透明黑色的简写,rgba(0,0,0,0),它是计算出来的 价值。

那是什么?为什么两个看似相同的值会产生不同的结果?我查看了 RGBA 的the formatting,并寻找了类似的问题(无济于事)。每个提到从transparentrgba(0,0,0,0) 的转换的问题/答案总是包含“应该”或“根据”字样。(例如here)。实际的区别是什么,为什么它会改变输出这么多?

注意:这发生在大多数(如果不是全部)Internet Explorer 版本中。我们也知道它发生在某些版本的 Firefox 中。然而 Chrome 和 Safari 并没有显示这种行为,这让我们相信 -webkit 中有某种补丁。


为了能够将此作为错误提交,我们需要使用最少的代码重现问题。所以,从我的另一个问题转移过来,这里是使用 transparentrgba(0,0,0,0) 的比较,以及当我们同时使用两者时会发生什么。

透明

@keyframes spin
	0% transform:rotateZ(0deg);
	50% transform:rotateZ(360deg);border-radius:60%;
	100%transform:rotateZ(720deg);

.spinme
	display:inline-block;
	position:relative;
	left:0;
	top:0;
	margin:0.2rem;
	width:0.8rem;
	height:0.8rem;
	border:0.2rem solid black;
	border-radius:0%;
	outline: 1px solid transparent;
	transform:rotateZ(0deg);
	animation: spin infinite 4s;
<div class="spinme"></div>

RGBA(0,0,0,0)

@keyframes spin
	0% transform:rotateZ(0deg);
	50% transform:rotateZ(360deg);border-radius:60%;
	100%transform:rotateZ(720deg);

.spinme
	display:inline-block;
	position:relative;
	left:0;
	top:0;
	margin:0.2rem;
	width:0.8rem;
	height:0.8rem;
	border:0.2rem solid black;
	border-radius:0%;
	outline: 1px solid rgba(0,0,0,0);
	transform:rotateZ(0deg);
	animation: spin infinite 4s;
<div class="spinme"></div>

两者

正如@andyb 所指出的,在单独的元素上同时使用两者时会出现奇怪的行为。你会认为只有一个会摇晃,但他们都会摇晃。如图所示:

@keyframes spin
  0% transform:rotateZ(0deg);
  50% transform:rotateZ(360deg);border-radius:60%;
  100%transform:rotateZ(720deg);

.spinme
  display:inline-block;
  position:relative;
  left:0;
  top:0;
  margin:0.2rem;
  width:0.8rem;
  height:0.8rem;
  border:0.2rem solid black;
  border-radius:0%;
  outline: 1px solid rgba(0,0,0,0);
  transform:rotateZ(0deg);
  animation: spin infinite 4s;

.spinme:nth-of-type(2)
  outline: 1px solid transparent;
<div class="spinme"></div>
<div class="spinme"></div>

对于那些无法在 Internet Explorer 中测试的人,这里是问题的动画 .gif:

这是transparent在左边,rgba在中间,两者都在右边。


正如@Abhitalks 指出的那样,我误读了参考资料,但我将在问题中留下以下内容,以表明我们已经考虑过这种可能性,或者万一遗漏/忽略了某些事情。

感谢@juan-cv 的回答,我决定尝试创建一个测试来查找每个浏览器中transparent 的计算值,并得出以下结论:

$('p').text($('p').css("background-color"));
pbackground-color:transparent;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>

如果您在 Chrome/Safari 中查看此内容,那么您很可能会看到(如果您不这样做,请评论)rgba(0,0,0,0)。但是在 IE 中,您可能仍会看到transparent。我正在阅读MSDN 参考并发现:

不支持透明关键字。

这解释了为什么浏览器显示不同的结果。然而,它并没有解释他们的transparent 版本实际上被定义为什么。我查看了旧的 CSS1 和 CSS2 w3c 规范,但找不到旧的定义。 transparent 是什么意思?

【问题讨论】:

不知道任何细节:它们应该相等并不意味着它们被渲染引擎平等地处理。 transparentexisted before rgba 被引入,因此负责transparent 的代码可能在代码的另一部分,然后是处理颜色的代码。例如。可能有一个标志 transparent 用于元素和一个颜色属性,而 transparent 可能完全省略渲染,rgba(0,0,0,0) 可能仍然渲染它但透明。 我刚刚阅读了上一个问题。这里至少有一些浏览器明显存在错误行为。我建议创建一个最小的测试用例来演示问题并将其提交给受影响的浏览器供应商。 @t.niese 上面的评论听起来非常合理。 我几乎可以肯定这也是 IE11 和 Edge 中的一个错误。在 IE11 或 Edge 中查看 this quick fiddle。摇摆不定的元素似乎也会影响使用outline-color:1px solid rgba(0, 0, 0, 0) 的其他元素。它可能不仅仅是透明 vs rgba 如果您有 microsoft.com 帐户,我建议您在此处提交错误报告:connect.microsoft.com/IE Firefox (nightly 2015-09-09) 在 transparentrgba(0,0,0,0) 之间的 DOM 级别也表现出显着差异。例如,前景色不能明显地设置为零四元组——而是node.style.color='rgba(0,0,0,0)' 立即导致node.style.color==='transparent'。此外,具有零 alpha 值的 any 颜色属性将“计算”为transparent(无论是否全为零)——例如:node.style.borderLeftColor='rgba(255,255,255,0)' 导致 getComputedStyle(node).borderLeftColor === 'transparent' 【参考方案1】:

rgba() 是一个计算项目颜色和透明度的函数,当你想控制项目的颜色和透明度时,它非常有用,特别是如果你不想完全透明。作为一个函数,你是在告诉浏览器你想要绘制项目的确切颜色和透明度,这更接近于 JS 而不是 CSS。

另一方面,“透明”是一个 CSS 属性,用于标识项目将完全透明,无需计算颜色和 alpha。作为 CSS 属性而不是函数,每个浏览器都以不同的方式应用它,因此它与浏览器应用此属性所使用的方法有很大不同。

编辑 好的,你说我的回答与此相矛盾:

透明

完全透明。这个关键字可以被认为是 透明黑色,rgba(0,0,0,0),这是它的计算值。

嗯,我不反对。一件事是 W3C 标准的规范,另一件事是不同浏览器的开发人员对该标准的实现。我不会破解IE的代码来证明我在说什么,因为这有点非法,直接问微软的人看看他们的答案。

我告诉你的是,它们是不以相同方式处理透明和 rgba(0, 0, 0, 0) 的浏览器。那是因为透明属性比 rgba(0, 0, 0, 0) 函数(你比 rgba() 更喜欢那个?),而且很可能,而 IE 已经开发了一个rgba(r,g,b,a)的有效方法,他们仍然使用具有透明属性的旧方法。

您必须始终牢记的一点是,没有网页浏览器 100% 符合 W3C 标准,这就是为什么在大多数新属性中必须添加制造商的特定扩展名的原因(moz- webkit- 等)

想想为什么把同样的东西写四次这么荒谬,当一切都可以使用标准属性解决时,你自己会回答,因为使用透明和rgba(0,0, 0, 0) 在 IE 中。

【讨论】:

为什么我投了反对票??你能解释一下吗?我已经回答了“rgba(0,0,0,0) 和透明有什么区别?”这个问题,我投了反对票,至少解释一下 虽然你的答案是有效的,但我认为它对手头的问题没有多大用处,我现在将解释......首先你没有提到rgba(0,0,0,0) 一次:你描述rgba()transparent 是什么,但这无助于解决问题。您回答中的信息要么是:在我的问题中陈述,要么据我所知(这是参考资料的帮助),虚构的。除此之外,任何引用都不支持您的答案,您甚至与已引用的某些来源的某些信息相矛盾。以后请阅读整个问题:不仅仅是标题。 我阅读了完整的问题,如果你有点聪明,你可以在我的回答中找到为什么你在 IE 中的“透明”属性有问题,以及为什么 rgba(0,0,0 ,0) (或任何 rgba(R, G, B, 0) 函数,因为最后一个 0 将始终使其透明)将解决问题。有时它不需要这么多的代码,也不需要太多的词来解释一件简单的事情。所以我会为你恢复我的答案:透明和 rgba(R, G, B, 0) 会给你一个透明的项目,但不是通过相同的方法,这就是为什么你在 IE 中没有相同的结果; IE中透明的方法是s**t。 PD,我没有提到 rgba(0, 0, 0, 0) 因为我认为聪明的人会明白 rgba() 是 rgba(r, g, b, a) 的缩写功能。并且不需要为透明项目制作 rgba(0, 0, 0, 0) , rgba(255, 255, 255, 0) 也将是透明的 不客气。问题总是IE,让网页设计师的日子越来越难过,哈哈哈【参考方案2】:

我一直在尝试使用 Chrome 中值 transparent 的代码,该代码安装在运行 Windows 7 操作系统的笔记本电脑上。

我自己没有任何晃动。所以我预计这个问题是特定于某些浏览器和操作系统的,具体取决于特定浏览器和操作系统如何决定呈现您的元素。

此问题可能与您的浏览器是否使用硬件加速有关。现在,有一个技巧可以强制您的浏览器使用硬件加速:让您的浏览器认为正在对元素应用 3D 转换。

您可以通过将以下属性添加到您的元素来实现:

.fake3Dtransformation 
   -webkit-transform: translate3d(0, 0, 0);
   -moz-transform: translate3d(0, 0, 0);
   -ms-transform: translate3d(0, 0, 0);
   transform: translate3d(0, 0, 0);
  /* Other transform properties here */

虽然我不完全确定这是否会解决使用 transparent 时出现的抖动问题(因为我无法重现该问题),但理论上应用此“hack”应该始终为您提供最流畅的渲染。看看例如。 this article 了解更多信息。

因此,对于您的演示代码,您将得到以下结果:

@keyframes spin
    0% transform:rotateZ(0deg);
    50% transform:rotateZ(360deg);border-radius:60%;
    100%transform:rotateZ(720deg);

#spinme
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    display:inline-block;
    position:relative;
    left:0;
    top:0;
    margin:0.2rem;
    width:0.8rem;
    height:0.8rem;
    border:0.2rem solid black;
    border-radius:0%;
    outline: 1px solid rgba(0,0,0,0);
    animation: spin infinite 4s;


#spinme:nth-of-type(2)
    outline: 1px solid transparent;
<div id="spinme"></div>
<div id="spinme"></div>

小提琴:

https://jsfiddle.net/z2r7ypy7/4/

【讨论】:

你看不到它摇晃,因为你需要在它前面加上@-moz- 等东西才能让它适用于所有浏览器。 Chrome(显然是 Safari)正在产生预期的结果。尝试在 Internet Explorer 中测试它,我会更新我的问题,特别提到 IE :) 我没想到在这种情况下强制硬件加速这么好喊!【参考方案3】:

在我看来,两次使用相同的 id 是不好的,无论你在做什么,它都意味着作为一个标识符。 我也不觉得它们都显示动画很奇怪,因为它们都具有与 css 中的 animation 匹配的相同 ID。

#spinme
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    display:inline-block;
    position:relative;
    left:0;
    top:0;
    margin:0.2rem;
    width:0.8rem;
    height:0.8rem;
    border:0.2rem solid black;
    border-radius:0%;
    outline: 1px solid rgba(0,0,0,0);
    transform:rotateZ(0deg);



#spinme:nth-of-type(1)
    animation: spin infinite 4s;

如果你这样做,只有一个会晃动,这对我来说很有意义。 也许它不能回答您关于transparent 问题的问题,但我不确定这是否真的是问题所在。

编辑 无论我尝试哪种颜色,transparentrgba(0,0,0,0) 的任意组合都会在 Safari 上生成动画。

【讨论】:

id 属性很好,尽管将其更改为 class 后没有任何变化:问题仍然存在。这不是关于他们是否有动画,而是一个摇摆不定的事实。这主要发生在 Internet Explorer 上,尽管其他用户告诉我们它发生在某些版本的 Firefox 上,所以我没有在问题中提到 Internet Explorer。 Chrome 和 Safari 都使用webkit,因此它们产生相同的结果(没有摆动)是有道理的。我不懂你的代码,只有其中一个会动画,这会破坏重点,不是吗? Aaah 现在我的意思是你所说的摆动。我很抱歉,我不清楚,我错过了 gif 中的细节。这看起来肯定是一个 IE 错误。

以上是关于rgba(0,0,0,0) 和透明有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

透明度 rgba 和 opacity 的区别

opacity与RGBA透明的区别

rgba和opacity区别

RGBA和OPACITY的透明效果有啥不同?

rgb() 和 rgba() 不透明度有啥区别?

rgba颜色透明度写法和js 获取rgba里的值