SASS:将 RGBa 转换回十六进制?
Posted
技术标签:
【中文标题】SASS:将 RGBa 转换回十六进制?【英文标题】:SASS: convert RGBa back to hex? 【发布时间】:2019-01-20 19:13:31 【问题描述】:我知道 SCSS 可以将 Hex 转换为 RGBa,但有相反的选项吗?
我的情况是这样的:我得到了一个不允许更改的调色板。这包括纯色强调色:
$color-accent: #039B15;
我被要求将其用作淡色背景色,不透明度为 80%。很简单,我可以用rgba()
:
$color-accent-bg: rgba($color-accent, .2);
但是,在某些情况下,我需要嵌套具有相同不透明背景颜色的元素 - 因为颜色是不透明的,嵌套时它们会变暗。
有没有办法可以使用 SASS 将 $color-accent-bg
转换回十六进制?
Ps:尝试使用lighten()
,但这似乎只能在 66% 的光线下工作。
【问题讨论】:
【参考方案1】:您可以尝试#039B1580
,但我相信此方法不适用于所有浏览器
【讨论】:
我创建了一个函数来convert rgba to hex接受look【参考方案2】:IMO 简单的 rgba($color-accent-bg, 1)
可以解决问题 - 它返回与 $color-accent
相同的颜色。
否则,您可以使用#ie_hex_str($color)。它将颜色转换为#AARRGGBB
格式的十六进制字符串。
将颜色转换为 IE 过滤器可以理解的格式。
例子: ...ie-hex-str(rgba(0, 255, 0, 0.5)) => #8000FF00
由于它返回字符串,您可以删除AA
部分,如以下 sn-p 中的最后一行:
$color-accent: #039B15;
$color-accent-bg: rgba($color-accent, .2);
$ie-hex: ie_hex_str($color-accent-bg); //#33039B15
$back-to-color-accent: unquote('#' + str_slice($ie-hex, 4)); //#039B15
【讨论】:
【参考方案3】:将 RGBa 转换为十六进制(透明。无背景,8 位颜色)。
经过测试的解决方案我已经在 scss 中编写了这段代码,然后转换为 sass
在你的 Scss 中输入:
// convert string to number
@function to-number($value)
@if type-of($value) == 'number'
@return $value;
@else if type-of($value) != 'string'
@error 'Value for `to-number` should be a number or a string.';
$result: 0;
$digits: 0;
$minus: str-slice($value, 1, 1) == '-';
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
@for $i from if($minus, 2, 1) through str-length($value)
$character: str-slice($value, $i, $i);
@if (index(map-keys($numbers), $character) or $character == '.')
@if $character == '.'
$digits: 1;
@else if $digits == 0
$result: $result * 10 + map-get($numbers, $character);
@else
$digits: $digits * 10;
$result: $result + map-get($numbers, $character) / $digits;
@return if($minus, -$result, $result);;
@function decimal-round ($number, $digits: 0, $mode: round)
$n: 1;
// $number must be a number
@if type-of($number) != number
@warn '# $number is not a number.';
@return $number;
// $digits must be a unitless number
@if type-of($digits) != number
@warn '# $digits is not a number.';
@return $number;
@else if not unitless($digits)
@warn '# $digits has a unit.';
@return $number;
@if $digits > 0
@for $i from 1 through $digits
$n: $n * 10;
@if $mode == round
@return round($number * $n) / $n;
@else if $mode == ceil
@return ceil($number * $n) / $n;
@else if $mode == floor
@return floor($number * $n) / $n;
@else
@warn '# $mode is undefined keyword.';
@return $number;
@function rgba-to-hex($rgba)
$colorCode: ( '0','1', '2','3','4','5','6','7','8','9','A','B','C','D','E', 'F');
// 255 / 100 = 2.55
// 10 / 16 = 0.625
$alpha: alpha($rgba);
// ============================================= RED ================================
$redStr: ''+(red($rgba) / 16);
$index: str-index($redStr, ".");
// add decimal number incase it does not have and update index
@if $index == null $redStr: $redStr+'.0'; $index: str-index($redStr, ".");;
// @debug $redStr '========================================================';
$redInteger : to-number(str-slice($redStr, 0, $index - 1));
$redDecimal: decimal-round(to-number(str-slice($redStr, $index + 1, $index + 1)) / 0.625);
// ============================================= GREEN ============================
$greenStr: ''+(green($rgba) / 16);
$index: str-index($greenStr, ".");
// add decimal number incase it does not have and
@if $index == null $greenStr: $greenStr+'.0'; $index: str-index($greenStr, ".");;
$greenInteger : to-number(str-slice($greenStr, 0, $index - 1));
$greenDecimal: decimal-round(to-number(str-slice($greenStr, $index + 1, $index + 1)) / 0.625);
// ============================================= BLUE ============================
$blueStr: ''+(blue($rgba) / 16);
$index: str-index($blueStr, ".");
// add decimal number incase it does not have and
@if $index == null $blueStr: $blueStr+'.0'; $index: str-index($blueStr, ".");;
$blueInteger : to-number(str-slice($blueStr, 0, $index - 1));
$blueDecimal: decimal-round(to-number(str-slice($blueStr, $index + 1, $index + 1)) / 0.625) ;
// if interger is 16 sent decimal should be 0
//@debug 'blue: '+ $blueStr +' interter: '+ $blueInteger +' decimal: '+ $blueDecimal;
// $blue: blue($rgba) / 2.55;
// ============================================= ALPHA ============================
$alphaStr: ''+ decimal-round((($alpha*100)*2.55) /16) ;
$index: str-index($alphaStr, ".");
@if $index == null $alphaStr: $alphaStr+'.0'; $index: str-index($alphaStr, ".");;
//@debug 'alphaStr: '+ decimal-round(to-number($alphaStr)) ;
$alphaInteger : ''+to-number(str-slice($alphaStr, 0, $index - 1));
$index: str-index($alphaInteger, ".");
@if $index == null $alphaInteger: $alphaInteger+'.0'; $index: str-index($alphaInteger, ".");;
$alphaInteger : to-number(str-slice($alphaStr, 0, $index - 1));
$alphaDecimal: to-number(str-slice(''+to-number(str-slice($alphaStr, $index + 1, str-length($alphaStr))) / 0.625, 0, 2)) ;
// @debug 'Integer: ==== '+$alphaInteger;
// @debug 'Decimal: ==== '+$alphaDecimal;
@return unquote("#"+nth($colorCode, $redInteger + 1)+nth($colorCode, $redDecimal + 1)+nth($colorCode, $greenInteger + 1)+nth($colorCode, $greenDecimal + 1) +nth($colorCode, $blueInteger + 1)+nth($colorCode, $blueDecimal + 1)+nth($colorCode, $alphaInteger + 1)+nth($colorCode, $alphaDecimal + 1));
;
用法
$result : rgba-to-hex( rgba(192, 84, 84, 0.582));
@debug $result;
.my-class
background-color: rgba-to-hex( rgba(192, 84, 84, 0.582));
输出
终端:
#C0535390
css 构建文件:
.my-class
background-color: #C0535390;
在您的 sass 文件中放入:
@function to-number($value)
@if type-of($value) == 'number'
@return $value
@else if type-of($value) != 'string'
@error 'Value for `to-number` should be a number or a string.'
$result: 0
$digits: 0
$minus: str-slice($value, 1, 1) == '-'
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9)
@for $i from if($minus, 2, 1) through str-length($value)
$character: str-slice($value, $i, $i)
@if (index(map-keys($numbers), $character) or $character == '.')
@if $character == '.'
$digits: 1
@else if $digits == 0
$result: $result * 10 + map-get($numbers, $character)
@else
$digits: $digits * 10
$result: $result + map-get($numbers, $character) / $digits
@return if($minus, -$result, $result)
@function decimal-round ($number, $digits: 0, $mode: round)
$n: 1
@if type-of($number) != number
@warn '# $number is not a number.'
@return $number
// $digits must be a unitless number
@if type-of($digits) != number
@warn '# $digits is not a number.'
@return $number
@else if not unitless($digits)
@warn '# $digits has a unit.'
@return $number
@if $digits > 0
@for $i from 1 through $digits
$n: $n * 10
@if $mode == round
@return round($number * $n) / $n
@else if $mode == ceil
@return ceil($number * $n) / $n
@else if $mode == floor
@return floor($number * $n) / $n
@else
@warn '# $mode is undefined keyword.'
@return $number
@function rgba-to-hex($rgba)
$colorCode: ( '0','1', '2','3','4','5','6','7','8','9','A','B','C','D','E', 'F')
// 255 / 100 = 2.55
// 10 / 16 = 0.625
$alpha: alpha($rgba)
// ============================================= RED ================================
$redStr: ''+(red($rgba) / 16)
$index: str-index($redStr, ".")
// add decimal number incase it does not have and update index
@if $index == null
$redStr: $redStr+'.0'
$index: str-index($redStr, ".")
$redInteger : to-number(str-slice($redStr, 0, $index - 1))
$redDecimal: decimal-round(to-number(str-slice($redStr, $index + 1, $index + 1)) / 0.625)
// ============================================= GREEN ============================
$greenStr: ''+(green($rgba) / 16)
$index: str-index($greenStr, ".")
// add decimal number incase it does not have and
@if $index == null
$greenStr: $greenStr+'.0'
$index: str-index($greenStr, ".")
$greenInteger : to-number(str-slice($greenStr, 0, $index - 1))
$greenDecimal: decimal-round(to-number(str-slice($greenStr, $index + 1, $index + 1)) / 0.625)
// ============================================= BLUE ============================
$blueStr: ''+(blue($rgba) / 16)
$index: str-index($blueStr, ".")
@if $index == null
$blueStr: $blueStr+'.0'
$index: str-index($blueStr, ".")
$blueInteger : to-number(str-slice($blueStr, 0, $index - 1))
$blueDecimal: decimal-round(to-number(str-slice($blueStr, $index + 1, $index + 1)) / 0.625)
// ============================================= ALPHA ============================
$alphaStr: ''+ decimal-round((($alpha*100)*2.55) /16)
$index: str-index($alphaStr, ".")
@if $index == null
$alphaStr: $alphaStr+'.0'
$index: str-index($alphaStr, ".")
$alphaInteger : ''+to-number(str-slice($alphaStr, 0, $index - 1))
$index: str-index($alphaInteger, ".")
@if $index == null
$alphaInteger: $alphaInteger+'.0'
$index: str-index($alphaInteger, ".")
$alphaInteger : to-number(str-slice($alphaStr, 0, $index - 1))
$alphaDecimal: to-number(str-slice(''+to-number(str-slice($alphaStr, $index + 1, str-length($alphaStr))) / 0.625, 0, 2))
@return unquote("#"+nth($colorCode, $redInteger + 1)+nth($colorCode, $redDecimal + 1)+nth($colorCode, $greenInteger + 1)+nth($colorCode, $greenDecimal + 1) +nth($colorCode, $blueInteger + 1)+nth($colorCode, $blueDecimal + 1)+nth($colorCode, $alphaInteger + 1)+nth($colorCode, $alphaDecimal + 1))
$result : rgba-to-hex( rgba(192, 84, 84, 0.582))
@debug 'peter =='+$result
我没有测试 sass 文件,我只是删除了分号“”和“”。
【讨论】:
我可以远程解释代码。以上是关于SASS:将 RGBa 转换回十六进制?的主要内容,如果未能解决你的问题,请参考以下文章
scss URL编码颜色SASS功能/将颜色转换为十六进制SASS功能