【问题标题】:SCSS Contrast (from Compass) output different to LESS's contrastSCSS 对比度(来自 Compass)输出不同于 LESS 的对比度
【发布时间】:2017-03-09 00:39:12
【问题描述】:

尝试在 SCSS 中使用 compass 库中的 .contrast-color 函数会生成与 LESS 中的 .contrast 不同的颜色,即使LESS 中的规范另有说明。

此功能的工作方式与 Compass for SASS 中的对比功能相同。 http://lesscss.org/functions/

这是我使用 SCSS 版本的 contrast-color 和输出的 css 的示例。

SCSS gist

这是 LESS 版本。

LESS version

SCSS 中是否有like for like LESS 对比功能?如果没有,如何转换它。从源代码来看,LESS 中似乎有相当多的依赖项与工作对比。

【问题讨论】:

    标签: html css sass less


    【解决方案1】:

    原因:

    不,这两个功能不一样。在 Less 中,contrast 函数根据经过伽马校正的亮度值比较颜色。以下是Less documentation的摘录:

    根据 WCAG 2.0,颜色的比较使用的是经过伽马校正的亮度值,而不是亮度。

    而在 Sass 中,它们是 comparing the colors based on brightness of the colors。此函数给出luminance value as the output 而不是亮度值。所以他们给出了不同的输出。


    解决方案:

    虽然 Less 有一个 luma function 也可以直接获取经过 gamma 校正的亮度值,但 Sass 似乎没有任何内置函数来提供此值。因此,我们必须基于WCAG 2.0 specifications 编写自定义函数。那里提供了计算逻辑,下面是摘录:

    对于 sRGB 颜色空间,颜色的相对亮度定义为 L = 0.2126 * R + 0.7152 * G + 0.0722 * B 其中 R、G 和 B 定义为:

    如果 RsRGB

    如果 GsRGB

    如果 BsRGB

    RsRGB = R8bit/255

    GsRGB = G8bit/255

    BsRGB = B8bit/255

    我不是 Sass 专家,无法自己编写这个自定义函数,所以我从 this article by Toni Pinel 那里得到了一些帮助(好吧,几乎所有东西都没有他的 re-gamma 函数)。如果您使用下面的contrast-color 函数,它将提供与 Less 相同的输出。

    @function de-gamma($n) { @if $n <= 0.03928 { @return $n / 12.92; } @else { @return pow((($n + 0.055)/1.055),2.4); } }
    
    // sRGB BT-709 BRIGHTNESS
    @function brightness($c) {
        $rlin: de-gamma(red($c)/255);
        $glin: de-gamma(green($c)/255);
        $blin: de-gamma(blue($c)/255);
        @return (0.2126 * $rlin + 0.7152 * $glin + 0.0722 * $blin) * 100;
    }
    
    // Compares contrast of a given color to the light/dark arguments and returns whichever is most "contrasty"
    @function contrast-color($color, $dark: #000000, $light: #FFFFFF) {
        @if $color == null {
            @return null;
        }
    
        @else {
            $color-brightness: brightness($color);
            $light-text-brightness: brightness($light);
            $dark-text-brightness: brightness($dark);
    
            @return if(abs($color-brightness - $light-text-brightness) > abs($color-brightness - $dark-text-brightness), $light, $dark);
        }
    }
    

    下面是Less is using for the luma function 的代码,它与上面给出的自定义函数非常相似。此函数返回与上面给出的 Sass 自定义函数相同的输出。

    Color.prototype.luma = function () {
        var r = this.rgb[0] / 255,
            g = this.rgb[1] / 255,
            b = this.rgb[2] / 255;
    
        r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
        g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
        b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
    
        return 0.2126 * r + 0.7152 * g + 0.0722 * b;
    };
    

    注意事项:

    1. 如果我们使用luma(darken(@bg,10%)),Less 编译器会给出 23.64695145 作为输出。这与 Sass 自定义函数的输出(即 23.83975738)略有不同。但是luma(#868686)给出的输出和Sass自定义函数一样,所以我认为自定义函数没有错。

    2. 一些 SASS 编译器没有上面使用的 de-gamma 函数所需的本机 pow() 函数。出于这个原因,您可能需要包含一个库,该库具有此库或至少具有此类库中的 pow() 函数。 Sassy-Math 就是一个例子。

    【讨论】:

    • 已投票。一旦可以,我会试试这个。感谢您的回复。
    • @Euphoria:不客气。请花点时间来测试一下。我对你的颜色进行了随机检查,我从这个 Sass 自定义函数中获得的亮度值是 23.83975738,而输出 Less 的亮度函数是 23.64695145。它仍然不是完全匹配,但它应该适用于 99% 的情况。如果我们想要更接近的匹配,我们必须查看 Less 源代码,因为这个 Sass 自定义函数与 WCAG 2.0 规范是内联的。
    • 好的,结果如下。完美的功能,感谢您写得如此出色的解释,非常感谢。然而,有一个问题(不是你的错)是某些 scss 编译器没有在 de-gamma 中使用的“pow”函数。为此,您必须使用 SCSS 扩展库或至少使用 pow() SCSS 函数。我们选择了@import "sassy-math";并且在我们的项目中,暂时只接管了 POW 函数以包含在 scss 中(如果需要,以后可能会添加 sassy-math)。这可能在答案中值得注意。再次感谢您。
    • @Euphoria:啊,我以为pow 一定是一个Sass 函数。让我看看是否有任何替代方案,而无需使用额外的库。如果我找到答案会更新答案:)
    • 如果您希望编辑/保留它等,我已经为您添加了注释:)
    猜你喜欢
    • 2011-08-17
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    相关资源
    最近更新 更多