How to organize CSS/SCSS with Hugo - with scoped CSS?

I’ve gotten used to 2 great tools in the past year: Hugo and Svelte.

One thing I love about Svelte is the automatic scoping of CSS & JS.
Much like with Vue.js, we can make something like this:

<!-- some_component.svelte -->
<style>
  h1 {
    color: red;
  }
</style>

<h1>Lorem Ipsum</h1>

And the color: red; will only apply to this H1, not anywhere else. (Because some class name will be applied at compilation.)

But with Hugo, it seems like the way to go is old school complete separation of HTML and CSS.

We can do some manual CSS scoping, so to speak, like this:

<!-- /layouts/partials/lorem_partial.html -->
<div id="lorem_partial">
  <!-- everything wrapped inside this div -->
</div>

<!-- /assets/scss/lorem_partial.scss -->
#lorem_partial {
  // all my styles for lorem_partial.html here
}

But:

  1. I’d rather have that SCSS right in lorem_partial.html
  2. Since it’s done manually, it’s prone to errors.
  3. That’s just my idea, so someone else probably thought of something better!

To me, it seems like scoping CSS is the way to go, but maybe there are good reasons not to do it?

Are there best practices for organization of CSS/SCSS in Hugo?

How do you organize your CSS/SCSS files?

1 Like

You could put style tags directly in an HTML partial if you’d like, but if you don’t do something special with the IDs/class names it won’t get scoped properly. For instance the style in your /assets/scss/lorem_partial.scss example above will not be scoped to only the /layouts/partials/lorem_partial.html component, it will get applied to any component that has the #lorem_partial ID. Svelte would handle something like this by adding a short hash that look like div#lorem_partial-urs9w7 so the style is scoped only to that specific element, even if another element in a different file uses the same ID/class name. Svelte will also strip out any unused styles before sending CSS to the browser. You could potentially build a custom system within Hugo to do something like that, but I’m not sure one currently exists. Maybe someone else is doing something similar? I’m working on a separate SSG that has a Go backend and Svelte frontend (https://github.com/plentico/plenti), but unfortunately the two are challenging to put together, so I’m not sure it would be an easy task to pull in. Hugo does now include esbuild for bundling JavaScript (https://gohugo.io/hugo-pipes/js/), so maybe it’s possible with that.

I usually break styles into their own component SCSS files that map to HTML partials, similar to your example. It doesn’t scope the style, but puts things in a logical place for a component based design approach. I’ve made a few videos showing the process for setting this up using Hugo Pipes so you don’t manually have to point to each SCSS file every time you add one:

Thanks @jimafisk!

I actually saw your presentation about Plenti at Svelte Summit ^^
Have yet to give it a proper try, though.

Anyways, I’ll stick to manually splitting styles in logically named .scss files for now.

I’ve made a few videos showing the process for setting this up using Hugo Pipes so you don’t manually have to point to each SCSS file every time you add one:

Interesting! Might give that a try too, although manually pointing to each SCSS file is not a huge bottleneck.

1 Like