Why Image-Path Is Not Resolved in SCSS

why image-path is not resolved in scss?

If it is scss and not compass then it would go like this (look at where you sprites folder is compared to your scss file)

.social-share-button-baidu 
{
display:inline-block;
width: 16px;
height: 16px;
background: url(../sprites/social-share-button.png) 0px 0px no-repeat;
}

../ takes you up out of one folder, can you see the sprites folder from there?

SCSS/CSS background-image url path problem

In a perfect world your URL paths should be absolute, so always starting with / refering to the base path of the domain.

You have:

background-image: url('./../img/coffee.png') no-repeat;

The shape you should be looking for is:

 background-image: url('/folder/img/coffee.png') no-repeat;
^ This lead slash references the base path of the domain.

So, the above example is domain.com/folder/img/coffee.png - you see the leading / is the base the whole URL is based from.

The advantage of this is your SCSS or CSS or image files can be placed in any location in your domain structure.

Absolute Pathing is the key to success!

Example 2:

 background-image: url('/images/tea.png') no-repeat;

Image is located at:

 mydomain.org/images/tea.png 

The location of the SCSS or CSS file is not important, as long as it's on the same domain.

webpack - scss cannot resolve background-image url

Since you're using Webpack 5, I'd recommend using Asset Modules instead of the deprecated loaders

module: {
rules: [
// ...
{
test: /\.(png|jpg|gif)$/i,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 8192
}
}
}
]
}

I suspect you were running into a resource handling duplication issue as noted in the documentation...

When using the old assets loaders (i.e. file-loader / url-loader / raw-loader) along with Asset Module in webpack 5, you might want to stop Asset Module from processing your assets again as that would result in asset duplication. This can be done by setting asset's module type to 'javascript/auto'.

Webpack 5 - Scss relative urls won't load images

At the end the problem with the images was simply in the publicPath on the web.config.js file.

Changing it from dist/ to /dist did the job.

const path = require("path");

module.exports = {
...
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "dist/", //This is where the issue was
filename: "main.js",
assetModuleFilename: "[name][ext][query]",
clean: true,
},
...
};

Let this be a warning for all ye who enter webpack.

SCSS image path not working

I'd personnally set the images url to fit the style.css needs.

In my point of view, style.scss is here only to provide more flexibility during the coding of your design. This way, i never use .scss files inside my HTML.

Taking the in mind that i always compile the .scss into .css, that makes no sense to me to set the path from the .scss file.

By the way, i know there are tools allowing to auto-compile .scss files before returning them compile from the server, but i'm not pretty fan of this solution, because more than requesting a file in HTTP GET, you'll need your server to compile code before returning it, so it'll obviously take a bit more time...

Webpack 5: sass doesn't find path for images

Long shot here, but it looks like you have the same file structure as my project, so you might only need to go up one directory for your import (i.e. ../images/bg.jpg rather than ../../images/bg.jpg).

I get the same error as you when I look two directories up, though it may be unrelated.

Unable to use assets in url() in scss after upgrading to Angular 10

Not really sure what's changed in Angular 10?

But I found three solutions. The first solution I knew will work but that's time taking to implement in an existing mid-size application. But if you have only a few assets to fix, you should go for the first solution only.

Solution 1 - Using relative assets path (Recommended)

The solution is to use the relative path (from your .scss file) of your assets. Basically adding ../ until the assets folder is reached.

:host {
display: block;
min-height: 500px;
// Using relative path
background: url('../../../assets/images/about-us.png') no-repeat center;
}

Pros

  1. This approach enables the hashing of your static assets. Once your application is built (using ng build --prod), your asset URL will be replaced with an MD5 hash to burst the caching.

    So your URL

    background: url('../../../assets/images/about-us.png') no-repeat center;

    will be replaced as

    background: url('about-us.add9979f32e1c969e6f8.png') no-repeat center;

    This is basically an MD5 checksum of the content of the image. So basically, when the image changes even by one pixel, this checksum will be changed by Angular. This helps you to burst caching in future when you change your image while keeping the file name the same.

    Read more here for knowledge.

  2. IDE (I use IntelliJ IDEA) does not show errors of the assets in your SCSS files that means if the file path is wrong, IDE will tell you in advance.

    IDE Errors Gone

  3. You get the directory linking. That means if I press Ctrl & click on a directory in the URL above, IDE will open up that directory.

Cons

  1. (Manageable) This might be a cumbersome approach as the developer has to write the asset which needs to be relative to the assets folder.

  2. (Manageable) The hashed asset (image in this case) will be copied to the root folder in the build (i.e. dist by default) directory which might fail your any kind of URL rules (for example, caching rules). So instead of-

    https://example.com/assets/images/about-us.png

    the following URL will be used-

    https://example.com/about-us.add9979f32e1c969e6f8.png
  3. (Manageable) If you change the path of your component, you have to change the image URL as well.



Solution 2 - Quick Fix

Based on the answer posted here https://github.com/angular/angular-cli/issues/10004#issuecomment-375969537, adding / in front of the URL worked.

:host {
display: block;
min-height: 500px;
background: url('/assets/images/about-us.png') no-repeat center;
}

Pros

  1. You do not have to add many ../ prefixes to make it a relative URL.
  2. If you change the path of your component SCSS file, you don't have to change the path of your assets in url("").

Cons

  1. The second solution will not work in the production build if --base-href is used (as stated here). angular-cli#18043.

  2. Your IDE keeps showing the path error even if the path is correct.

    IDE path error

  3. You do not get the hashed URLs to burst the cache (unlike solution 1)



Solution 3 - Fooling the Angular CLI processor (not recommended)

I looked into the CLI code & figured out that if a URL starts with ^, Angular ignores the asset by bypassing the URL.

:host {
display: block;
min-height: 500px;
background: url('^assets/images/about-us.png') no-repeat center;
}

Source code- https://github.com/angular/angular-cli/blob/v10.0.0/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/postcss-cli-resources.ts#L72

Pros

  1. You do not have to add many ../ prefixes to make it a relative URL.

  2. If you change the path of your component SCSS file, you don't have to change the path of your assets in url("").

Cons

  1. This solution might get removed in the future releases as stated by one of the Angular CLI developers in #18013 (comment)


Related Topics



Leave a reply



Submit