CSS:半透明之地的冒险

最近,我被要求更正一个登陆页面。我在他的代码中发现了一张图片,在该图片上放置了两个与之重叠的半透明元素。两者在属性中具有相同的RGB颜色值background-color它看起来像这样:

<img src='myImage.jpg'/>
<div class='over1'></div>
<div class='over2'></div>

不需要使用两个这样的元素。除非由于只有一个这样的元素不能充分着色图像的事实,否则可能需要这样做。由于某些原因,该页面的作者认为添加另一个叠加在图像上的半透明元素比增加opacity第一个参数的值更好 结果,我决定删除其中一层,并设置其余一层的参数,以使外部图像看起来与上一层相同。所有这些都很好,但是出现了一个问题:如何调整其余元素的参数,以使结果与应用两个半透明层时的结果相同?



opacityopacity

如果你读这个我口罩的组合物物品,那么你可能已经猜到了如何选择合适的值。毕竟,这里使用相同的公式,使用在那里将其用于半透明元素的组成mask-composite: add如果有两层的透明度值等于a0a1,则结果指标的值计算如下:

a0 + a1 - a0*a1

在这里,您可以找到一个交互式演示,可以在该演示中比较图像的外观,分为两层的色调,可以使用滑块控制opacity其(a0a1的属性以及opacity根据公式计算的layer属性进行色调的同一图像a0 + a1 — a0*a1


对图像进行着色的选项(两个副本相邻显示)。

有趣的是,如果两个半透明元素以及一个这样的元素所在的区域没有显示,则它们看起来相同(您可以使用复选框禁用图像输出)位于屏幕底部)。但是,如果在这些图层下显示图像,则其两个选项会略有不同。也许这种差异只是光学错觉的结果,也许图像的某些部分对我来说似乎比实际更亮或更暗。

如果您不将它们并排显示,它们的外观肯定不会有所不同,而只是在属性值opacity等于a0和的两层之间切换a1和一层,其值opacity可通过公式找到a0 + a1 — a0*a1这是一个相关的例子。


可以在一个和两个半透明层之间切换的图像着色选项,

此示例可以扩展到更多层。在这种情况下,首先计算新层的透明度,该透明度等于两个较低层的透明度。然后找到该图层的透明度,该透明度与新图层及其上一层的透明度相等。重复此操作,直到处理完所有图层为止。


将多个半透明层缩减为一个单层

类似的实验让我思考了如何计算不透明背景图像的参数,该参数等效于一个不透明层(c0)和叠加在其上的半透明层(c1其透明度设置为a)。在这种情况下,可以通过逐通道处理原始图像来找到单层的最终图像,而所得通道的颜色值则通过以下公式计算:

ch0 + (ch1 - ch0)*a

这里ch0是不透明下层的沟道(redgreenblue-用于红色,绿色和蓝色),ch1是上部半透明层的相应的信道,并且所述指示器a是一个指标,设定相同半透明层的透明度。

如果以SCSS代码的形式表示这些参数,则会得到以下结果:

/*       */
@function res-ch($ch0, $ch1, $a) {
  @return $ch0 + ($ch1 - $ch0)*$a
}

@function res-col($c0, $c1, $a) {
  $ch: 'red' 'green' 'blue'; /*   */
  $nc: length($ch); /*   */
  $ch-list: ();

  @for $i from 0 to $nc {
    $fn: nth($ch, $i + 1);
    $ch-list: $ch-list, 
      res-ch(call($fn, $c0), call($fn, $c1), $a);
  }

  @return RGB($ch-list)
}

这是一个交互式示例。通过对其进行试验,您可以比较这两层的外观以及它们等效的外观,以单层的形式呈现。在这里您可以选择两层的RGB颜色值以及第二层的透明度级别。


将半透明层应用于不透明层的结果

根据设备,操作系统和浏览器的不同,您将看到此示例中的颜色面板看起来相同还是不同。该公式是正确的,但是在不同环境中如何精确处理两个源图层可能会有所不同。


图像的左侧部分是将两层缩减为一层的预期结果。右侧显示了如何将两个图层组合在一起(从图像的右上方),右下方显示的图层看起来与预期的有所不同,

我要求Twitter用户使用此示例简化测试版向我发送屏幕截图。从我收到的反馈来看,无论使用什么操作系统,这两个面板在移动浏览器(Android和iOS)以及Firefox浏览器中看起来总是相同的。尽管我得到的回答表明Chrome和Chromium Edge有时呈现的面板与预期不同,但在Windows上面板几乎总是一样的。

如果我们谈论在macOS和Linux上运行的基于WebKit的浏览器,可以注意到结果是非常不同的。在大多数情况下,面板的颜色略有不同。但是使用sRGB颜色配置文件有助于使面板看起来相同。如果在使用两个监视器的系统中考虑此示例,则最有趣的事情开始。将窗口从一个监视器拖到另一个监视器可能导致以下事实:面板之间的差异是可见的还是不可见的。

应当指出,在实际情况下,差异很小,并且一对这样的面板不太可能彼此相邻。但是,即使有区别,也没有人会知道,直到他在不同的环境中测试页面为止。无论如何,只有Web开发人员才能执行此操作。另外,当使用不同的设备,操作系统和浏览器时,普通的不透明元素的颜色看起来也会有所不同。例如,#ffa800在css-tricks.com上广泛使用的颜色在装有Ubuntu和Windows的笔记本电脑上看起来就不同。但是毕竟,不同人的眼睛可以以不同的方式感知相同的颜色。

亲爱的读者们! 您是否在使用不同浏览器,操作系统或显示不同颜色网页的设备时遇到问题?


All Articles