SASS 检测颜色暗度以确定样式
Posted
技术标签:
【中文标题】SASS 检测颜色暗度以确定样式【英文标题】:SASS detect colour darkness to determine styles 【发布时间】:2022-01-21 10:34:43 【问题描述】:我正在尝试制作一个可以检测是否显示深色文本(如果传递给 buttonStyles
的颜色是浅色的)或浅色文本(用于传递深色)的 mixin。我记得有一种方法可以用 LESS 来做,我想知道是否有 SASS 方法。
考虑这个 SCSS:
$white: #fff;
$text: #393939;
$font-std: 18px;
$transition-std: 0.4s ease all;
$primary: #f8e421;
$secondary: #354052;
@mixin buttonStyles($color)
font-size: $font-std;
color: $text;
padding: 1rem 3rem;
background-color: $color;
color: $white;
transition: $transition-std;
&:hover
cursor: pointer;
background-color: lighten($color, 15%);
&:focus
background-color: lighten($color, 10%);
&:active
background-color: lighten($color, 25%);
.btnPrimary
@include buttonStyles($primary);
.btnSecondary
@include buttonStyles($secondary);
还有这个html:
<button class='btnSecondary'>secondary</button>
<button class='btnPrimary'>primary</button>
辅助按钮比主按钮更易读。我知道我可以传入第二个参数来设置文本颜色,但想知道是否有与 LESS 一样更清洁、更自动的方式? (不幸的是,我不记得它是如何使用 LESS 完成的)
现场演示:https://jsfiddle.net/3v0ckeq9/5/
谢谢
编辑:
我已经添加了这个似乎几乎可以工作的功能:
@function ligthOrDark($color)
$result: red;
@if (blackness($color) == 50) // fails with > 50 or < 50
$result: green;
@return $result;
但问题是 SASS 在尝试确定颜色是否大于 50(或小于)时会抱怨,但可以使用 ==
。我只想能够确定提供的颜色是深色还是浅色,以便应用正确的文本颜色。
看来这里应该有判断明暗的选项:https://sass-lang.com/documentation/modules/color#grayscale
欢迎使用替代解决方案。
【问题讨论】:
【参考方案1】:根据documentation、whiteness
和blackness
与HWB color model 相关。如果您可以使用 HSL 模型,则可以使用 lightness
,如下所示:
$white: #fff;
$text: #393939;
$font-std: 18px;
$transition-std: 0.4s ease all;
$primary: #f8e421;
$secondary: #354052;
@function contrastText($color)
$result: invert($color);
$lightness: lightness($result);
@if ($lightness < 50)
$result: black;
@return $result;
@mixin buttonStyles($color)
font-size: $font-std;
padding: 1rem 3rem;
background-color: $color;
color: contrastText($color);
transition: $transition-std;
&:hover
cursor: pointer;
background-color: lighten($color, 15%);
&:focus
background-color: lighten($color, 10%);
&:active
background-color: lighten($color, 25%);
.btnPrimary
@include buttonStyles($primary);
.btnSecondary
@include buttonStyles($secondary);
.btnTest
@include buttonStyles(#888);
编译后如下:jsfiddle
/* CSS compiled from SASS*/
.btnPrimary
font-size: 18px;
padding: 1rem 3rem;
background-color: #f8e421;
color: black;
transition: 0.4s ease all;
.btnPrimary:hover
cursor: pointer;
background-color: #faed6b;
.btnPrimary:focus
background-color: #faea52;
.btnPrimary:active
background-color: #fcf39d;
.btnSecondary
font-size: 18px;
padding: 1rem 3rem;
background-color: #354052;
color: #cabfad;
transition: 0.4s ease all;
.btnSecondary:hover
cursor: pointer;
background-color: #536480;
.btnSecondary:focus
background-color: #495871;
.btnSecondary:active
background-color: #697d9e;
.btnTest
font-size: 18px;
padding: 1rem 3rem;
background-color: #888;
color: black;
transition: 0.4s ease all;
.btnTest:hover
cursor: pointer;
background-color: #aeaeae;
.btnTest:focus
background-color: #a2a2a2;
.btnTest:active
background-color: #c8c8c8;
.testRed
font-size: 18px;
padding: 1rem 3rem;
background-color: red;
color: cyan;
transition: 0.4s ease all;
.testRed:hover
cursor: pointer;
background-color: #ff4d4d;
.testRed:focus
background-color: #ff3333;
.testRed:active
background-color: #ff8080;
.testGreen
font-size: 18px;
padding: 1rem 3rem;
background-color: green;
color: #ff7fff;
transition: 0.4s ease all;
.testGreen:hover
cursor: pointer;
background-color: #00cc00;
.testGreen:focus
background-color: #00b300;
.testGreen:active
background-color: lime;
.testBlue
font-size: 18px;
padding: 1rem 3rem;
background-color: blue;
color: yellow;
transition: 0.4s ease all;
.testBlue:hover
cursor: pointer;
background-color: #4d4dff;
.testBlue:focus
background-color: #3333ff;
.testBlue:active
background-color: #8080ff;
.testOrange
font-size: 18px;
padding: 1rem 3rem;
background-color: orange;
color: #005aff;
transition: 0.4s ease all;
.testOrange:hover
cursor: pointer;
background-color: #ffc04d;
.testOrange:focus
background-color: #ffb733;
.testOrange:active
background-color: #ffd280;
.testPurple
font-size: 18px;
padding: 1rem 3rem;
background-color: purple;
color: #7fff7f;
transition: 0.4s ease all;
.testPurple:hover
cursor: pointer;
background-color: #cc00cc;
.testPurple:focus
background-color: #b300b3;
.testPurple:active
background-color: magenta;
.testYellow
font-size: 18px;
padding: 1rem 3rem;
background-color: yellow;
color: blue;
transition: 0.4s ease all;
.testYellow:hover
cursor: pointer;
background-color: #ffff4d;
.testYellow:focus
background-color: #ffff33;
.testYellow:active
background-color: #ffff80;
<button class='btnSecondary'>secondary</button>
<button class='btnPrimary'>primary</button>
<button class='btnTest'>test</button>
<hr>
<button class='testRed'>Red</button>
<button class='testGreen'>Green</button>
<button class='testBlue'>Blue</button>
<button class='testOrange'>Orange</button>
<button class='testPurple'>Purple</button>
<button class='testYellow'>Yellow</button>
我不明白为什么 HWB whiteness
和 blackness
无法与 HSL lightness
这样的数字相提并论。但有可能不用这些函数也能搞定,因为公式很简单:
您可以使用red($color) 和min
max
函数。
仅使用whitness
、blackness
和lightness
不足以处理某些颜色。我认为您正在寻找的是relative luminance 以获得最具对比的颜色。白色的亮度为 1,黑色的亮度为 0。灰底黑对比度大于灰底白。探索更多,了解this website 是如何计算对比度的。
可选参数您可以通过定义参数的默认值来生成arguments optional。在我们的例子中,任何非颜色值都可以:
@function contrastText($color, $text:-1)
$result: invert($color);
$lightness: lightness($result);
@if ($lightness < 47)
$result: black;
@if ($lightness > 46)
$result: white;
@if (type_of($text) == 'color')
$result: $text;
@return $result;
@mixin buttonStyles($color)
color: contrastText($color);
/*color: contrastText($color,);*/
/*color: contrastText($color, red);*/
【讨论】:
谢谢 - 看起来这可能是最接近的选项。但是是否可以使用 SASS 函数传入可选参数?我希望能够传入一个可选的文本变量,因为黄色按钮有点偏离,就像我刚刚制作的这个演示一样:jsfiddle.net/xytuj739 - 这可能吗?第 17 行似乎打破了它 是的,由于缺少参数,它在第 27 行color: contrastText($color)
失败。您可以将参数设为可选。查看更新后的答案。
太好了,谢谢!以上是关于SASS 检测颜色暗度以确定样式的主要内容,如果未能解决你的问题,请参考以下文章