Evaluation of functions within variables passed to SCSS

So a while back I found this post and particularity the new way mentioned here: Initialize Sass variables from Hugo templates

So I have a very similar setup as mentioned in that thread, in my html I have the following bit to render the SCSS with dartsass:

    {{ $options := (dict "targetPath" "css/style.css"
                         "vars" site.Params.style
                         "transpiler" "dartsass"
                         "outputStyle" "compressed"
                         "enableSourceMap" (not hugo.IsProduction)
                         "includePaths" (slice "assets/scss/lib")) }}
    {{ $style := resources.Get "scss/main.scss" | resources.ToCSS $options | resources.Fingerprint }}
    <link rel="stylesheet" href="{{ $style.Permalink }}" integrity="{{ $style.Data.Integrity }}" media="screen" />

Then in my scss file:

@mixin my-light-theme() {
  --background-color: #{h.$light-background-color};
  --foreground-color: #{h.$light-foreground-color};
}

And this works very well and good with the following config:

params:
  style:
    light-background-color: '#ffffff'
    light-foreground-color: '#000000'

Here comes the first twist on what I’m trying to do

Here comes the twist, sometimes I want to run a function within the css on the variable that I create.

So instead of the following:

@mixin my-light-theme() {
  --background-color: darken(#{h.$light-background-color}, 5%);
  --foreground-color: #{h.$light-foreground-color};
}

I just do this instead:

params:
  style:
    light-background-color: 'darken(#ffffff, 5%)'
    light-foreground-color: '#000000'

However, it doesn’t work with custom functions

In my main.scss file I have defined the line

@import "functions";

That imports the following file that contains a function called contrast-color that does what it says, it automatically calculates contrast colors for the foreground to be readable against the background: https://github.com/etu/etu.github.io/blob/main/src/scss/functions.scss#L53-L77

However, it seems like my contrast-color function isn’t evaluated when passing it through from a variable. My only guess is that it’s something that happens when hugo sends off the variables from yaml to scss so it evaluates functions it knows that are built in but not functions that are included.

Is there some way to accomplish this or do I have to find some other way?

So the logic is here: https://github.com/gohugoio/hugo/blob/master/resources/resource_transformers/tocss/internal/sass/helpers.go#L29

We try our best to preserve typed SASS values (e.g. 24px) , but I’m not sure we want to complicate this further. I think you put too much SASS in your Hugo coinfig – the issues you see can easily be avoided.

Yeah, you’re most probably right that I’m pushing it here :joy:

I’m building a theme that I want to be super flexible in terms of looks so I can re-use it and make it look quite different for different sites.

There’s probably a better way to do this…

So, not directly related to this, but I find it “simplest” (at least for smaller setups) to just import (or include) the vars into the default namespace. That way the user can override any variable he/she wants and can do so in either the Hugo config or in a SCSS file:

That said, I don’t see why your construct shouldn’t work, though, as contrast-color(... should just be passed as is to Dart Sass.

Oh, I just got it to work.

I changed this:

@use "hugo:vars" as h;
@import "functions";

Into this:

@import "functions";
@import "hugo:vars";

Had to change from the @use since it has to go first, and then ditch the h. “namespace” of variables. But it works! I will consider other ways as well for the future :slightly_smiling_face:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.