Page MenuHomePhabricator

Decide which non-standard CSS properties to support in TemplateStyles
Open, LowPublic

Description

wikimedia/css-sanitizer understands CSS 2/3/4 properties with a decent level of support but does not recognize most vendor-prefixed versions (which are sometimes necessary for compatibility).

Related Objects

Event Timeline

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

It is strange that Wikimedia code uses a lot of needed vendor prefixes, but in TemplateStyles they can’t be referenced. It is probably a good decision from the security side, but then you need to use a library like Autoprefixer that would add any needed prefixes for supported vendors for editors. I had, for example, to remove vendor prefix that provided support for user-select even to my browser (latest Firefox) because otherwise saving page with TemplateStyles was impossible.

Unfortunately Autoprefixer doesn't seem to have a PHP version.

Compiled a Browserlist rule for this based on available browser matrix for desktop and mobile:
last 2 chrome versions, last 2 firefox versions, edge >= 11, ie 11, opera > 15, safari >= 5.1, ios >= 6.1, android >= 4.1, and_chr >= 48

Then I used a file with all CSS properties and inserted it into online Autoprefixer tool with the parameters above. Comparing two files, these are the results that I got:

1-webkit-align-content: value;
2-webkit-box-align: value;
3-webkit-align-items: value;
4-webkit-align-self: value;
5-webkit-animation: value;
6-webkit-animation-delay: value;
7-webkit-animation-direction: value;
8-webkit-animation-duration: value;
9-webkit-animation-fill-mode: value;
10-webkit-animation-iteration-count: value;
11-webkit-animation-name: value;
12-webkit-animation-play-state: value;
13-webkit-animation-timing-function: value;
14-webkit-backface-visibility: value;
15-webkit-border-image: value;
16-webkit-box-decoration-break: value;
17-webkit-column-break-after: value;
18-webkit-column-break-before: value;
19-webkit-column-break-inside: value;
20-webkit-clip-path: value;
21-webkit-column-fill: value;
22-webkit-column-gap: value;
23-webkit-column-rule: value;
24-webkit-column-rule-color: value;
25-webkit-column-rule-style: value;
26-webkit-column-rule-width: value;
27-webkit-column-span: value;
28-webkit-columns: value;
29-webkit-column-count: value;
30-webkit-column-width: value;
31-webkit-filter: value;
32-webkit-flow-into: value;
33 -ms-flow-into: value;
34-webkit-flow-from: value;
35 -ms-flow-from: value;
36-webkit-box-flex: value;
37-webkit-flex: value;
38-webkit-flex-basis: value;
39-webkit-flex-grow: value;
40-webkit-flex-shrink: value;
41-webkit-box-orient: vertical;
42-webkit-box-direction: normal;
43-webkit-flex-flow: value;
44-webkit-flex-direction: value;
45-webkit-flex-wrap: value;
46-webkit-font-feature-settings: value;
47-webkit-font-kerning: value;
48-webkit-font-language-override: value;
49-webkit-font-variant-ligatures: value;
50-ms-grid-columns: value;
51-ms-grid-rows: value;
52-ms-grid-column: value;
53-ms-grid-row: value;
54-webkit-hyphens: value;
55-ms-hyphens: value;
56-webkit-box-pack: value;
57-webkit-justify-content: value;
58-ms-grid-column-align: value;
59-webkit-mask: value;
60-webkit-mask-image: value;
61-webkit-mask-repeat: value;
62-webkit-mask-position: value;
63-webkit-mask-clip: value;
64-webkit-mask-origin: value;
65-webkit-mask-size: value;
66-webkit-box-ordinal-group: value;
67-webkit-order: value;
68-webkit-perspective: value;
69-webkit-perspective-origin: value;
70-webkit-region-fragment: value;
71 -ms-region-fragment: value;
72-webkit-scroll-snap-coordinate: value;
73 -ms-scroll-snap-coordinate: value;
74-webkit-scroll-snap-destination: value;
75 -ms-scroll-snap-destination: value;
76-webkit-scroll-snap-points-x: value;
77 -ms-scroll-snap-points-x: value;
78-webkit-scroll-snap-points-y: value;
79 -ms-scroll-snap-points-y: value;
80-webkit-scroll-snap-type: value;
81 -ms-scroll-snap-type: value;
82-webkit-shape-image-threshold: value;
83-webkit-shape-margin: value;
84-webkit-shape-outside: value;
85-moz-tab-size: value;
86-webkit-text-decoration: value;
87-webkit-text-decoration-color: value;
88-webkit-text-decoration-line: value;
89-webkit-text-decoration-style: value;
90-webkit-text-decoration-skip: value;
91-webkit-text-emphasis: value;
92-webkit-text-emphasis-color: value;
93-webkit-text-emphasis-style: value;
94-webkit-text-emphasis-position: value;
95-webkit-text-size-adjust: value;
96-ms-text-spacing: value;
97-webkit-transform: value;
98-webkit-transform-origin: value;
99-webkit-transform-style: value;
100-webkit-transition: value;
101-webkit-transition-delay: value;
102-webkit-transition-duration: value;
103-webkit-transition-property: value;
104-webkit-transition-timing-function: value;
105-webkit-writing-mode: value;
106 -ms-writing-mode: value;

Don’t know which are not supported in TemplateStyles, I opted to check all of them. If my browser matrix is wrong, you can probably edit it to get it right.

Out of my personal experience in working with TemplateStyles, having flexbox prefixed properties supported as soon as possible is probably the most crucial out of this. column-width/column-count, too, because column layouts are used in Wikimedia sites’ CSS frequently. Hope this helps in fixing this, this is probably the most noticeable hurdle in working with TemplateStyles for me at the moment.

Edit: noticed that I accidentally inserted ios >= 5.0 instead of ios >= 6.1. Would have to redo this, the list would probably be smaller. Update: nothing changed.

For anyone that will decide to do this task: we got consensus in the Russian Wikipedia to improve the main page using TemplateStyles, and the ability to use prefixed CSS properties would be more than welcome addition to see. Right now I intend to add prefixed properties only directly to Common.css/Mobile.css before pushing new version, which would be less than ideal.

I typed this a while ago, but never hit the submit button. It seems phabricator remembered the comment, and since the issue is still current I'll post it now.

@stjn just on an unrelated note caniuse analytics show that support for prefixed vs. unprefixed flexbox properties is nearly an identical audience. Browsers supporting neither is a much larger group. The amount of bugs and browser diversity with unprefixed flexbox is also rather large. As such I think any time is better spent on having good fallbacks using float/inline-boxes (Which should NOT necessarily have to look the same, just be readable and accessible) being actually much more important.

While initially I figured it was unmanageable to not support prefixes, I have since sort of changed my mind and have not run into situations where this seemed to be an actual real world problem that I have to care about it. This does not mean it cannot be a problem, just that the severity and frequency of it seems much reduced to my initial assessment.

We don’t support browsers supporting neither, so there’s no need to care about that (they can just display one-column layout after all in case of Russian Wikipedia). Bugs with flexbox are also manageable and mostly are concerning older IEs, I don’t see how this is an argument against using it.

The main audience for which flexbox prefxies are needed is older iPads, to be honest.

Change 436338 had a related patch set uploaded (by Anomie; owner: Anomie):
[css-sanitizer@master] WIP: Support vendor prefixes

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

I drafted a patch for allowing vendor prefixes. It still needs work (as noted in the commit summary), and I'm not entirely happy with it but going further would be even more complex.

The main audience for which flexbox prefxies are needed is older iPads, to be honest.

Which i find a strange reason, i dont see why such ipads would be more important than IE7...

Apparently there's a Compatiblity living standard for vendor prefixes which everyone should support. It's a WHATWG spec so not easy to judge how established it is, but it has been around since 2015, at least.

I note that's for what browsers need to support never-updated websites rather than vice versa. It includes things like -webkit-linear-gradient() which https://caniuse.com/#search=linear-gradient reports hasn't been needed for any browser released in the past 5 years.

As part of T228604, ran into several things using zoom: 1; which is preventing me from saving the edit in an AbuseFilter-like fashion.

Is there a path forward here to start whitelisting a bare minimum of known totally safe property/value pairs so as to avoid blocking adoption of TemplateStyles and/or requiring clever hacks where part of the styles stay behind in Common.css (which then causes the cascade to be out of sync, and also mis-matching selectors given auto-wrapping of selectors).

Sure, can you propose such a whitelist?

Sure, can you propose such a whitelist?

  • zoom: 1

:-)

Alternatively, zoom: 1 can be dropped from every codebase since it’s a property that does something in IE5-7, browsers that should be used by absolutely no one in 2019.

Unfortunately Autoprefixer doesn't seem to have a PHP version.

Yes, Autoprefixer is Not Available For Php but you can try Python Autoprefixer

Unfortunately Autoprefixer doesn't seem to have a PHP version.

Yes, Autoprefixer is Not Available For Php but you can try Python Autoprefixer

A python version is no more usable within a PHP MediaWiki extension than a nodejs version is.

Theoretically, Autoprefixer just uses Caniuse data to match it with a required set of browsers, so it might be possible to use it in the same way (raw Caniuse data is just a lot of JSON) but in PHP. The esteemed Somebody Else would have to port the code in the first link to css-sanitizer, however, and keep up with development of Autoprefixer in the future (the latter is easier than the former).

Until we can gradually start adding known safe exceptions to the standard syntax, I'm marking this as perf recommendation because it blocks adoption of TemplateStyles.

Arthur2e5 subscribed.

The autoprefixer thing using caniuse looks good. -webkit-text-emphasis is especially a pain in the alias for Chinese/Japanese, as 71% of global users only get support via this prefixed version. Chrome, ya know.

@stjn Someone is going to need to get a CSS parser for PHP to do it, and it sounds like hard work. Maybe someone else can try some interprocess stuff if shell calls are deemed too expensive? (Or is caching enough to justify shelling?)

@Tgr the compatibility stuff is for browsers, not for us. Just because browsers support them doesn't mean we should encourage their use. We are supposed to only use prefixes when a majority of users are stuck with a browser that only supports them, not when writing code for input. It would be actually good to yell at users for using prefixes when we have autoprefixer later.

I thought that the main (or only) reason for sanitization and allow-listing declarations, is security. Thus any vendor-prefixed rule known to be used by notable browsers, useful for end-users, and with no known security risk, seems trivial to add one-off in individual tasks and patches.

Is this task intended to block that in favour of a generalized solution? Or is this a nice-to-have long term exploration? I'm not sure a how a generalized solution could work or exist, but maybe there's a spec or trusted source that I'm not aware of. Or maybe there's a limitation, cost or concern with the current code that makes it not feasible to add these rules individually?

As a user on wiki, I'm personally torn about allowing vendor prefixes in the general (or was it decided somewhere we should?). On one hand, it would be nice to be more slick (and there is at least one other point above about mixed solutions).

OTOH, some reasons I'm not a fan of vendor prefixes:

  • I'm still going to be conservative in what I author on wiki (and really, what looks usable is already figured out). Maybe that's just me and others want to forge ahead.
    • Corollary to "maybe": As a gnome, I don't really want to clean out unnecessary prefixes a decade down the road.
  • Anything that relies on a vendor prefix probably has a graceful default fallback already anyway (maybe Grid excepted, in the current list of CSS; maybe there's something someone can sell me on that's bigger). We're kind of at a point on diminishing returns for new CSS (beside the JavaScript being dragged into CSS and a lot of that ends up on the ban list anyway because calc and friends).
  • Not really a fan of increasing the HTML payload just to handle the vendor solutions, as compressed as it might be.

Is this task intended to block that in favour of a generalized solution? Or is this a nice-to-have long term exploration? I'm not sure a how a generalized solution could work or exist, but maybe there's a spec or trusted source that I'm not aware of. Or maybe there's a limitation, cost or concern with the current code that makes it not feasible to add these rules individually?

There is a subset of prefixed properties (called ‘legacy name aliases’ officially if I am not mistaken) that actually made it into spec:
https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions#Formerly_proprietary_properties_that_are_now_standard

I don’t know how well the list corresponds with the one compiled by me before, but that is one pointer about this. Every browser has to support those -webkit-/-epub- prefixes now, theoretically.

This comment was removed by Aklapper.

Change 436338 abandoned by Umherirrender:

[css-sanitizer@master] WIP: Support vendor prefixes

Reason:

Old outdated patch set

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

Another point of failure: Webkit/Blink-based browsers do not support box-decoration-break without a prefix, but do support -webkit-box-decoration-break. I cannot use them both in TemplateStyles together, so the only solution is to put inline styles while that is still a problem. Maybe let’s just allow to use prefixed properties that match allowed properties to bring this a bit forward?

See https://ru.wikipedia.org/?diff=131066838