半透明背景dom的叠加样式

199 阅读2分钟

问题

主题工具系统,设置表格样式,当鼠标悬浮后会出现这样的情况.

c1c38ad23f686a3a34d4a1ab5c8c596035594b182d68e09cbb6ea5b215718899QzpcVXNlcnNcMTk3NDJcQXBwRGF0YVxSb2FtaW5nXERpbmdUYWxrXDE2MTI0NjIwNDlfdjJcSW1hZ2VGaWxlc1wxNzIwNTcwNTQzNDA5XzExN0I1ODMxLTUzNDQtNDlmNS1BRkVGLUY4RTg2NjlCRkNCQy5wbmc=.png
感觉有点熟悉,看一眼css,发现悬浮行颜色透明度是0.7.这个问题其实之前也处理过,设置Input样式的时候,原生input与外部wrapper颜色不一致,也是半透明颜色重叠导致的,不过那时比较简单,原生input背景设为transparent即可.

思路和尝试

遮盖法

在左侧单元格下方放置一个dom,它的背景颜色与表格背景相同,遮盖下方单元格.由于做的是主题工具,考虑从css着手设置其before和after,但是这两个伪元素都已经被使用了,此法不行

混色法

直接计算出原悬浮色覆盖于表格背景的最终颜色,并以之作为新的悬浮色.使用css函数color-mix混色,但最终结果仍具有透明度,会透露出下层单元格的内容.

blend-mode

查阅资料后发现,css 可以设置blend-mode控制混色结果,这可能对我有帮助.background-blend-mode仅对当前元素的背景有效,而mix-blend-mode同样无法规避透明度的影响.

解决

遮盖法无法实施,blend-mode可能性已经穷尽,我便从混色法开始思考.我意识到我需要的实际上并不是color-mix的'混色',而是'一个具有透明度的颜色覆盖于一个不透明颜色 最终呈现的颜色'.
7e04f35a7e978bcdbec4ec0fb2887150aa30749b307927634f2d3efd71da9911QzpcVXNlcnNcMTk3NDJcQXBwRGF0YVxSb2FtaW5nXERpbmdUYWxrXDE2MTI0NjIwNDlfdjJcSW1hZ2VGaWxlc1wxNzIwNTc0Mjg2Njk4X0VFM0E2NEVBLUE3OEYtNDdkMy1CNDVDLTc3RDNCNEQ2RjZCRC5wbmc=.png
问题解决了!

最终产物

函数

    // @cover覆盖于@bg上呈现出的颜色
    .cover-color(@cover, @bg) {
      @r1: red(@cover);
      @g1: green(@cover);
      @b1: blue(@cover);
      @a1: alpha(@cover);

      @r2: red(@bg);
      @g2: green(@bg);
      @b2: blue(@bg);
      @a2: 1;

      @r: round(@a1 * @r1 + (1 - @a1) * @r2);
      @g: round(@a1 * @g1 + (1 - @a1) * @g2);
      @b: round(@a1 * @b1 + (1 - @a1) * @b2);

      @res: rgb(@r, @g, @b);
    }

使用

    &:hover>td {
        background-color: .cover-color(@hover, @bg)[@res];
    }