Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS media query (prefers-color-scheme) in custom SVG icons are not preserved #1937

Open
capi1O opened this issue Dec 26, 2024 · 0 comments
Open

Comments

@capi1O
Copy link

capi1O commented Dec 26, 2024

Steps to reproduce

  • Select a custom icon for a panel
  • Load a SVG icon containing a CSS media query to change color based on device light mode (light/dark)
@media (prefers-color-scheme: dark {
	path { fill: white; }
}
  • switch device light mode (light/dark)

Actual behavior

The color of the icon does not change (except for very small SVG icons, more on that in the description)

Expected behavior

The color of the icon should update based on the device light mode

System

Arch Linux

Firefox version

133

Sidebery version

5.2.0

Logs

no logs

Why I am using CSS media queries in icons

I am using CSS media query to update icon colors based on device light setting (dark or light), here is an example:

<?xml version="1.0" encoding="utf-8"?>
<svg height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
	 viewBox="0 0 512 512" xml:space="preserve">
	<style>
		path {
			fill: black;
		}
		@media (prefers-color-scheme: dark) {
			path {
				fill: white;
			}
		}
	</style>
	<path d="M503.581,384.894c-0.022-0.044-0.055-0.099-0.076-0.154L329.856,67.019c-31.962-58.479-115.761-58.469-147.717,0
			L8.414,384.894c-25.098,47.048,8.96,103.943,62.361,103.943h370.443C494.543,488.837,528.715,432.01,503.581,384.894z
			 M346.603,249.868L259.625,412.6c-8.272,15.449-31.909,9.513-31.909-7.935v-89.671h-75.53c-12.739,0-20.85-13.765-14.806-24.959
			l92.589-171.155c8.294-15.372,31.641-9.35,31.641,8.012v98.206h70.143C344.478,225.099,352.569,238.689,346.603,249.868z" />
</svg>

If you save this icon into a file and load it as a custom icon (file) for a panel, it will be black in light mode and white in dark mode. Whenever you switch the device light mode the icon color changes.

However for most of the other SVG icon files I tried, this does not work: it will appear with the correct color (based on the device light mode) upon load but will keep this color when device light mode is switched.

Here is an example of an icon file that stays to the same color:

<?xml version="1.0" encoding="utf-8"?>
<svg width="800px" height="800px" viewBox="0 -64 640 640" xmlns="http://www.w3.org/2000/svg">
	<style>
	path {
		fill: black;
	}
	@media (prefers-color-scheme: dark) {
		path { fill: white; }
	}
	</style>
	<path d="M512.9 192c-14.9-.1-29.1 2.3-42.4 6.9L437.6 144H520c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24h-45.3c-6.8 0-13.3 2.9-17.8 7.9l-37.5 41.7-22.8-38C392.2 68.4 384.4 64 376 64h-80c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h66.4l19.2 32H227.9c-17.7-23.1-44.9-40-99.9-40H72.5C59 104 47.7 115 48 128.5c.2 13 10.9 23.5 24 23.5h56c24.5 0 38.7 10.9 47.8 24.8l-11.3 20.5c-13-3.9-26.9-5.7-41.3-5.2C55.9 194.5 1.6 249.6 0 317c-1.6 72.1 56.3 131 128 131 59.6 0 109.7-40.8 124-96h84.2c13.7 0 24.6-11.4 24-25.1-2.1-47.1 17.5-93.7 56.2-125l12.5 20.8c-27.6 23.7-45.1 58.9-44.8 98.2.5 69.6 57.2 126.5 126.8 127.1 71.6.7 129.8-57.5 129.2-129.1-.7-69.6-57.6-126.4-127.2-126.9zM128 400c-44.1 0-80-35.9-80-80s35.9-80 80-80c4.2 0 8.4.3 12.5 1L99 316.4c-8.8 16 2.8 35.6 21 35.6h81.3c-12.4 28.2-40.6 48-73.3 48zm463.9-75.6c-2.2 40.6-35 73.4-75.5 75.5-46.1 2.5-84.4-34.3-84.4-79.9 0-21.4 8.4-40.8 22.1-55.1l49.4 82.4c4.5 7.6 14.4 10 22 5.5l13.7-8.2c7.6-4.5 10-14.4 5.5-22l-48.6-80.9c5.2-1.1 10.5-1.6 15.9-1.6 45.6-.1 82.3 38.2 79.9 84.3z" />
</svg>

Explanation

Since I tried various icons I realized that the only icons that "worked" were small icons, that is in size (kB). Whenever the path is big, it will not work.

After digging into the code I realized the problems comes from an optimization that Sideberry does when loading a custom icon, this happens in the function resizeFavicon

This functions makes a copy of the icon loaded, and saves it as PNG. Therefore any CSS styles are lost.
This optimization is skipped for small SVG files because of this check:

  const newFav = favRescaleCanvas.toDataURL('image/png')

  if (newFav.length + THRESHOLD_BYTES_DIFF >= fav.length) return fav
  else return newFav

where:

const THRESHOLD_BYTES_DIFF = 150 * window.devicePixelRatio

So if resulting icon is larger by 300 bytes (in my case window.devicePixelRatio = 2 according to FF) than original icon, the operation is skipped.

Proposal to allow media queries to work

May be this optimization could be disabled for SVG icons?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant