Setting images as background-image in css/sass

Hi, just looking for some clarification. I am trying to set a background image using sass. I initially placed the images in /assets/images/image.png. I then called the image in my sass using background-image: url("/images/image.png"). It worked. I did it this way as I read somewhere online that having images in assets enables Hugo to do some compression etc (maybe not the case?).

The following day I start working on the project and the image is not loading. There is the following message in the console GET http://localhost:1313/images/image.png 404 (Not Found).

Why did it work initially now it wont work? Also is there a preferred way of calling images in css?

I can get it to work fine if I place the image into /static, but would like to use assets if the compression handling occurs.

Below is my dart sass code

 {{ $opts := dict "transpiler" "dartsass" "targetPath" "css/style.css" "vars"
    site.Params.styles "enableSourceMap" (not hugo.IsProduction) "includePaths"
    (slice "node_modules/bootstrap/scss") }} {{ with resources.Get
    "sass/main.scss" | toCSS $opts | minify | fingerprint }}
      href="{{ .RelPermalink }}"
      integrity="{{ .Data.Integrity }}"
    {{ end }}

You might have had a version of that image in static/images….

You’re specifying an absolute URL here (“/images…”). So, your image must be located at $baseURL/images… at runtime. Which it apparently is not, as your browser can’t find it. You can

  • either specify a relative URL for your image, considering that this location is relative to the CSS’s location;
  • or specify an absolute URL and make sure that your image is there at runtime

In general, files in assets are not published by Hugo unless you process them (see the “Pipes” section in the documentation). That’s true for images as well.
If you don’t want/need to process the images, put them in static somewhere.

And please: Post a link to your repository instead of arbitrary sections of code. That permits others to reproduce your problem easily.

Thanks for the help @chrillek.

Heres a link to my repo develop branch.

I’ve done a bit more reading around the issue and believe now the image only previously worked because I initially called it as an img element using the following structure.

{{ $asset := resources.Get "/duck.png" }}
{{ $img := $asset.Fit "600x400" }}
<figure class="image is-3by2">
  <img alt="Yellow Duck" src="{{ $img.RelPermalink }}" />

Only the files whose .Permalink or .RelPermalink are used in a layout will be published to the public directory. Hence, my browser must have cached the image path allowing me to remove the image and call it later using the url in css.

Looking at the pipes docs its unclear to me how I would pipe the /asset/images. Any chance @chrillek you can expand on this process? Imagine I will also need to pipe .js files down the line as well.

Thanks again for the help.

1 Like

This example demonstrates, among other things, how to use a global resource (i.e., a file in the assets directory) as a background image when transpiling Sass to CSS.

git clone --single-branch -b hugo-github-issue-10558 hugo-github-issue-10558
cd hugo-github-issue-10558
npm ci
hugo server


1 Like

@jmooring I’ve given it ago see this branch. Unfortunately it still doesn’t work.

I’m able to access the variable in the .scss file using h.$test_image, but there is no image at the url. Comparing against hugo-github-issue-10558 the main difference I note is that when running hugo server the /resources directory has /gen/assets which includes /scss and /images. Whereas mine only has /scss. Also i have 0 images processed.

You’re missing a piece.

Go back to the example and look at layouts/partials/get-scss-vars.html.

Thanks @jmooring. I’ve now got it working.

I was hoping it would be able to fetch the image just by calling "vars" as per the reference. But I guess the key part re images is the following:

{{ $test_image := "" }}
{{ with }}
  {{ with resources.Get . }}
      {{ $test_image = .RelPermalink }}
  {{ end }}
{{ end }}

This is where the image is bound to the variable.

@jmooring what would be the preferred way to store and use images? Using the above method with /assets or simply compressing and image then placing it in /static/images and calling it from static?

Three methods…

  1. As you suggest, just place it in static.
  2. Place it in static, but pass the path through relURL or relLangURL before assigning it to a sass vars key
  3. Place it in assets per the example above

With method #1, if you later decide to change your baseURL in order to serve your site from a subdirectory (e.g. GitHub Pages), the URL will break. For your own site, if you know that the baseURL will never change, I guess that’s OK. But for a theme that’s a very bad idea.

Methods #2 and #3 prevent the broken URL problem described above, but option 3 gives you access to Hugo’s imaging pipeline (crop, fit, fill, resize, rotate, format, quality, filters, etc.).

1 Like