Angular 2 Load CSS background-image from assets folder

try

background-image: url('../../assets/home-page-img/header-bg.jpg');

Demystifying Angular paths to resources in CSS files

This is not documented nor has anyone to my knowledge written about it.

This is true for Angular 11 but has certainly been around for a while.

(Note: setting --base-href or --deploy-url in ng build has no consequence to the following).

The regular way to include assets in a css file, such as:

background-image: url(/assets/someImage.png);

is with a leading slash. During the build prosses (ng serve or ng build), if angular sees that leading slash, It will ignore that path, meaning it will copy it as is. So the browser will see that path '/assets/someImage.png', and will look for that file starting at the root or as we call it domain. (Note: paths in CSS are relative to the location of the CSS file, but even in CSS a leading slash means looking for the file starting form root). Angular assumes you put that file In the default assets folder, who's contents are copied as is to the dist folder, and that sits by default in the root, so someDomain.com/assets/someImage.png just works.

However, if for some reason you are trying to do something else, and you remove that slash, a whole new prosses is happening. For example, lets say you now write

background-image: url(assets/someImage.png);

without the slash. (for example when you deploy your app to an inner folder in a domain 'someDomain.com/some-folder/', and assets is in that folder. With the slash it will look for assets in the root, and it not there, its in some-folder. So you remove the slash thinking that it will also copy that code as is and look for assets from where the css file is, which is what the browser will do).

Surprise! Angular this time does not ignore that file path!! it looks for it during build time!! and it doesn't fine it, and you get that annoying error saying angular can't find that file. So what you do is rewrite that path until angular can find it (in your file system), for example: if your in a deeply nested component

background-image: url(../../../../assets/someImage.png);

And then, boom, it works, but take a look at what happened to your dist folder and to your CSS code. Angular makes two copies of the someImage.png file. One in the regular assets folder and the other in the root, right next to all the js bundles. And in you CSS file

background-image: url(../../../../assets/someImage.png);

will be rewritten to

background-image: url(someImage.png);

This works, but not exactly nice dist folder structure. This behaver is same for global style.css or component style that gets injected to the index.html or shadowRoot (ViewEncapsulation.shadowDom)

(Note: in the html templates there are no checks or rewrites)


I use it. Always starting with "/assets/" in CSS and HTML "assets/". And I have no problems. Angular recognizes it.

CSS

.descriptionModal{
    background-image: url("/assets/img/bg-compra.svg");
}

HTML

<img src="assets/img/ic-logoembajador-horizontal.svg" alt="logoEmbajador">

For background-image: url(/assets/images/foo.png), I have another problem with i18n + base-href, finally I found a workaround solution.

My problem was solved by:

background-image: url(~src/assets/images/foo.png) .

image tag:

<img src="assets/images/foo.jpg" />

Tags:

Html

Css

Angular