Page MenuHomePhabricator

Allow styles to be language-dependent
Closed, DeclinedPublic


It should be possible to vary skin and/or core styles based on language, preferably in a way that does not make dealing with large groups of languages onerous. See T73240 for motivation (in that case it is about content language; it's not hard to imagine other use cases which would need varying on user interface language, so ideally both should be supported).

Old patch from @Jdlrobson:

Event Timeline

Tgr created this task.Jun 10 2015, 6:53 AM
Tgr raised the priority of this task from to Needs Triage.
Tgr updated the task description. (Show Details)
Tgr added subscribers: Tgr, Jdlrobson.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJun 10 2015, 6:53 AM

There is a patch pending review, with some questions on whether that's really the best way we currently have:

Volker_E added a subscriber: Volker_E.EditedJun 10 2015, 3:17 PM

Connected to T65817 (Provide a workaround to IE's bug that causes the generic "serif" rendered broken)

For styles and as handler for JS we're already able to use :lang pseudo-class (IE8+) or attribute selectors like [lang="en"] or [dir="ltr] (IE 7+) to target different languages.
Changing a theme based on language would be a subtask, but varying the skin is already supported by those selectors. It's the best approach out there says the W3C.

One difference between the two selectors we should take care of is possibility of fuzziness with attribute selector like outlined in examples with all possible language subtags ([lang|="zh"]) variations. Right now, I don't know if same is possible and completely supported by :lang pseudo-class.

Tgr added a comment.Jun 12 2015, 9:25 PM

A few comments about :lang:

  • it is fuzzy by default - :lang(zh) will select <span lang="zh-Hans">.
  • [lang|="zh"] is not a drop-in replacement for :lang(zh) - h2:lang(zh) will work, but h2[lang|="zh"] won't, you have to use [lang|="zh"] h2 (since the lang attribute is somewhere high in the DOM tree, on the body or the main content element). Not sure what impact that has on performance - use of the descendant selector together with generic selectors like tag or attribute is usually discouraged.
  • for most practical font-related purposes you would have to use a huge list of language codes (there are, for example, over 100 latin scripts, which would usually get the same styles). Those groups should clearly be in core so that they do not have to be replicated each time in the LESS code. (I don't think there is a good way to avoid replicating them in the generated CSS.)
Tgr added a comment.Jun 12 2015, 9:29 PM

The last point is nontrivial as there is not much support for generating selectors in LESS (you can use a string as a selector but you need to generate that string yourself). Something like

@latin: ":lang(en), :lang(de), ...";
h2 {
    &@{@latin} {
        /* font rules */

would work I guess, but it looks rather nasty.

Change 200940 had a related patch set uploaded (by Mjbmr):
Language based default font-family

Mjbmr set Security to None.Jun 13 2015, 1:01 AM
Mjbmr added a subscriber: Mjbmr.

"Latin" is very generic. For instance, Finnish and German are common Latin script languages, yet on the Lyon Hackathon badges the ö was not printed correctly. Sure, that was an encoding issue, not a font issue, but I don't think one can assume that any font good for English is also good for all the 1338 Latin characters.

Change 200940 abandoned by Mjbmr:
Language based default font-family

Restricted Application removed a subscriber: Mjbmr. · View Herald TranscriptJun 20 2015, 6:04 AM

Change 200940 restored by Mjbmr:
Language based default font-family

Krinkle triaged this task as Normal priority.Jul 13 2015, 3:00 PM
Krinkle moved this task from Inbox to Backlog on the MediaWiki-ResourceLoader board.

Change 200940 abandoned by Mjbmr:
Language based default font-family

Tgr added a comment.Jan 28 2016, 10:44 PM

Not necessarily the same thing. For example adding a style for all latin scripts is probably not something you'd want to do by enumerating them in the ResourceLoader configuration.

@Tgr: Agreed, but those use cases are imho not appropiate for module definitions. They seem like a perfect fit for run-time variables.

For LTR/RTL, and other larger groups, it's probably better served by adding this meta-data to the Language class and exposing that directly to stylesheets instead of varying the module definition itself by language meta-data. We already output html[lang=".."] and class="rtl". We could provide additional classes for other meta data groups, like class="lang-latin" or some such.

And instead of having two files with each 1 line of CSS as follows:

languageStyles => [ 'groupFoo' => 'foo.css', 'groupBar' => 'bar.css' ]

Instead you'd have

styles => 'example.css'


.lang-group-foo { a }
.lang-group-bar { b }

Similar to what we do for mw-content-ltr/rtl. Alternatively, if you're sure certain the use case only applies to user-interface language and not to content-language (meaning, you really only need one variant in the stylesheet at run time), then one could also Less by exposing the language meta data to Less variables and conditionally only outputting the relevant version.

This encourages related code to be in the same file instead of scattered across various files, and makes it easier to use specificity rules as intended within context of other rules.

it's probably better served by adding this meta-data to the Language class

How can the Language class know what weird things a skin might want to do with fonts?

Restricted Application added a project: Performance-Team. · View Herald TranscriptMay 26 2018, 6:24 PM
Legoktm reopened this task as Open.May 26 2018, 6:26 PM
Legoktm added subscribers: ashley, Legoktm.

I've re-duped the two tasks the other way - this one has way more relevant discussion on it.

Another feature that could use this is the capitalize-all-nouns feature in MonoBook, which only applies to German, and languages that fallback to it:

PerfektesChaos added a subscriber: PerfektesChaos.EditedMay 28 2018, 2:55 PM

Please note that the skin matters are probably a scripting problem rather than a language issue.

While many languages are usually written in one scripting, some have more:

  • Serbian sr is common as both sr-Latn and sr-Cyrl. Serbian Wikipedia is a strange merger of two scriptings in one language.
  • Transcriptions (romanisations) provide a latin variant of a non-latin generic language.
  • Chinese zh is nowadays written as simplified zh-Hans, or traditionally zh-Hant, and other CJK systems. However, zh-Latn is Pinyin, a latin transcription of Putonghua, or other romanisation.
  • Several countries south of the caucasus used arabic scripting, turned in the 1930’s into cyrillic under Soviet government and nowadays heading for a change to latin. All the same language and with equal rights.
  • Mongolian is written as Uigur, a vertical scripting, then arabic, under Soviet influence cyrillic, today widely chinese CJK, also latin transcription.

Our ULS suffers from the same fundamental error to derive one and only one particular font and scripting unconditionally from the basic language.

For CSS and skin issues the scripting is the core point. CJK and other ideographic, RTL ./. LTR, other asiatic, or any latin. Greek and cyrillic won’t differ much from latin. The language itself is not authoritative.

Scripting is standardized by ISO 15924 and coded by four letters. See: list of script names and codes

Please avoid individual things like -latin- in CSS context, but use standardized -Latn or at least -latn for systematic approach.

See also RFC 5646.

I'll try to look at the MonoBook use case.

Krinkle closed this task as Declined.Jul 3 2018, 12:18 AM

Declining for now. The use case for MonoBook is interesting, but I don't think it justifies the development and maintenance of an additional feature in ResourceLoader.

Its use case in a nut shell: There are anchor links in MonoBook's output HTML with an interface label that is stylistically preferred to be in lowercase (e.g. "my talkpage" not "My talkpage"). This design decision was implemented in MonoBook by using the style rule text-transform: lowercase; in its stylesheet.

That style rule subsequently caused problems as some of the German translations of those messages intentionally use (and linguistically require) an uppercase letter for the noun (e.g. "mein Diskussion"). This problem was solved by outputting an extra class on the <body> tag for German (and languages that use German as fallback) and an additional CSS rule that undoes this style using the style rule text-transform: none;.

I agree that the current code seems inefficient (in that it outputs two style rules instead of one, where the latter sometimes overrides the former), and I understand that moving it to a separate set of files that are conditionally loaded, would address that.

On the other hand, there are three other ways in which we can solve this that also address that - but without requiring the files to be split and without needing a feature that doesn't exist (languageStyles).

  1. Update the original non-German interface messages to be in lowercase and remove the CSS rules entirely. This is the approach usually taken in MediaWiki and also the most efficient in terms of code and complexity.
  1. Or; Apply the text transformation server-side instead of client-side, using the same conditional, an remove the CSS rules entirely. This avoids having duplicate style rules, and leaves us with only one conditional block - which would do exactly what MonoBook's design wants (lowercase the link labels outside German).
  1. Or: Adopt the :not() selector pattern in MonoBook CSS, which would apply the same styles as today, but without the need for the duplicate rule to undo the default styles. This selector is supported in all Grade A browsers, and most Grade C browsers. (Unsupported in only IE <= 8, Safari 3.0, and Firefox 3.0. Supported in IE 9+, Safari 3.2+, and Firefox 3.5+, and all other Grade C browsers.)
Tgr added a comment.Jul 3 2018, 9:12 AM

Its use case in a nut shell: There are anchor links in MonoBook's output HTML with an interface label that is stylistically preferred to be in lowercase (e.g. "my talkpage" not "My talkpage"). This design decision was implemented in MonoBook by using the style rule text-transform: lowercase; in its stylesheet.

So what about the non-fringe use case, which is supporting optimal font selection for non-latin scripts?

@Krinkle could ResourceLoaderLessVarFileModule be used here?

"monobook-transform-preference": "lowercase"

RL definition

'monobook.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
                'class' => ResourceLoaderLessVarFileModule::class,
                'lessMessages' => [
                'styles' => [


.myrule { text-decoration: @message-monobook-transform-preference; }