14

I am using CSS custom properties to set the background image for a div. The div is nested inside an anchor tag to represent a clickable "card" that routes to another page.

In Chrome with dev tools open and cache disabled, when I click on the card, the background image flickers. It appears to be fetching the image again every time the state of the anchor tag changes.

Additionally, if I add text-decoration to the anchor tag on hover the image flickers when hovering too.

CSS looks like:

:root {
  --image-url: url("https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80")
}

.image-div {
  height: 100px;
  width: 100px;
  background-image: var(--image-url);
  background-position: 0;
  background-size: cover;
}

See the pen: https://codepen.io/hally9k/pen/RmepVe

hally9k
  • 2,423
  • 2
  • 25
  • 47
  • I don't see it in chrome Version 74.0.3729.169 (Official Build) (64-bit) – Arleigh Hix May 30 '19 at 07:25
  • 5
    @ArleighHix It appears to be refetching the image every time the anchor state updates, the flickering is only noticable when dev tools is open with the cache disabled. The image gets refetched over the network every time the anchor state updates. – hally9k May 30 '19 at 22:22
  • Well that's what happens when you disable the cache, every time the element is re-drawn it will fetch the latest version. – Arleigh Hix May 31 '19 at 00:25
  • 1
    Hmmm, is it really as cut and dry as that? Firefox doesn't appear to behave in this way. Safari does though. Are you able to point to some docs, the spec or some other literature that would help me understand this better? – hally9k May 31 '19 at 05:32
  • 1
    This also seems to happen for me and is dependant on machine. It happens when dev tools is open and only on certain machines. If I swap out the image for a base64 encoded one; it stops happening. I would also like to know more; as I don't see a reason why there should be inconsistency between images declared with CSS variables and images declared in-place. – shennan Jul 03 '19 at 06:22
  • This happens for us as well under certain circumstances. It happens under slightly different configuration on all of Chrome, Safari, and Firefox, but in all cases only when using a CSS custom property for the image src. In our use case the image gets refetched every frame as its container transitions in position or size. I disagree with the assertion that a disabled cache means it should be refetched by the browser with every paint (and only when using a CSS custom property). – doublemarked Sep 11 '19 at 12:13
  • I reported this bug to the Chromium team, it seems to be a bug related to the "disable cache" setting as mentioned in below answer by @doublemarked. https://bugs.chromium.org/p/chromium/issues/detail?id=1282332 – George Jan 05 '22 at 05:57

1 Answers1

8

I have found that I can stifle this flickering (and refetching) by ensuring the image is returned with a Cache-Control header. Some common services (e.g. S3) don't return Cache-Control headers by default.

In my humble opinion, there's an underlying browser problem that causes it to sometimes refetch images when you're using a CSS custom variable and it repaints the element. In our case this occurred only when transitioning the element. The Cache-Control header taps into more low-level browser functionality related to resource caching.

doublemarked
  • 1,920
  • 1
  • 13
  • 10
  • Great job, this solves the problem. It is crazy how cache control can affect the flickering of a background image that uses variables. This happened to me on chrome and safari btw and only in real device. It is interesting to hear how you found this out. – Rotem May 05 '20 at 17:19