Requests for comment/Allow styling in templates

Request for comment (RFC)
Allow styling in templates
Component General
Creation date
Author(s) Jon Robson
Document status implemented
See Phabricator.

Current status edit

The rudimentary "proof of concept" patch was abandoned and we[who?] welcome someone new to take this over.

(2014-10-15) Brion is interested in taking this RfC over and getting a provisional implementation done. Style scoping is a potential security issue here, needs a little more thought put into it.

  • RfC provisionally accepted 2014-10-15, implementation plan:
    • Brion: syntax & general implementation
    • Tim: CSS preprocessor to force the scoping

Background edit

Currently the MediaWiki markup allows the inclusion of html elements with style attributes. Mixing layout with content causes various problems with reusability, maintainability and is not future proof. Already on the mobile version of MediaWiki problems are being seen with inline styles with how pages render on smaller screens which could be solved via css3 media queries, however these cannot be done in inline styles.

It should be possible for templates to have associated stylesheets so that media queries can be applied where necessary. This is related to bugzilla:35704.

A proof of concept can be found here: https://gerrit.wikimedia.org/r/68123

Problem edit

In terms of how separating styles into stylesheets will help things out on mobile fundamentally it allows you to use media queries. Thus you can do radically different things such as have a 2 column layout on a desktop browser but have a 1 column layout on mobile. For instance in this code snippet:

@media all and (min-width: 600px) {
	.leftPane { width: 300px; float: left; }
	.rightPane { width: 300px; float: right; }
}

This means if the screen is smaller than 600px then none of these css rules will apply. On a screen of 320px such a style introduced via inline style would be broken (and you cannot do media queries in a style attribute).

Various rendering issues on mobile are caused by the existence of inline styles which do not degrade. See bug 35704.

Challenges edit

  • Templates could use conflicting CSS names causing incompatibilities between templates
    • This is seen as a good thing as it leads to better template maintenance and promotes reuse and collaboration
      • However, there is a difference between factoring out code cleanly (a CSS library) and one template mysteriously relying on another's styles (possibly in a totally undocumented way). Superm401 - Talk 23:12, 16 September 2013 (UTC)[reply]
        • Actually assuming a CSS base that defines common styles that all subsequent stylesheets can rely on is a good pattern going forward. To be clear, what I am describing is a 1 level dependency on CSS, not "n" levels.That is, the base styles are well defined and applied to common elements. They do not define styles of features. By definition the "base layer" is small and namespaced to prevent conflicts. NRuiz (WMF) (talk) 10:13, 26 March 2014 (UTC)[reply]
  • CSS rules within templates could be applied to UI chrome
    • This can be resolved by using scoped style tags that only apply styles to the template itself (or potentially a part of it) - scoped styles is currently a W3C candidate recommendation
    • For older browsers that do not support scoped CSS there is a JavaScript shim
      • For browsers that do not support JavaScript there is a danger that CSS could leak outside templates. It is decided that this in acceptable tradeoff
        • with LESS support and some work we could fallback to scoping the stylesheet to #bodyContent to at least prevent spillage into the UI
      • It is better (IMO) to add a restrictive selector to each rule during the CSS sanitization process; this works on both old and new browsers and doesn't require a JS client-side shim. cscott (talk) 21:11, 15 October 2015 (UTC)[reply]
  • Balanced and unbalanced templates could lead to styles leaking to places that they shouldn't
    • It is proposed that by allowing template designers to add style tags in the wikitext itself this gives them control to ensure they are applied correctly. For example, a top template would have
      <div><style scoped>styles here</style>
      tag, and a bottom template would have
      </div>
      (and thus close the <style scoped> tag's applicability). This is basically a logical conclusion of how unbalanced templates work now.
    • Styles "leaking out" of templates is exactly the point of this -- {{Mediawiki.css}} should affect the article content. But that's fine WRT incremental page update, because the "leakage" happens in the browser, <style> doesn't leak out of the DOM.cscott (talk) 21:11, 15 October 2015 (UTC)[reply]
  • What about templates that are used multiple times in a page?
    • This can lead to CSS duplication.
      • It is suggested that a template that is used multiple times on a page probably should still make use of inline styles or Common.css so this might not be a problem that should be worried about.
      • Since styles are scoped, you will *need* to duplicate the <style scoped> tag in order to apply the same styles to a different part of the page. This is "as designed". You need something more like ResourceLoader if you want to encapsulate the styles differently. cscott (talk) 21:11, 15 October 2015 (UTC)[reply]

Implementation details edit

  • If a style tag is not inserted with the scoped attribute the styles do not get applied to the page and shows up HTML-encoded (the same as any HTML tag that is not allowed).

Proposal edit

First pass:

  • Allow STYLE tags inside template pages.
    • Where multiple versions of the same template are added on the same page ensure only one instance of the style tag is included.
    • Templates can simply contain style tag
    • Templates containing simply style tags can be transcluded and shared between commonly used templates
    • Use media queries in problematic templates to improve their rendering on mobile.

Note: This involves fiddling with the parser which is extremely nasty :(

  • Fiddling with the parser is the wrong way to do this IMO. What you want to do is implement <style> as an extension tag. That handles all the parsing for you, and hands your extension the big block of CSS styles rules. Your extension would then be mostly concerned with sanitizing the CSS styles. cscott (talk) 21:14, 15 October 2015 (UTC)[reply]

Second pass:

  • Explore templates with suffix .css being allowed to contain just pure CSS.
    • This option could be interesting for all pages, not just templates (think Main Page)

Third pass:

  • Deprecate inline styles
    • This will break cases where CSS is built from parser functions/lua .css(); no more dynamic styling.
  • Move template rules inside MediaWiki:Common.css rules to templates themselves

Examples edit

Use cases edit

See also edit