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 转换回十六进制?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 rgba 转换为透明度调整的十六进制?

ruby 将十六进制颜色转换为RGBA

将 8 位十六进制颜色转换为 rgba 颜色?

scss URL编码颜色SASS功能/将颜色转换为十六进制SASS功能

scss URL编码颜色SASS功能/将颜色转换为十六进制SASS功能

将 RGBA 转换为 HEX