As I mentioned in my previous post, I was intrigued when the release of Hugo v.0.158.0 introduced its css.Build 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.
For example, it wasn’t so long ago that simply nesting your CSS like this . . .
.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; but, 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 using a post-processor to transpile 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).
Unless your site’s styling is very simple, you may want to organize your CSS into multiple files. If so, you then must determine how best to deliver all that CSS in production. Of course, your HTML can just link to multiple stylesheets, but it’s often better to combine multiple CSS files, especially for critical CSS, into one production-side bundle. That, too, formerly required one or more external packages, but CSS-bundling is another advantage css.Build can give you.
Also, you almost certainly want to minify your CSS for production. Although Hugo’s long been able to do that for CSS, as it does for other delivered files, css.Build now provides another way to do it for just CSS.
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” where CSS is concerned rather than having to use, say, Sass in development and/or PostCSS on the production side.
What it comes down to is that you must make a judgment call about which newer-style CSS features your site may require. Since css.Build works atop the esbuild package, the best source for what css.Build can and can’t do in this regard is the actual CSS-specific documentation for esbuild itself; this information lists the features for which esbuild performs either transpilation or browser-prefixing. And, even when armed with this knowledge, you still must test how/whether css.Build converts all the newer-style CSS you wish to deploy.
For those items which esbuild (and, thus, css.Build) currently can’t convert to your liking, you’re left with two choices: (a.) add some post-processing that will fill in the gaps; or (b.) decide to target only those browser versions that “know” those CSS items. While deciding, you’ll appreciate the convenience of tools like the Browserslist playground and the Baseline-specific list of supported browsers.1
Such limitations notwithstanding, css.Build’s other capabilities that I mentioned above can reduce or eliminate your needs for other CSS processors. Bundling and minification work right out of the box. And, best of all, css.Build works very quickly, which is an especially big advantage during development. The bigger your site and the more CSS you’re using, 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 those specific CSS gotchas we already mentioned above, what else, if anything, would you lose by going with just a vanilla-CSS-and-css.Build solution? To help answer that, let’s conclude by looking at the alternatives as you would use them in Hugo:
Sass pre-processing (involves writing .scss or .sass files, rather than .css files)
@use command.outputStyle option.PostCSS post-processing
@import command.Lightning CSS post-processing
css.Build or Dart Sass) when properly “shoehorned.”@import command.For my own lightly visited, non-commercial site with its relatively simple styling, I’ve determined that Baseline 2024 will suffice; but those of you with more heavily visited sites, especially if they’re commercial in nature, may well want to use additional post-processing to accommodate older and/or less commonly used browser versions. ↩︎
This is as opposed to how Lightning CSS works with some other static site generators, especially if Vite is involved. ↩︎
Latest commit (47c00b98a) for page file:
2026-04-02 at 12:20:39 PM CDT.
Page history