[css-images][svg2] gradient rendering and the image-rendering property

A discussion at the joint SVG/CSS face-to-face meeting centered on gradient
quality, and whether features such as dithering could be supported (or
required) to address banding in gradients.

I brought up that there are already cross-browser inconsistencies in
whether colors are anti-aliased when gradients have sharp transitions
(color stops at the same offset value to create stripes), and pointed out
that anti-aliasing looks better on diagonal stripes but can look fuzzy on
horizontal/vertical stripes.  Someone suggested I write up a proposal.  I
initially avoided an action, but after discussion moved on I realized that
this is essentially the same issue as the image-rendering properties:
sometimes you want smooth interpolation, and sometimes you want crisp edges.

So, the basic proposal is as follows: make the image-rendering property
apply to gradient images, including CSS and SVG gradients for an element.
Add the proposed "smooth" value to distinguish from "auto", and make the
definitions for each value as follows:

auto <https://drafts.csswg.org/css-images-3/#valdef-image-rendering-auto>The
image or gradient should be rendered with an algorithm that balances a
smooth appearance with performance.smoothThe image or gradient should be
rendered in such a way that pixilation effects are minimized. In
particular, image scaling should smoothly interpolate color transitions,
such as by using bilinear interpolation. This is intended for images such
as photos.  Gradient rendering should use anti-aliasing on sharp color
transitions and may use dithering or similar effects to minimize banding
when the color depth of the display cannot create an even color transition.
crisp-edges
<https://drafts.csswg.org/css-images-3/#valdef-image-rendering-crisp-edges>The
image or gradient should be rendered in a way that preserves contrast and
edges in the image.  Images should be scaled with algorithms that do not
smooth colors or introduce blur to the image in the process. This is
intended for images such as pixel art.  Gradient rendering may (or should?)
nonetheless use anti-aliasing to create clean diagonal lines.pixelated
<https://drafts.csswg.org/css-images-3/#valdef-image-rendering-pixelated>Images
must be scaled with the "nearest neighbor" or similar algorithm, to
preserve a "pixelated" look as the image changes in size. Gradients should
not use anti-aliasing or dithering.

Some additional complications:

   - For SVG paint servers, should the value in effect on the paint server
   element be used, or the value in effect on the painted shape?  I think
   consistency with other *-rendering properties (e.g. for color) is to use
   the value on the gradient element itself.  Alternatively, the "auto"
   behavior on a shape could be to use the behavior on the gradient, but a
   different value on the shape could override it.
   - Should you be able to set different rendering hints on different
   layers of CSS backgrounds (e.g. to have a smooth gradient overtop of a
   crisp-edges stripe)?  E.g., with a background-image-rendering property that
   takes a list of values?  If so, probably also want to introduce equivalent
   properties for layered SVG fill and stroke paint.

   - For existing SVG content, there may be backwards compatibility
   issues.  E.g., if image-rendering is set on the <svg> element itself with
   the expectation that it would only affect <image> elements, but now it also
   affects gradients.  Not sure if this would break anything badly.

If people are worried about backwards compatibility, an alternative would
be to create a distinct `gradient-rendering` property.  If so, I would want
`gradient-rendering` to use the same values as `image-rendering` as
described above, so authors would only have to memorize one set of keywords.

~Amelia Bellamy-Royds

Received on Wednesday, 3 February 2016 03:11:35 UTC