Search code examples
htmlcsssassjekyllbackground-color

Changing the opacity of the background color by converting the color to rgba


I am using the Jekyll theme just-the-docs.

I have defined a new custom-callout class and would like to change the opacity of the background color. This is the code I have come up with and it does not work:

custom-callout.html file:

{% assign callout_type = include.callout %}
{% assign callout_color = site.callouts[callout_type].color %}
{% assign callout_title = site.callouts[callout_type].title %}
{%- assign callout_opacity = 0.2 -%}
{% assign background_color=rgba(${{ callout_color }}, {{ callout_opacity }}); %}

<div class="custom-callout" style="background-color: {{ background_color}}; border-left: 4px solid {{ callout_color }}; border-radius: 4px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); padding: 0.8rem; margin-bottom: 1.5rem;">
  <strong class="custom-callout-title" style="color: {{ callout_color }}; display: block; font-weight: bold; margin-top: 0; margin-bottom: 0.5rem;">{{ callout_title }}</strong>
  {{ include.content | markdownify }}
  {% if include.collapsible_content %}
    <details>
      <summary>{{ include.summary }}</summary>
      {{ include.collapsible_content | markdownify }}
    </details>
  {% endif %}
</div>

The callout definition in the _config.yml file

callouts:
  error:
    title: Error
    color: red

Note: if I change the line

{% assign background_color=rgba(${{ callout_color }}, {{ callout_opacity }}); %}

to

{% assign background_color=callout_color; %}

it all works fine but obvisously there is no opacity applied. It seems clear that the problem is converting the color to rgba in order to apply the opacity parameter. I also tried other functions like fade which did not work either.


Solution

  • color-mix()

    You could use color-mix() like:

    {%- assign callout_opacity = '20%' -%}
    <div class="custom-callout" style="background-color: color-mix(in srgb, {{ callout_color }}, transparent {{ callout_opacity }});
    

    However, please be aware that browser support is spotty, with no support in Firefox.

    Keyword to RGB components map

    Define some sort of object map for every HTML color keyword that you may use to convert the keyword into its RGB component equivalent:

    {
      "red": "255 0 0",
      "blue": "0 0 255",
      …
    }
    

    Then use the callout_color as the key to this map, whereby it has been injected into the template as the rgb_map variable:

    {% assign callout_opacity = '0.2' %}
    <div class="custom-callout" style="background-color: rgb({{ rgb_map[callout_color] }} / {{ callout_opacity }});
    

    If you know there is only a subset of keywords that will be used, you could try a set of if or case/when statements instead:

    {% case callout_color %}
      {% when 'red' %}
        {% assign rgb_color = '255 0 0' %}
      {% when 'blue' %}
        {% assign rgb_color = '0 0 255' %}
      …
    {% endcase %}
    {% assign callout_opacity = '0.2' %}
    
    <div class="custom-callout" style="background-color: rgb({{ rgb_color }} / {{ callout_opacity }});