Chrome 设置后略微改变 RGBA 颜色的 alpha 值
Chrome slightly changes alpha-value of RGBA color after setting it
请考虑以下代码段:
var el = document.getElementById('x');
el.style.backgroundColor = "rgba(124, 181, 236, 0.25)";
alert(el.style.backgroundColor);
<div id="x">Testing</div>
在 Windows 8.1 上,这会在 IE 11 和 Firefox 37 中返回 backgroundColor
的确切输入,但在 Chrome 43 中它会更改 alpha 值,并且警报显示:
rgba(124, 181, 236, 0.247059)
请注意,alpha 值意外地 returns 0.247059
而不是 0.25
。
我已经完成 the background-color
spec as well as the rgba spec and more specifically the bit about alpha values,但无法确定这是一个错误还是 UA(在本例中 Chrome)是否允许这样做。
是否有任何相关规范解释了 Chrome 的行为是否是 "allowed"?作为奖励,谁能解释一下 为什么 Chrome 会巧妙地改变 alpha 值?
脚注:检查它是否是 "setter" (el.style.backgroundColor = ...
) 的罪魁祸首我还尝试在 DOM 本身内的元素上声明样式。这将产生相同的(意外的)结果。请参阅此片段:
document.addEventListener("DOMContentLoaded", function(event) {
var el = document.getElementById('x');
alert(el.style.backgroundColor);
});
<div id="x" style="background-color: rgba(124, 181, 236, 0.25);">Testing</div>
It's a known issue of Chrome, for quite a long time...
这是由于 Chrome 如何计算 计算样式 alpha 值。
例如,您输入的 alpha 值是 0.25
。
- Chrome先将其转化为8bit级别,
0.25 * 255 = 63.75
.
- 奇怪的是,这个数字被截断为整数,
63
。
- 然后,Chrome使用整数返回CSS3颜色符号,
63/255 = 0.24705882352941178
,大约 0.247059
.
不仅用JS设置颜色会出现,CSS也会出现。例如:
<style>
div { color: rgba(100, 100, 100, 0.3) }
<style>
<div></div>
<script>
document.querySelector('div').style.color // rgba(100, 100, 100, 0.298039)
</script>
认为 RGBA 是用 32 位表示的。这意味着实际上没有 8 位 alpha 的精确 0.25 这样的东西。因此 0.247059 是实际正确的外推值。那么 Chrome 错了吗?或者它实际上是正确的吗?而其他浏览器给你一个无效的数字,它不是页面上呈现的内容的真实真实表示?
然后您可以争辩说 W3C 标准并不完全正确,它应该只允许使用 8 位 Alpha 完全设计的值。但这只是一个建议,而不是法律。 .
下面是 Chromium 自定义 webkit color.cpp 代码的精简版本,看起来可以进行颜色转换。但我不是铬专家
http://www.chromium.org/developers/how-tos/getting-around-the-chrome-source-code
#include <iostream>
using namespace std;
typedef unsigned RGBA32;
int colorFloatToRGBAByte(float f)
{
return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
}
RGBA32 makeRGBA32FromFloats(float r, float g, float b, float a)
{
cout << "Alpha: " << a;
return colorFloatToRGBAByte(a) << 24 | colorFloatToRGBAByte(r) << 16 | colorFloatToRGBAByte(g) << 8 | colorFloatToRGBAByte(b);
}
int main()
{
RGBA32 t;
t = makeRGBA32FromFloats (255.0f, 255.0f, 255.0f, 0.25f);
cout << static_cast<unsigned>(t) << std::endl;
return 0;
}
请考虑以下代码段:
var el = document.getElementById('x');
el.style.backgroundColor = "rgba(124, 181, 236, 0.25)";
alert(el.style.backgroundColor);
<div id="x">Testing</div>
在 Windows 8.1 上,这会在 IE 11 和 Firefox 37 中返回 backgroundColor
的确切输入,但在 Chrome 43 中它会更改 alpha 值,并且警报显示:
rgba(124, 181, 236, 0.247059)
请注意,alpha 值意外地 returns 0.247059
而不是 0.25
。
我已经完成 the background-color
spec as well as the rgba spec and more specifically the bit about alpha values,但无法确定这是一个错误还是 UA(在本例中 Chrome)是否允许这样做。
是否有任何相关规范解释了 Chrome 的行为是否是 "allowed"?作为奖励,谁能解释一下 为什么 Chrome 会巧妙地改变 alpha 值?
脚注:检查它是否是 "setter" (el.style.backgroundColor = ...
) 的罪魁祸首我还尝试在 DOM 本身内的元素上声明样式。这将产生相同的(意外的)结果。请参阅此片段:
document.addEventListener("DOMContentLoaded", function(event) {
var el = document.getElementById('x');
alert(el.style.backgroundColor);
});
<div id="x" style="background-color: rgba(124, 181, 236, 0.25);">Testing</div>
It's a known issue of Chrome, for quite a long time...
这是由于 Chrome 如何计算 计算样式 alpha 值。
例如,您输入的 alpha 值是 0.25
。
- Chrome先将其转化为8bit级别,
0.25 * 255 = 63.75
. - 奇怪的是,这个数字被截断为整数,
63
。 - 然后,Chrome使用整数返回CSS3颜色符号,
63/255 = 0.24705882352941178
,大约0.247059
.
不仅用JS设置颜色会出现,CSS也会出现。例如:
<style>
div { color: rgba(100, 100, 100, 0.3) }
<style>
<div></div>
<script>
document.querySelector('div').style.color // rgba(100, 100, 100, 0.298039)
</script>
认为 RGBA 是用 32 位表示的。这意味着实际上没有 8 位 alpha 的精确 0.25 这样的东西。因此 0.247059 是实际正确的外推值。那么 Chrome 错了吗?或者它实际上是正确的吗?而其他浏览器给你一个无效的数字,它不是页面上呈现的内容的真实真实表示?
然后您可以争辩说 W3C 标准并不完全正确,它应该只允许使用 8 位 Alpha 完全设计的值。但这只是一个建议,而不是法律。 .
下面是 Chromium 自定义 webkit color.cpp 代码的精简版本,看起来可以进行颜色转换。但我不是铬专家 http://www.chromium.org/developers/how-tos/getting-around-the-chrome-source-code
#include <iostream>
using namespace std;
typedef unsigned RGBA32;
int colorFloatToRGBAByte(float f)
{
return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
}
RGBA32 makeRGBA32FromFloats(float r, float g, float b, float a)
{
cout << "Alpha: " << a;
return colorFloatToRGBAByte(a) << 24 | colorFloatToRGBAByte(r) << 16 | colorFloatToRGBAByte(g) << 8 | colorFloatToRGBAByte(b);
}
int main()
{
RGBA32 t;
t = makeRGBA32FromFloats (255.0f, 255.0f, 255.0f, 0.25f);
cout << static_cast<unsigned>(t) << std::endl;
return 0;
}