Using templating and "@use" now Sass has deprecated "@import"

Dart Sass deprecated the use of @import in 1.80.0. Jekyll depends on sass-embedded, ~> 1.75, which looks to track the Dart Sass versioning. Hence, Jekyll now depends on a version of Sass that has deprecated @import.

As mentioned here without much resolution, this means most users of a Jekyll theme will see a lot of deprecation warnings.

Looking into it, it seems to me that @import is intwined with the way Jekyll does templating. That is, Jekyll expects the main scss file to have YAML front matter and can contain Liquid syntax, but the scss partials are pure scss. So typically in Jekyll you would use YAML to configure your main scss file, and then @import the partials. The partials then apply what got configured.

For example, main.scss might contain something like:

$header-image: "{{ site.data.style.header-image }}";
@import "base/page.scss";
@import "components/buttons.scss";
@import "components/navbar.scss";
@import "layout/services.scss";

Each of the partials can then make use of $header-image.

Without @import this doesn’t seem possible. You’d have to @use the partials, which then wouldn’t inherit the variable. And you can’t just @use a separate file that defines the variable, because only the main scss file can use configuration.

I’m new to Jekyll but I understand it’s mature, so if the above is correct (it may not be!), then maybe the way forward is to pin to <1.80.0. Or, given it’s just a warning, ask users to add quiet_deps to their config? I’m not sure if this has to be done by the user, or whether silence_deprecations is a better fit. The latter is not available in jekyll-remote-theme yet (I can’t add link cause newbie, but it’s issue #111).

Thank you for bringing this up. My main site is built w/o any theme to avoid dependencies. Another one, built on “minimal-mistakes”, I just moved to bootstrap, copying all pertinent files to my own assets. A third site, also on “minimal-mistakes”, which I rarely update, brings up lots of depreciation warnings. Prompted by you, I looked up more about `sass`. My version is 1.97.2, and would hope that the flag `–silence-deprecation` will give it some more years :smiling_face_with_sunglasses:. As you can see, I have no solution. Moving forward, I will just be even more wary of dependencies, though I get it: I maintain a repo myself and strive very hard to avoid breaking changes, but it’s difficult.

1 Like

I looked into this a couple of weeks ago.

I was interested in the ‘just-the-docs’ theme, and all the scss uses import and sass variables.

I fiddled around with it and managed to create a version that uses @use, @forward and also mostly css custom variables.

About then, I decided that ‘just-the-docs’ wasn’t what I needed, and left it.

It’s sitting in github, in branch sass-update, if you’re interested. WAF (with all faults) as they say in the used book business. Not refined, not squashed, not even properly commented.

Oh very interesting, thanks for sharing.

My understanding is that you could achieve this for the same reason it can be done for minima - the scss file doesn’t have any configuration. There’s no YAML front matter in base.scss, and all the variables.scss are hard coded. So the problem goes away.

But there’s something more going on here - the css files in the _includes folder are liquid files! I’m not sure how this works. They don’t have YAML front matter and I’m not clear on how they get processed. I think it might have something to do with the {% include command in the html includes.

So I think the fundamental issue remains - if you follow the Jekyll method for templating, you’re stuffed. But it’s certainly interesting this seems to be an alternative approach.

Files in _includes/css/*.scss.liquid have frontmatter and liquid includes.

I did find it fiddly tracing all the different locations. Looking at it now I see

  • _includes/css/*.css.liquid
  • _sass/*.scss
  • assets/*.css

Hmm, I still can’t see the frontmatter in those files. However, I realised I shouldn’t anyway, because they’re just the partials! The entry point is actually /assets/css and those files do have the frontmatter, as expected.

So my hypothesis turns out to be false. I said:

the scss file doesn’t have any configuration

but it does (eg. site.color_scheme and site.logo). Now site.color_scheme isn’t inherited (it gets assigned to a liquid variable and then just passed via include. But site.logo is!

So I don’t know how this works:

  1. site.logo is configured in _config.yml :white_check_mark:
  2. Jekyll processes the assets/css/just-the-docs-default.scss file, passing it the site configuration dictionary. :white_check_mark:
  3. That file includes _includes/css/just-the-docs.scss.liquid, which being liquid, also has access to the site dictionary. :white_check_mark:
  4. It assigns the site.logo value to the Sass variable $logo. :white_check_mark:
  5. You’ve changed it to @use _sass/modules.scss and, as is necessary, before $logo gets assigned :red_question_mark:
  6. _sass/modules.scss now @uses _sass/layout.scss :white_check_mark:
  7. Which finally, checks the $logo variable contents. :exclamation_question_mark:

I can’t see how layout.scss can know about the $logo variable. Possibly:

  1. I’m wrong about @use and it does actually pass variables down, even if they’re defined after the @use statement!
  2. There’s some other way layout.scss knows about $logo that I’m not seeing.
  3. Or, it doesn’t, and the port to @use wasn’t entirely successful…

This is super hard to follow and debug, so it could be any of these options! Would love to hear your thoughts.