CSS background-image relative path var() on Safari not loading image
Asked Answered
W

3

7

Not sure if anyone encountered this problem (I've seen similar but not exactly) but on Mac OSX Safari browser the following problems happen when you use the variable for a relative image location for a background-image, it doesn't load

:root {
  --lb3-widget-icon: url(../../images/logo-icon2.png);
}
.image-area {
  background-image: var(--lb3-widget-icon);
}

Here is an example of a project that has that problem: https://codepen.io/alexbernotas/pen/dypLKvR

As you can see that the image that is over the blue area in the top left corner is not loading, but on Firefox and Chrome it loads without any problems, any ideas?

enter image description here

Checked on:

  • Mac OS 11.2.1
  • Safari 14.0.3

I know if you use the full image path URI then it will work but I need to get it to work with relative file paths


EDIT:

A much simpler example: https://codepen.io/alexbernotas/pen/abpbVeG

Willey answered 22/3, 2021 at 19:3 Comment(5)
Does the png definitely not load? Could you put up a simple snippet which shows the problem because when I tried a ../../file.jpg in the background image var it worked under Safari 14.4 (IOS) but I don't see the image in the linked site you give.Huckleberry
@AHaworth sure I added a much simpler example that replicates the problem, check the link above under the EDITWilley
Thanks, I can now see the problem under Safari (IOS).Huckleberry
This is looking like a Safari bug. If we use background-image: url(../../images/logo-icon2a.png); it picks up the image OK, i.e. manages to find the correct folder, but not if it's a variable. Do you see any errors at all? Not sure what to suggest.Huckleberry
Hi @AHaworth nope I don't see any errors in the console at all, yep I noticed if you put in the path directly it is happy but as a variable it fails :/Willey
H
6

This appears to be a Safari bug - seen also in IOS Safari (14.4).

The only workaround I can find is to have the background-image statement

background-image: var(--lb3-widget-icon);

in a style element in the main code file (with positioning of the png in the right relative place for that) - the var can still be set in the css file.

This is obviously not ideal, but does mean you can still use a CSS variable with relative folder path to select an image, though means the image folder has to move.

Huckleberry answered 23/3, 2021 at 16:16 Comment(1)
that is correct, we came to the same conclusion if you move the CSS file out to the location of the image directory or move the images to the exact same directory where the CSS file is hosted then this issue will be resolved as Safari is not happy with "../../" going up a level or a few levels when a CSS variable is involved. In addition to maintain the same structure for our publically available widget we decided to use SCSS variable instead for image paths as this allows us to retain the folder structure as it was a minimal change effortWilley
T
4

I just ran into this exact same bug. Thank you for writing it up!

For what it's worth, I added a redirect rule to my .htaccess file as a dumb but effective workaround:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*/(images/bg_.+\.png) real/path/$1 [L,QSA]

This will redirect all requests for images/bg_XXX.png with an invalid prefix to the correct path at real/path/images/bg_XXX.png.

Trioxide answered 11/12, 2021 at 22:54 Comment(0)
G
0

It looks like this specific problem has been fixed on the latest Safari, however there is still a problem (more a difference of opinion in fact) with the way Safari calculates paths that has been causing me problems and which prevents the accepted solution working for me.

In my case I have a custom .css containing a users own logo. It is located in mywebsite.com/css/application/custom/<userid>/. It contains this:

--bannerimage: transparent url(../../../images/application/custom/<userid>/logo.png) top left;

This variable is used by a css at a different level in mywebsite.com/css/application/something/somecss.css.

All browsers except Safari pick up the logo which is in mywebsite.com/images/application/custom/<userid>/logo.png. On Safari it tries to load a file mywebsite.com/css/images/application/custom/204107/logo.png. If I add an additional ../ to the path then it works on Safari, but no other browser.

What appears to be happening is Safari is determining the path relative to the CSS where the variable is defined. In Chromium and other browsers it is determining the path relative to the CSS where the variable is used.

There are two solutions:

  1. Store the two CSS files at the same level.

  2. Use Safari specific style to correct the path.

The Safari specific style solution has worked for me:

:root {
  --bannerimage: transparent url(../../../images/application/custom/<userid>/logo.png) top left;
}
    
@supports (font: -apple-system-body) and (-webkit-appearance: none) {
    :root {
        --bannerimage: transparent url(../../../../images/application/custom/<userid>/logo.png) top left;
  }
}

See also this question for Safari specific styles: Is there a way to apply styles to Safari only?

Hope this helps

Gondola answered 4/6 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.