hugo-theme-zzo icon indicating copy to clipboard operation
hugo-theme-zzo copied to clipboard

Custom CSS (or SCSS) that uses existing theme variables (colors)

Open somethingSTRANGE opened this issue 4 years ago • 4 comments

I would like to add custom CSS that uses an existing color variable defined in the themes, so if the viewer selects the "dark" theme, the class will use one background color, but when the "light" theme is selected, a different color will be used.

theme variable color value
dark search-background-color #212121
light search-background-color #eeeeee
.customClass {
  background-color: <search-background-color>;
}

I tried creating a custom SCSS file, but it generates an error: "no mixin named themify".

.customClass {
  @include themify($themes) {
    background-color: themed("search-background-color");
  }
}

I see that the themes/zzo/assets/sass/main.scss file imports themse/zzo/assets/sass/abstracts/_mixins.scss before importing other files that call the themify mixin, but I'm not sure how I should be importing those same mixins in my custom SCSS file, or whether I should even be trying to do that at all.

How can theme variables be accessed and used in custom CSS?

somethingSTRANGE avatar Jan 18 '21 08:01 somethingSTRANGE

Do you know Hugo's lookup order concept? https://gohugo.io/templates/lookup-order/#readout You can override the theme file. Try this

  1. Make a folder at root/assets/sass/themes
  2. Make files in the folder that you want to override. eg)_dark.scss, _light.scss
  3. Edit a color value in files.
  4. Restart Hugo after edit the files

Hugo will use your files instead of looking up the zzo folder.

zzossig avatar Jan 18 '21 09:01 zzossig

Thanks for that information. I will review those documents, however I'm not looking to override an existing theme, rather I'm looking to use an existing theme variable in my custom CSS.

I created custom CSS and SCSS files as mentioned in the Zzo Customization section, and the custom CSS works well, but I haven't figured out how to specify that theme-based colors should be used. If I set a background color to "red", it would use that color regardless of which theme was selected. I'm assuming I should be using the SCSS instead to access the theme variables and assign them to custom style.

For example, the following would force the background to red regardless of which theme was selected:

#body {
  background-color: red !important;
}

What I'm hoping to get it this:

#body {
  background-color: <insert the theme's "search-background-color" here> !important;
}

.brandNewCustomClass {
  font-family: <insert "title_font" as defined in "font.toml" here>;
  background-color: <insert the theme's "search-background-color" here>;
}

It's not clear to me how I would instead access an existing theme color, such as "search-background-color", and assign that to a background-color in a custom CSS class. I suppose the same could be said of the fonts. How would I assigned the theme's "title-font" to the font-family in a custom class in such a way that if the user selected a different theme, the CSS would be updated to match the new theme?

somethingSTRANGE avatar Jan 18 '21 09:01 somethingSTRANGE

Okay. It seems like custom SCSS defined in the custom_css array in "params.toml" are loaded, but they are not preprocessed through the theme, so theme variables cannot be used in them. However, importing that same custom SCSS from within the theme's "main.scss", does work.

I have the following two custom SCSS files:

root/assets/scss/custom.scss

//# Importing partial to make sure it works.
@import 'components/pagination';

//# Accessing a variable in Site Params doesn't seem to work. The rebuild fails with:
//#     TOCSS: failed to transform "main_parsed.scss" (text/x-scss): SCSS processing
//#     failed: file "<...>/assets/scss/custom.scss", line 5, col 12: Invalid CSS after
//#     "$testColor:": expected 1 selector or at-rule, was "{{ .Site.Params.tes"
//$testColor: {{ .Site.Params.testColor | default "#3399FF" }};

//# The DIV with the following class should be styled with the colors defined in $themes
//# and $codeblock, and the themed() function should return the proper colors.
.pagination-single-sidebar {
    @include themify($themes) {
        background-color: themed('navbar-background-color');
    }

    @include themify($codeblock) {
      color: themed('link-hover');
      text-decoration: underline double themed('content-pre-main-color');
    }
}

root/assets/scss/components/_pagination.scss

//# The link colors and fonts should be assigned using theme variables.
.pagination-single-sidebar a {
    font-family: $title-font;
    @include themify($themes) {
        color: themed('social-icon-color') !important;
    }
}
.pagination-single-sidebar a:hover {
    font-family: $cursive-font;
    @include themify($themes) {
        color: themed('social-icon-hover-color') !important;
    }
}

When the custom SCSS file is referenced in "params.toml", the following error is generated:

root/config/params.toml

testColor = "#660066"
custom_css = ["scss/custom.scss"]

TOCSS: failed to transform "scss/custom.scss" (text/x-scss): SCSS processing failed: file "<...>/assets/scss/components/_pagination.scss", line 3, col 18: Undefined variable: "$title-font".

When I remove the font-family: $title-font lines from "_pagination.scss", the build then fails on the themify function:

TOCSS: failed to transform "scss/custom.scss" (text/x-scss): SCSS processing failed: file "<...>/assets/scss/components/_pagination.scss", line 4, col 14: no mixin named themify

When I comment out the @import 'components/pagination'; in "custom.scss", the build then fails on the themify function call in "custom.scss".

TOCSS: failed to transform "scss/custom.scss" (text/x-scss): SCSS processing failed: file "stdin", line 14, col 14: no mixin named themify

If I remove the custom SCSS declaration (custom_css = ["scss/custom.scss"]) from "params.toml", and instead add the following line to the end of the theme's "main.scss", things start working and I see the expected colors and styles applied when the page is rendered.

root/themes/zzo/assets/sass/main.scss

@import '../../../../assets/scss/custom';

My understanding is that I shouldn't be modifying theme files, and I could probably make a copy of "main.scss" and add that import to the bottom, but shouldn't I be using "params.toml" to specify the custom SCSS file? If so, why isn't that working? What should I be doing to correct this, or am I expected to maintain a copy of the entire "main.scss" just to add an import at the end?

To be clear, using "params.toml" does work as long as I use literal colors and font names ("#FF0000" or "Arial"), but when I attempt to use values provided by theme settings, things fail.

somethingSTRANGE avatar Jan 22 '21 01:01 somethingSTRANGE

I'm pretty sure this was all do to user error on my part.

I renamed my "assets/scss" folder to "assets/sass" and then copied the contents of the theme's 'main.scss" over to my "main.scss".

At the bottom of my "main.scss" copy, I added

// This now works.
$testColor: {{ .Site.Params.testColor | default "#333333" }};

.pagination-single-sidebar {
	background-color: $testColor !important;
}

@import 'custom';
@import 'components/sidebar-pagination';

Now the custom SCSS files are being used and I'm able to access both theme and site variables within them.

Unless it seems like I'm doing something incorrectly or if I should really be using custom_css in "params.toml", you can probably close this issue.

somethingSTRANGE avatar Jan 22 '21 02:01 somethingSTRANGE