Page MenuHomePhabricator

SVG files color cannot be overriden
Open, LowPublicFeature

Description

We sometimes use a single monochrome SVG image in different colors, which requires the use of different SVG files. For example, Wikimedia Commons has so many checkmarks with different colors that we have a template to list them. Yet, most are monochrome and could be dynamically derived from just the black version.

It would save us time if MediaWiki offered a way to show an SVG in a different color, which at least didn't require to change every variant when the (typically B&W) original/master file evolves.


Option 1

Enhance the [[File:]] syntax adding a "color=" attribute to allow recoloring on-the-fly the (typically B&W) source SVG, generating the same image but in a different color, rather than having to adapt the file, upload the variant, then maintain multiple versions.

Positives:

  • Reducing the duplication of same files differing only by color.
  • More user friendly - no need to work with the file anymore.

The generated file will be stored then like:
<server>/path/to/thumb/<hash1>/<hash2>/<filename>/<size>px_<4colorhexRGBA>-<filename>.png

So for instance for green File:AddSpeechbubble icon.svg it will be
[[File:AddSpeechbubble icon.svg|240px|color=#0f0|Icon]]
https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/AddSpeechbubble_icon.svg/240px_00ff0000-AddSpeechbubble_icon.svg.png

Complications:

  • tinting ability might need to be added to thumbor for Wikimedia production usage
  • as with size, page, etc this can create a large number of derivative files that need to be cleared on modification, but this should work with existing support
  • tinting/coloring alone might not be enough, we might need other features...
  • might be an extra complication to support that extra parameter in front-end tools

librsvg version 2.47.3 and ulterior would facilitate that avenue.

Option 2

Create a more general "derivative files" concept allowing 'virtual' modified files to be created from on-wiki sources, such as with a color tint (among other possibilities outside the narrow scope here). The derivative file can then be used with a direct [[File:]] usage as if it were any other file.

Complications:

  • need a UI for generating derivative files and saving them into the system
  • probably want an API for that too!
  • how many modification features to support? complexity/usability/safety concerns
  • thumbor considerations:
    • if MediaWiki generates the derivative master, then thumbor only needs to handle the thumbnails from a master, perhaps?
    • or do all derivation through thumbor, more complex
  • would URL structure of the generated files look the same as those with raw sources? If so, should work well with existing front-end tools?

Option 3

Add an explicit way to mark derivative files, with the implementation of tinting/cropping/etc left to extensions or bot tools for now. (cf DerivativeFX)

Option 4

Let templates / Lua modules generate SVG (sanitized for safety) and leave templating/tinting/etc to those templates to deal with. Also usable for graphics and things (compare with https://en.wikipedia.org/wiki/Module:Chart HTML charts!)

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

In my not-quite-done-yet patch the URL style will be like:

<path/to/thumb/hashes/filename>/(lang(<lang>)-)?(color(<color>)-)?<width>px-<filename>

If there's no lang or no color, those params don't get included.

Change 225657 had a related patch set uploaded (by Brion VIBBER):
Add ability to apply tint colors to SVGs with 'color='

https://gerrit.wikimedia.org/r/225657

That token to @Danny_B for creating a phabtask.

File inclusion syntax is already pretty rough. Typically we've been hesitant to extend it. Maybe the Parsoid folks will want to weigh in here.

I'm not sure about "color" as an attribute name. It seems like a really broad term. Maybe fillcolor? I'm also not sure the approach of extending file inclusion syntax to accommodate image variants is the correct approach.

It might be cool if you could have like a wrapper in the DOM that the SVG could then inherit from. Like you could specify background-color or color or border or whatever on the parent element and then the SVG would just inherit those properties.

If we go forward with this new syntax, the Wikimedia operations team may want a heads-up about the change in file name generation. Looking at the proposed file naming structure, I'm curious what |color=gray would do, for example.

File inclusion syntax is already pretty rough. Typically we've been hesitant to extend it. Maybe the Parsoid folks will want to weigh in here.

We had quite a long discussion with @brion and @violetto on this and the conclusion was that for the desired purpose this is the best and simpliest solution. Solutions like external tools and parser function in the extension were considered too. They were stroked out due to being either worse usable and accessible or too difficult to create.

I'm not sure about "color" as an attribute name. It seems like a really broad term. Maybe fillcolor?

There is not only fill color, but also stroke color. Both apply, thus we chose this attribute name.

I'm also not sure the approach of extending file inclusion syntax to accommodate image variants is the correct approach.

Please see the first paragraph for the reasoning.

It might be cool if you could have like a wrapper in the DOM that the SVG could then inherit from. Like you could specify background-color or color or border or whatever on the parent element and then the SVG would just inherit those properties.

That most probably wouldn't work as expected. Take inline attributes into consideration which have higher priority than stylesheet or style for parent element. @brion could perhaps say more on this, he was doing deeper research on it than me.

If we go forward with this new syntax, the Wikimedia operations team may want a heads-up about the change in file name generation.

This has also been discussed with @Esanders and @Krinkle. They may put more details here. So far I remember the deal was, that only if the (valid) |color= attribute would apply, then the new form of the filename will apply. Without the (valid) attribute the old name structure would apply. Thus still back compatible. @brion's filename structure also follows current habits (which I didn't take into consideration when proposing the filename structure).

Looking at the proposed file naming structure, I'm curious what |color=gray would do, for example.

Basically as long as the color is valid CSS valuke, it will apply, if invalid, it will be ignored. Reserved words for colors have their respective RGB numbers.

File inclusion syntax is already pretty rough. Typically we've been hesitant to extend it. Maybe the Parsoid folks will want to weigh in here.

We had quite a long discussion with @brion and @violetto on this

Who are "We"?

This seems like an incredibly edge-case to expand the already-too-complicated syntax with.

Currently we don't have a way of colorizing SVG. Our users have found icons on Commons to be useful for their own project uses, but there is no flexibility to tailor how the icons appear to fit their own project color themes or however they prefer to use them. They shouldn't need to own a graphics program to change SVG colors, it should be made as accessible as possible for their uses. This effort is based on real use cases and requests from volunteers, we should see how we can make it happen for them. Here's a few examples, and I'm imagining how many others feel like they need to stick with the black default and don't own a graphics program to alter an icon. [1][2][3]

The syntax may be already too complicated, but there is a real use case to this. I trust that @brion and @Danny_B came up with this solution based on what they thought was the simplest, given the timeframe, although it might not have hit all the goals:

As straight forward as possible to change color (e.g.: 2 clicks at most)
Minimize file duplication on Commons

If we don't think this is a perfect way to get around this need, let's put out a suggestion or talk about how we can make this happen.

[1] https://commons.wikimedia.org/wiki/Category:Derivatives_of_VisualEditor_icons
[2] https://commons.wikimedia.org/wiki/Category:Wikicons
[3] https://commons.wikimedia.org/wiki/Category:SVG_icons / examples: arrow facing right, alphahelixsection, bombilla, checkbox, community noun project

What is the status of this task, now that Wikimania 2015 is over? As this task is in the "Backlog" column of the Wikimania-Hackathon-2015 project's workboard: Did this task take place and was successfully finished? If yes: Please provide an update (and if the task is not completely finished yet, please move the project to the "Work continues after Mexico City" column on the Wikimania-Hackathon-2015 workboard). If no: Please edit this task by removing the Wikimania-Hackathon-2015 project from this task. Thanks for your help and keeping this task updated!

Moved. It was a WM2015 hackathon project, it started there and got almost finished there. Now final touches and review are being done.

There will always be users who ask for the moon, that is not the same as "our users as a whole are demanding X and if we don't give it to them we are failing them". In this case there are many downsides to the proposal:

  • overcomplicating already complicated syntax as James stated
  • issues with caching/server-load as mentioned by Krinkle IRL
  • reduced design consistency: if we have a set of theme-compatible colours we can point the user in that direction so that they can create more consistent UIs. Part of the reason users haven't created consistent UIs in the past is not just because of their desire to make a unique design, but because we haven't provided tools which make using standard UI components easier than starting from scratch. If you all do is give the users a box of crayons they'll pick their favourite colour and draw any shape button they think of. If you give them a "button" stamp, they'll use that instead - no matter what the colour.

A message to all open tasks related to the Wikimania-Hackathon-2015. What do you need to complete this task? Do you need support from the Wikimedia Foundation to push it forward? Help promoting this project? Finding an intern to work on it? Organizing a developer sprint? Pitching it to WMF teams? Applying for a grant? If you need support, share your request at T107423: Evaluate which projects showcased at the Wikimania Hackathon 2015 should be supported further or contact me personally. Thank you!

I know this is a old topic, but wanted to comment on it. In the example you give you want to colorize a speech bubble icon, this can be done already as long as the icons are crafted with this in mind.

As a example I took the icon File:Talk icon-72a7cf.svg I edited it so it now looks like File:Talk icon-transparent.svg

Since part of the image was left transparent, we can now use CSS to set the background-color of the element the image is a child of and this will change the color of the image.

You can see a example of setting different colors for the image on this sample page.

Since all the images are the same, the image only has to get cached by commons and the users browser once, instead of having to cache different colored images.

Couldn't we do this with a bot of some sort, rather than expand the image syntax? Ie, just refer to the file as [[file:basename-color.svg]] and we'll auto-generate the colored version of the svg from basename.svg. Maybe mark the SVG as colorable by adding it to [[Category:Colorable]] or something.

This kind of feature would be useful also in resource loader for some SVG images shipped in MediaWiki and extensions. It would need some kind syntax to specify the color in CSS/LESS.

@Nikerabbit Could you please specify such a use case?

It would help third party wikis in general with theming. They could use ooui icons in different colors in the content, or custom icons that are delivered with an extension rather than file uploads. It could be used to separate color from simple icons, so that color can be more easily changed. For example I maintain one wiki where each content namespace has a set color to differentiate it from others. I could also think of icons that change color on hover could benefit from this. It would reduce manual maintenance overhead.

From a usability and user experience perspective I'd be very careful with such use case. Most of OOUI icon packs' icons shouldn't be used in any possible way or color. Users should be able to quickly identify icons and interaction elements and their meanings in the whole website and should be able to recognize them after first usage.

daniel moved this task from (unused) to Under discussion on the TechCom-RFC board.

Looks like there's still some interest in this -- shall we consider a few options:

  • use just color overrides, or a more general templatized SVG system?
  • for File: renderings only, or make same system available to ResourceLoader?
  • ???
  • profit!
In T106240#3887935, @brion wrote:
  • for File: renderings only, or make same system available to ResourceLoader?

I think splitting this RfC along the lines of these two might make sense (as I support the latter but not the former without some serious controls).

TechCom is hosting a public IRC meeting for this on 2018-05-02 in the #wikimedia-office channel at 2pm PST(22:00 UTC, 23:00 CET)

It may be easier if we support embedding SVG instead of rasterizing it (T5593: [Epic] SVG client side rendering), so we don't have to touch the thumbnail URL

Change 225657 abandoned by Brion VIBBER:
Add ability to apply tint colors to SVGs with 'color='

Reason:
Abandoning this version of the patch. Will whip up some provisional replacements later once we're more sure what we want to implement.

https://gerrit.wikimedia.org/r/225657

some recommendations to do user testing with TemplateStyles and CSS filters before investing further (brion, 21:48:11)

The issue with CSS filters is that it is damn hard to add a (specific) color to black icons.

The issue with CSS filters is that it is damn hard to add a (specific) color to black icons.

I came across a tool to help with that: https://codepen.io/sosuke/pen/Pjoqqp

@Nikerabbit Thanks for sharing. Would be handy. But we need to be careful with this though, as the comments on the original SO thread shows, Edge doesn't seem to like the sepia filter (on black) and therefore doesn't colorize the icon.

image.png (722×1 px, 154 KB)
Edge 15

Moving to the RFC backlog, for lack of product support.

Maybe the Multimedia team wants to pick this up? This shouldn't be implemented without an RFC, but it seems unclear whether it's needed/wanted at the moment. If not, it should probably be closed as stalled.

FWIW, OLPC did recoloring of SVGs by (re)defining XML entities. Probably not too useful, since I don't think there was ever good tool support for this, just adding it for completeness: http://wiki.laptop.org/go/Making_Sugar_icons#Defining_Entities

Aklapper added a subscriber: brooke.

This task has been assigned to the same task owner for more than two years. Resetting task assignee due to inactivity, to decrease task cookie-licking and to get a slightly more realistic overview of plans. Please feel free to assign this task to yourself again if you still realistically work or plan to work on this task - it would be welcome!

For tips how to manage individual work in Phabricator (noisy notifications, lists of task, etc.), see https://phabricator.wikimedia.org/T228575#6237124 for available options.
(For the records, two emails were sent to assignee addresses before resetting assignees. See T228575 for more info and for potential feedback. Thanks!)

This appears to be a feature request more than a technical RFC. Perhaps it should be declined, but I'd like to give SDE an oppertunity to give this a moment from a product perspective and make that call.

If not declined, then please re-tag TechCom-RFC and follow the RFC process by adding the template to the task description.

Quoting the librsvg-developer from https://gitlab.gnome.org/GNOME/librsvg/-/issues/736#note_1119478


Inheriting color from the outside - this is already doable since #379 (closed). You can use rsvg-convert --stylesheet=custom.css -o output.png myfile.svg to use a custom stylesheet. SVG lets you specify an "environmental" color with currentColor like this:
hello.svg:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="40" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <text fill="currentColor" x="20" y="20" font-family="sans" font-size="20">Hello world!</text>
</svg>

custom.css:

* { color: green; }

If you run rsvg-convert --stylesheet=custom.css -o hello.png hello.svg you will get green text. This is especially useful if you render equations as SVG; if you include inline equations as SVG in the middle of a paragraph in HTML, and they use currentColor, they will inherit the color of the surrounding text.


So I think it implemented since librsvg2.48 .

Yes, this was included in 2.47.3 and every later version.

This is fixed in librsvg version 2.47.3 and later librsvg versions.

Fixed is maybe a wrong wording. librsvg supports this feature, but MediaWiki imho not now (even if librsvg would be updated). In SVG exists 16777216 colors + 'none' . 4096colors also have a three digit code and 147 colours have a name. So files with currentColor needs to have additionally this css-feature, this must be dedected during parsing (similar to systemLanguage). For the preview we should also define a default color (mabe black). Do we allow this css-feature in combination with 'systemLanguage'? If would allow a more generall css (e.g. as in File:SVG_CSS_Test.svg ), it will be difficult to allocate a already rendered png without rerendering.

For the current station I would call it stalled & upstream (patch merged upstream), also that's not fully correct (as I just explained). But as soon we are going to update to 2.48 (only even numbers are for production), we should rethink how and what we/WMF want(s) to implement.

I would decline this task.

Uploading files is fairly cheap. Adding mechanism is expensive.

Any wikitext syntax would not have a parallel in other, external, environments.

Yes, CSS can tailor appearance, but that is meant for an overall style rather than customizing individual images.

Aklapper changed the subtype of this task from "Task" to "Feature Request".May 24 2023, 10:09 AM
Chealer renamed this task from Colorable SVG to SVG files color cannot be overriden.Oct 21 2024, 7:13 PM
Chealer updated the task description. (Show Details)

Wikimedia now uses a recent enough librsvg, but as @JoKalliauer wrote, this does not solve the problem, it only facilitates one avenue; I rectified the description accordingly.

I hope there can be a better way than controlling rasterization (it may be more efficient client-side), but I note that although very promising (as this introduction/demonstration shows) and well supported, the CSS filter effects module remains a working draft :-/

some recommendations to do user testing with TemplateStyles and CSS filters before investing further (brion, 21:48:11)

The issue with CSS filters is that it is damn hard to add a (specific) color to black icons.

Can you clarify? Can you provide an example?

Side note about color accuracy

I noticed while sorting all our check mark variants that the color of some PNG conversions are slightly incorrect. The body of the check mark in the SVG has a color different from the body in the PNG, although the difference is hard to notice from naked eye. Cases I noticed:

  1. Green_check.svg, which has #088908 instead of the specified #118811.
  2. Check-green.svg, which has #008100 instead of the specified #008000.

Purging the cache does not fix. If someone is aware of this bug, please let me know if it is tracked.