Hugo's New CSS Powers
Source: Hacker News
As I mentioned in my [previous post](https://www.brycewray.com/posts/2026/03/mixed-nuts-17/), I was intrigued when the release of
[Hugo](https://gohugo.io/) **v0.158.0** introduced its [`css.Build`](https://gohugo.io/functions/css/build/#article) function.
The new powers that resulted are worth a look when you consider all the aspects of styling a site you’ve built,
or plan to build, on Hugo. Still, the enhancements have certain limitations of which you’ll also want to be aware.
When forming the styling structure for a Hugo‑based website, you have a variety of options. CSS itself has gained many
additional features over the years, and browsers have improved to handle them.
> **Example:** It wasn’t so long ago that simply nesting your CSS like this…
```css
.my-div {
background-color: #ffffaa;
h1 {
font-size: 2rem;
color: #005500;
}
p {
font-size: 0.75rem;
}
}…required pre‑processing through Sass or post‑processing through something like PostCSS or Lightning CSS.
Now you can deliver CSS in production just like you see above, and any browser compatible with Baseline 2023 will display it as you intend.
However, unless you’re sure everyone in your site’s target audience is using a sufficiently updated browser, you have to adapt your site’s production styling accordingly—manually by using only pre‑2023 vanilla CSS, or automatically through Sass‑processed CSS or a post‑processor that transpiles modern CSS for compatibility with older browsers. That post‑processing is one way that css.Build shines (mostly; more on that in a little while).
Organising CSS
Unless your site’s styling is very simple, you may want to organise your CSS into multiple files
(MDN: Organising stylesheets). If so, you then must determine how best to deliver all that CSS in production.
- You could link to multiple stylesheets in your HTML, but it’s often better to combine them—especially for critical CSS—into a single production‑side bundle.
- Bundling formerly required external packages, but CSS‑bundling is another advantage
css.Buildcan give you.
You almost certainly also want to minify your CSS for production. Although Hugo has long been able to do that for CSS (as it does for other delivered files via resources.Minify), css.Build now provides another way to do it specifically for CSS.
Gotchas
All that said, css.Build has some gotchas which you’ll need to take into account when assessing whether this feature can be your sole “helper” for CSS, rather than using, say, Sass in development and/or PostCSS on the production side.
- You must decide which newer‑style CSS features your site may require.
css.Buildworks atop the esbuild package; the best source for what it can and can’t do is the esbuild CSS documentation. That page lists the features for which esbuild performs either transpilation or browser‑prefixing. - Even with that knowledge, you still must test how (or whether)
css.Buildconverts all the newer‑style CSS you wish to deploy.
For items that esbuild (and thus css.Build) currently can’t convert to your liking, you have two choices:
- Add some post‑processing that will fill in the gaps.
- Decide to target only those browser versions that already support those CSS items.
While deciding, you’ll appreciate tools like the Browserslist playground and the Baseline‑specific list of supported browsers.1
Why css.Build Might Be Enough
- Bundling and minification work right out of the box.
- It runs very quickly, which is a big advantage during development. The larger your site and the more CSS you use, the more you’ll appreciate the speed of
css.Build.
Perhaps after thinking through all this you decide css.Build might just work for your site.
Other than the specific CSS gotchas mentioned above, what else (if anything) would you lose by going with a vanilla‑CSS‑and‑css.Build solution? To help answer that, let’s look at the alternatives you would use in Hugo.
Alternatives
Sass pre‑processing
(involves writing .scss or .sass files rather than .css files)
- Requires use of the Dart Sass binary
(Hugo docs – Dart Sass).
But it works smoothly and very quickly with Hugo Pipes. - Provides no browser‑prefixing. Remember, it’s a pre‑processor; for prefixing you need a post‑processor, which adds complexity and likely slows down development.
- Lets you nest your styling, but currently does not support native CSS nesting
(Sass blog – native nesting).
This may not matter if your styling code is all‑Sass anyway. - Provides bundling through Sass’s
@use/@forwarddirectives, but you still need an extra step for minification and prefixing if required.
(Further alternatives such as PostCSS, Lightning CSS, etc., would be listed here in a full article.)
Footnotes
Sass (Dart Sass) – css.Build
Works natively with Hugo Pipes.
- Uses the
sasscommand‑line tool (via thecss.Buildfunction). - Performs minification through the “compressed”
outputStyleoption. - Offers math functions, logical functions, and mixins – some (or all) of which are already available in native CSS or may become part of Baseline CSS in the near future.
PostCSS post‑processing
Works well with Hugo Pipes but, because PostCSS is built on JavaScript, it is much slower than the other options described here.
- Uses various plugins to:
- Perform transpilation, polyfills, and browser‑prefixing for older browsers.
- Provide bundling via a plugin’s interpretation of CSS’s
@importrule. - Perform minification.
Lightning CSS post‑processing
Must be “shoehorned” into Hugo (see Bryce Wray’s guide). Lightning CSS also lacks a file‑watching capability, so that must be handled manually during development. When properly integrated, the Rust‑based Lightning CSS is very fast (though not quite as fast as css.Build or Dart Sass).
- Performs transpilation, polyfills, and browser‑prefixing for older browsers.
- Provides bundling via Lightning CSS’s interpretation of CSS’s
@importrule. - Performs minification.
Which to choose?
For my own lightly visited, non‑commercial site with relatively simple styling, I’ve determined that Baseline 2024 will suffice.
However, sites with higher traffic—especially commercial ones—may want additional post‑processing to support older or less‑common browsers. ↩︎
Note: This differs from how Lightning CSS works with some other static‑site generators, especially when Vite is involved. ↩︎
Latest commit (47c00b98a) for this page file:
2026‑04‑02 12:20:39 PM CDT.
Page history
Footnotes
- Baseline 2024 provides a solid, modern foundation for most sites.
- Lightning CSS integration with Vite is smoother because Vite handles watching and rebuilding automatically.
Footnotes
See the Browserslist playground and Baseline‑specific supported‑browsers list for quick reference on which browsers support which modern CSS features. ↩