Page MenuHomePhabricator

It should be easier for a skin to add classes to the body
Closed, ResolvedPublic

Description

A skin can currently add classes to the body or HTML element by the following methods:

  • Overriding the class property in the array returned by Skin::getHtmlElementAttributes
  • The OutputPageBodyAttributes hook.

Both methods are called within OutputPage::headElement

Looking at existing usages of getHtmlElementAttributes we see skins use it for no reason whatsoever (BlueSpiceCalumma) or to add classes to the HTML element (Vector, LiquiFlow). In the latter case, both classes could easily be added to the body tag instead.

The OutputPageBodyAttributes hook is more frequently used.

Some skins, provide their own static body classes. e.g. Apex and Astra (currently via JavaScript)

TODO

- [] Update Vector to use the OutputPageBodyAttributes to conditionally add the sticky header class (good reasons to still use HTML tag)
- [] We hard deprecate Skin::getHtmlElementAttributes and move functionality into OutputPage. (good reasons to still use HTML tag)

  • Allow skins to define a skin option bodyClasses at skin registration.

e.g.

"ValidSkinNames": {
               "vector": {
                       "class": "SkinVector",
                       "@args": "See SkinVector::__construct for more detail.",
                       "args": [
                               {
                                       "name": "vector",
                                      "bodyClasses": [ "skin-vector-legacy" ],
  • Update Vector skin to showcase its usage.

Event Timeline

Jdlrobson renamed this task from It should be easier for a skin add classes to the body and HTML tag to It should be easier for a skin add classes to the body and we should deprecate modifications to the HTML tag.Jan 6 2022, 9:14 PM
Jdlrobson triaged this task as High priority.
Ammarpad renamed this task from It should be easier for a skin add classes to the body and we should deprecate modifications to the HTML tag to It should be easier for a skin to add classes to the body and we should deprecate modifications to the HTML tag.Jan 7 2022, 6:28 AM
Ammarpad subscribed.

Change 753560 had a related patch set uploaded (by Jdlrobson; author: Jdlrobson):

[mediawiki/core@master] Skins can define bodyClasses at skin registration

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

@Jdlrobson Please note that some classes may not work on the body tag and require to be added to the html tag in order to function. For example, the .vector-sticky-header-enabled [1] which applies scroll padding to account for the sticky header in Vector does not work when applied to the body tag in Chrome, Safari, and possibly other browsers

[1] https://github.com/wikimedia/Vector/blob/467283247c2e04a55cd42e1337a9c04bc060a74d/includes/SkinVector.php#L497

Interesting. Do you think that could be generalized in any way for all skins? Perhaps htmlClasses property would also be useful.

htmlClasses/bodyClasses in skin.json would work for static classes that are not conditional, but I wonder how one would add classes that are based on conditions (e.g. the .vector-sticky-header-enabled class should only be added if the sticky header feature is enabled)

My feeling around this is that the conditional classes can be served in the future by a generic feature management system described in T242835.

Given the sticky header is JavaScript only, we might want to add the class via JavaScript.
If we ever make the sticky header enabled for all users, then the class would be defined statically, right?

Ah okay, if a feature manager were responsible for conditional classes I guess that could work.

The sticky header class is a bit of an edge case because even though the sticky header is JS only, the scroll padding class actually has to be server rendered to account for navigating directly to a page with a hash fragment (e.g. https://en.wikipedia.beta.wmflabs.org/wiki/Dog#Bibliography) [1]. If the class were added via JS, the browser could already have scrolled to the incorrect position by the time the JS executes.

Yes, if the sticky header is enabled for all users, that class could be static (but it would still need to be server rendered).

[1] https://github.com/wikimedia/Vector/blob/699579e646ba2f0a2b7d234ec9ccf0fdd71cab3d/includes/SkinVector.php#L490-L496

Change 753560 merged by jenkins-bot:

[mediawiki/core@master] Skins can define bodyClasses at skin registration

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

Jdlrobson renamed this task from It should be easier for a skin to add classes to the body and we should deprecate modifications to the HTML tag to It should be easier for a skin to add classes to the body.Feb 4 2022, 4:08 PM
Jdlrobson updated the task description. (Show Details)

Given the sticky header needs to add scroll padding to root element there seems to be legitimate uses for updating the HTML tag so let's retain that. Hopefully the bodyClasses will provide an attractive alternative for skin developers who don't want to deal with hooks.

Change 759730 merged by jenkins-bot:

[mediawiki/skins/Vector@master] Use bodyClasses option to register static classes on skin

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