Icon standardisation

The purpose of this page is to document current methods for styling icons across MediaWiki extensions.

Overview
Flow uses a local copy of WikiFont for most of its icons.

It has some implicit icons with no text: [···] for drop-down, v for its sort menu, but most are [glyph] Action name.

Example
To render a lock icon, but with backup text for screen readers and older/incompatible browsers (text does not render in modern browsers; just the icon):

Browser support
Icons: IE9+, FF3.5+, Chrome, Safari 3.2+. (IE8 support can be added with an uglier CSS hack, if applied to the patch linked below.)

Backup text: all browsers, screen readers.

Code
icons.less (backup text support is in a patch)

Overview
We generally use background images, with SVG and PNG fallback. We are fine with using WikiFont for permanent features.

However, we want the ability to use SVG/PNG (or a similar low-friction method) for experimentation, so not every experiment needs to go through the full WikiFont workflow.

This workflow is:


 * Regenerate the output font files (which currently is not scripted)
 * Commit the updated/added source file, and updated generated files to the WikiFont repository (getting code review for this)
 * Commit the built version of WikiFont to core (getting code review for that)
 * If a Growth extension needs the icon before the normal train deployment, cherry-pick the core commit to a core deployment branch

Then (in the event we decide not to make it a permanent feature) remove the icon, doing the whole thing (except the cherry-pick) in reverse.

Browser support
As with MobileFrontend, we rely on having a correctly sized fallback PNG for those browsers that don't support SVG and the `background-size` property.

Overview

 * In mobile we use SVGs and fallback pngs with background-size
 * All our classes are top level without nesting. This is an OOCSS approach.
 * In mobile we use a generic icon class which defaults to 24px width and height and is designed to hide any text inside the element the class is associated with
 * We use modifiers to tweak an icon.
 * Modifiers define the icon image e.g. icon-settings.
 * Modifiers can change the icon size. e.g. icon-32px would set the icon to use a background size of 32px
 * Modifiers can make the icon appear to the left of the text by using the icon-text class

Example
See output of this example on MobileMenu

Browser support

 * The only browsers that experience problems with our method are browser which do not support `background-size`. These also correspond with browsers that do not support SVG. To get around this we ensure the fallback PNG has the same dimensions as the situation where it used. For example if an element has the class "icon-unicorn icon icon-64px" the fallback png would (or should) be 64px by 64px.

Code
Our icons less file documents usage in MobileFrontend.

Overview
VisualEditor uses the  mixin from OOjs UI to add icons to widgets. There is also a related mixin,, that adds an "indicator". Icons are 24x24px and generally go on the left, whereas indicators are 12x12px and generally go on the right. A good example of an indicator is the down arrow to the right of the label on a dropdown.

Mixing in IconedElement and IndicatedElement is simple. The mixins read the  and   parameters from the config object and generate spans with the right CSS in   and. All the caller has to do is pass in the icon/indicator parameter to the widget's constructor, and all the widget's constructor has to do is take  and   and put them in the DOM somewhere.

Most widgets are optionally iconed/indicated, and default to not using them. Some widgets have a default icon/indicator which will be used unless overridden.

Example
TextInputWidget, for example, mixes in both IconedElement and IndicatedElement. It doesn't specify a default for either the icon or the indicator, so neither will be displayed unless the constructor is called in a way that explicitly calls for an icon and/or indicator.

Then this is how SearchWidget constructs a TextInputWidget. It specifies the icon by symbolic name. The indicator is not specified, and TextInputWidget doesn't have a default indicator, so no indicator will be used.

Here's how OutlineControlsWidget mixes in IconedElement, with a default icon of. This can still be overridden by the caller through the config parameter.

For what the CSS/LESS looks like, see the links in the "Code" section below.

Browser support

 * OOjs UI supports both SVG and PNG, and has both SVG and PNG versions of all(*) icons
 * OOjs UI does not itself provide for a mechanism to detect whether SVG is supported and use SVG if so or PNG otherwise
 * VisualEditor used to feature-detect SVG support and dynamically choose whether to use the SVG or the PNG stylesheet from OOjs UI
 * Nowadays, VE is SVG-only because our other browser support requirements already exclude all non-SVG browsers anyway

(*) Or at least that's what we aim for, it's possible that we don't literally have every single icon supported in PNG at this precise moment

Code

 * Implementation of the icon, indicator and texture functions in common.less
 * IconElement class
 * IndicatorElement class