Page MenuHomePhabricator

RfC: Allow styling in templates
Closed, ResolvedPublic40 Estimated Story Points

Assigned To
Authored By
Qgil
Sep 25 2014, 11:39 AM
Referenced Files
None
Tokens
"Like" token, awarded by IKhitron."Like" token, awarded by Sophivorus."Mountain of Wealth" token, awarded by RandomDSdevel."Like" token, awarded by Liuxinyu970226."Like" token, awarded by MartinK."Like" token, awarded by JMinor."Mountain of Wealth" token, awarded by John_Cummings."Yellow Medal" token, awarded by Enterprisey."Barnstar" token, awarded by Jdforrester-WMF.

Description

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 T37704.

This RFC was proposed in 2013, discussed at two separate RFC meetings in 2014, and the status is unclear as of 2016-03-29. More detailed status in the comments of this task

Full writeup:
Allow styling in templates RfC.

Related Objects

StatusSubtypeAssignedTask
DeclinedNone
ResolvedJdlrobson
DeclinedNone
DuplicateNone
ResolvedJdlrobson
DuplicateNone
DuplicateNone
DeclinedNone
ResolvedJdlrobson
DuplicateNone
DuplicateNone
ResolvedNone
OpenNone
OpenNone
ResolvedTheDJ
DeclinedNone
InvalidNone
OpenFeatureNone
InvalidNone
ResolvedTheDJ
ResolvedTheDJ
InvalidNone
ResolvedIzno
ResolvedTheDJ
OpenNone
ResolvedJdlrobson
Openovasileva
DeclinedNone
ResolvedTgr
Resolvedcoren
ResolvedAnomie

Event Timeline

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

With the latest rounds of merges, the TemplateStyles extension appears to be in a reasonable state and implements the major substantive part of this RfC as discussed in Jerusalem.

An interesting side effect of the current implementation is that a <templatestyles> tag appearing on a page not appearing in the list of allowed namespaces will not - as designed - affect pages transcluding it but it does style itself regardless of namespace.

I'm not sure that shouldn't simply be documented as a feature. :-)

Note that people do like to use templates outside the template NS, for user or project pages for instance. Not sure if we want to support that explicitly/implicitly/not at all, etc. :)

In T483#2232314, @brion wrote:

Note that people do like to use templates outside the template NS, for user or project pages for instance. Not sure if we want to support that explicitly/implicitly/not at all, etc. :)

It's supported via $wgTemplateStylesNamespaces; whether that is left to just Template: or not when that gets deployed to prod seems to me to be a decision best left to the individual communities.

It seems like an unnecessary burden on users to figure out why it didn't work and ask their communities for permission to change, on communities to deal with the question, and on wmf releng to handle updating the setting.

What downside is there to just having it always on everywhere?

In T483#2232450, @brion wrote:

on communities to deal with the question, and on wmf releng to handle updating the setting.

I don't know if you've been watching Wikimedia-Site-requests lately but the credit for handling that process really should go to the volunteers involved.

If volunteers are +2'ing config updates and deploying them, I'm impressed. :)

In T483#2232623, @brion wrote:

If volunteers are +2'ing config updates and deploying them, I'm impressed. :)

Regardless, it is probably worthwhile to ask what the communities around templates think before we figure it out - at least on the bigger projects. Ima do this this week.

I was thinking a bit about variance, maintainability etc. And in the mobile-friendly content meeting we were also discussing: How do we document this so that editors know what they should do ?

Lets say we have a block like:

@media print and (min-width: 480px)

How do we make sure that not every single template has a different cutoff width and thus triggers a reflow? In every single language ?

This made me realize: We need to make this a less sheet and MediaWiki/Wikimedia should have a centralized less sheet with predefined variables, functions/mixins etc. We could properly document those variables and functions and use them in our examples. We could put complicated CSS magic in descriptively named functions/variables, so that people don't have to understand all the CSS details, they can just be "in this situation i need to use this function".

This would make templatestyles a lot more maintainable and consistent, still give lot's of flexibility to editors and also allow us to make changes from the MediaWiki/Wikimedia side.

Adding the parsing team, as this would introduce page-global state, and also needs to work in Parsoid and VE.

Adding the parsing team, as this would introduce page-global state, and also needs to work in Parsoid and VE.

I've been pondering on that issue for a bit; clearly there needs to be an API endpoint for parsoid to hit - but I'm not certain what data would be most useful to return; would the final "merged" stylesheet be apropriate?

@coren: When implemented as proposed here, Parsoid and VisualEditor both would need to reimplement the same logic independently. Additionally, any application composing content on the client would need to implement similar aggregation passes, which would make our content a lot less modular than desirable.

There are alternatives that don't suffer from this issue:

Inline stylesheets

All modern browsers support <link rel="stylesheet"> in the body. While this was not sanctioned by the HTML4 spec, it has recently been allowed in the HTML5 spec. Chrome is explicitly working on further improvements in how it handles rendering of such styles. Among other things, the technique is used to speed up time to first paint by deferring the loading of below-fold CSS until it is needed.

While this could be used to pull in external styles, that would add some network requests. However, the styles we are talking about here should be fairly small, so inlining them would be preferable. This can be done using data URLs like this (tested in Chrome and Firefox, JSFiddle):

<body>
    <div id="mw12345">
        <link rel="stylesheet"
        href="data:text/css;base64,I213MTIzNDUgeyBjb2xvcjogcmVkIH0=">
        This text is styled red.
    </div>
</body>

This solves the primary issue of avoiding global state, but still requires styles to be explicitly prefixed to enforce scoping, for example by prefixing CSS selectors as in this example: #mw12345 { color: red }.

Shadow DOM

The Shadow DOM spec is aiming to fully encapsulate styling and DOM behavior of components. It is pushed by Google & others as the successor to <style scoped>. In recent months the spec has been shaping up quickly, but I expect it to still take some time until implementations are consistent enough & polyfills have caught up.

In summary, we might be able to leverage Shadow DOM for cleaner style isolation in the future, but for now inline stylesheets with selector prefixing should get us what we need while keeping page components self-contained.

All modern browsers support <link rel="stylesheet"> in the body

It's not immediately clear to me what the fundamental difference is between that and the current scheme (a <style> tag in the header)?

It's not immediately clear to me what the fundamental difference is between that and the current scheme (a <style> tag in the header)?

The <style> tag in the header requires a page-global aggregation pass to collect styles, which would need to be implemented in the PHP parser, Parsoid, VisualEditor, and any other application composing wiki content (such as apps).

The inline stylesheet on the other hand keeps each template expansion self-contained, and avoids the complexity of global passes. It is both easier to implement, and easier to consume.

In T483#2289858, @TheDJ wrote:

I was thinking a bit about variance, maintainability etc. And in the mobile-friendly content meeting we were also discussing: How do we document this so that editors know what they should do ?

Lets say we have a block like:

@media print and (min-width: 480px)

How do we make sure that not every single template has a different cutoff width and thus triggers a reflow? In every single language ?

This made me realize: We need to make this a less sheet and MediaWiki/Wikimedia should have a centralized less sheet with predefined variables, functions/mixins etc. We could properly document those variables and functions and use them in our examples. We could put complicated CSS magic in descriptively named functions/variables, so that people don't have to understand all the CSS details, they can just be "in this situation i need to use this function".

This would make templatestyles a lot more maintainable and consistent, still give lot's of flexibility to editors and also allow us to make changes from the MediaWiki/Wikimedia side.

👍 This seems very reasonable to me. From user experience _and_ developer perspective it makes sense to choose the media query breakpoints wisely and provide them in a central stylesheet. Less and future CSS offers this capability!

href="data:text/css;base64,I213MTIzNDUgeyBjb2xvcjogcmVkIH0=">

Just as side-note: Why would you base64 text? That might result in more data over the wire –after gzipping– like with SVGs laid out here.

Just as side-note: Why would you base64 text? That might result in more data over the wire –after gzipping– like with SVGs laid out here.

Good point! The following seems to work just as well:

<div id="mw12345">
  <link rel="stylesheet"
    href="data:text/css,#mw12345 { color: red }">
  This text is styled red.
</div>

The main limitation with data URLs is limited support in IE8. Only IE9+ supports stylesheets in data URLs. If we care about IE8, then we could create some JS for a read-only fix-up. VisualEditor does not support IE8, so there is no need to support the more complex editing scenarios.

We do care about IE 8, and even IE 6, as allowing users to view the site with correct styling is a basic core feature of MediaWiki, and therefore we should strive to support grade C browsers here. See https://www.mediawiki.org/wiki/Compatibility#Basic for details.

@GWicke Are you suggesting that we duplicate the template stylesheet for every template invocation? That's crazy, and it would be literally the opposite of what this feature is being developed for.

@matmarex, do you expect a drastic increase in the size of the CSS associated with templates? If anything, being able to migrate some inline styles to rules should reduce CSS size somewhat, and compression would pick up repetitions & avoid a significant impact on download sizes.

Less styles in the <head> can also unblock rendering of above-fold content more quickly, which matters especially on mobile (see T124966).

In any case, I would expect very frequently used transclusions like cite to still be predominantly styled globally. Changing some linked / global CSS is a lot cheaper than re-rendering all of Wikipedia to update a detail in citation styling.

We do care about IE 8, and even IE 6

The read-only JS fix for IE8 would work in earlier IE versions as well.

We do care about IE 8, and even IE 6, as allowing users to view the site with correct styling is a basic core feature of MediaWiki, and therefore we should strive to support grade C browsers here. See https://www.mediawiki.org/wiki/Compatibility#Basic for details.

I'm not sure about this requirement. Right now we are just talking about template styles. Would it be a travesty if these styles didn't apply but an IE6 browser could still use the content? If we were talking about disabling skin styles I would understand but an unstyled infobox is not the end of the world.

Hi @coren. We're looking at goal options for Reading Infrastructure in Q1 FY 2016-2017.

The question arose: is the following something that's still relevant and that you were thinking to pursue?

Safety/security notes:

  • need to parse/validate CSS rules for safety anyway -- avoid external refs, scary things
    • probably have to do a 'real' CSS parse rather than blacklisting a few keywords like we do on inline styles
    • doing this reliably may be the hardest part!

@coren, if it's not on your list (yet still in scope), we were thinking this might be something Reading Infrastructure could work on starting July 2016. If it's already on your list, we would consider a different Reading Infrastructure goal for Q1 FY 2016-2017.

CC @JKatzWMF, @Tgr, @Anomie

In T483#2239190, @coren wrote:

Regardless, it is probably worthwhile to ask what the communities around templates think before we figure it out - at least on the bigger projects. Ima do this this week.

Is there any follow-up to this? I agree with Brion that restricting TemplateStyles to the Template namespace seems unnecessary. I'm pretty wary of global configuration variables, so if we can kill $wgTemplateStylesNamespaces, I think that's a win.

It's not immediately clear to me what the fundamental difference is between that and the current scheme (a <style> tag in the header)?

The <style> tag in the header requires a page-global aggregation pass to collect styles, which would need to be implemented in the PHP parser, Parsoid, VisualEditor, and any other application composing wiki content (such as apps).

The inline stylesheet on the other hand keeps each template expansion self-contained, and avoids the complexity of global passes. It is both easier to implement, and easier to consume.

I looked at T124966 a bit recently. The TemplateStyles extension is scheduled for a security review the week of May 30, according to T133408#2281285. Do you think your implementation concerns are hard blockers to deploying the TemplateStyles extension to Wikimedia wikis in the next few months?

In T483#2289858, @TheDJ wrote:

This made me realize: We need to make this a less sheet and MediaWiki/Wikimedia should have a centralized less sheet with predefined variables, functions/mixins etc. We could properly document those variables and functions and use them in our examples. We could put complicated CSS magic in descriptively named functions/variables, so that people don't have to understand all the CSS details, they can just be "in this situation i need to use this function".

It's funny, when I was skimming T133408 and starting to consider the various security concerns, one thought I had was "thank God we're not trying to start with a CSS preprocessor, variables and functions and a whole embedded programming language would make this crazy difficult to review." If we get really comfortable with being able to fully sanitize CSS output, I suppose adding a preprocessor wouldn't be totally insane. You'd still need to either do the processing client-side in JavaScript or do sandboxing server-side, the latter being similar to how we deal with embedded Lua, I believe.

I don't think we need to block the deployment of TemplateStyles over preprocessor support, though. Support for a preprocessor would probably happen in this extension at around the same time or after it happens for MediaWiki core (cf. T56864).

I'm hoping to find some time to play around with TemplateStyles this week. I'm curious whether features such as url() will be totally banned or only banned for non-Wikimedia domains. If we're going to disallow certain kinds of CSS (i.e., if we're only going to allow a subset of CSS), we'll want to make sure that the documentation and user interface both make this clear early and often to prevent headaches and frustration.

I'm hoping to find some time to play around with TemplateStyles this week. I'm curious whether features such as url() will be totally banned or only banned for non-Wikimedia domains. If we're going to disallow certain kinds of CSS (i.e., if we're only going to allow a subset of CSS), we'll want to make sure that the documentation and user interface both make this clear early and often to prevent headaches and frustration.

I presume that anything banned inline is banned in TemplateStyles as well, as they are both 'public access' so to speak. What would be cool is to have some directive to import stylesheets from MediaWiki: space, where CSS is unrestricted.

This comment was removed by IKhitron.

Once T133410: Deploy TemplateStyles to WMF production is done, then the exact functionality this task has requested will be in production. So, functionally, this task is a duplicate of that task, which is in process right now.

To be less confusing, let's make this a sub-task instead.

Nevertheless, it can be closed. The RfC was accepted and the feature implemented, reviewed and deployed; nothing actionable left in this task.