CSS Gradient Proposal

This is a proposal for adding simple linear gradients to CSS. It could be added as a separate module or it could be split up and added to the appropriate component modules. It makes use of the 'background-color' and 'background-attachment' properties from the Backgrounds module and extends that module with the 'background-gradient' property. It makes use of the 'border-*-color' properties from the Borders module and extends it with four 'border-*-gradient' properties and a 'border-gradient' shortcut. It makes use of the 'color' property from the Color module and extends it with the 'gradient' and 'gradient-attachment' properties. It makes use of the 'outline-color' property from the Basic UI module and extends that module with an 'outline-gradient' property.

Issues to be settled

Issue 1: A separate layer or not?

One question to be decided is when doing the layout does a gradient act as separate layer that lies on top of the layer that uses the associated color or does it act as a replacement for the layer that uses the associated color? This proposal is written as if it were a replacement and thus avoids creating any additional layers in the layout.

Issue 2: Other types of gradients?

There are other types of gradients that are definable such as the rectangular and circular gradients. However, these other types of gradients are ill-suited for use with all four of the current usages of color in CSS, namely, backgrounds, borders, foregrounds, and outlines while linear gradients can be used with all four of these. That is why this proposal sticks to just linear gradients.

Issue 3: Free rotation of background and foreground gradients?

It would not complicate the syntax to use <angle> instead of allowing only horizontal or vertical gradients. However, it would require calculating a separate color value for each pixel instead of just one for each pixel row or pixel column. This would increase the computation cost involved in creating the gradients from O(n) to O(n²) as well requiring more complicated calculations for each color determined.. Is the flexibility worth the extra effort that would be required? Should this be handled as with the 'image-orientation' property of CSS Paged Media, in that while any angle may be specified, a user agent is free to round the value to a set of values that it accepts such as 0deg, 90deg, 180deg, and 270deg? For the moment this proposal aims for as much simplicity as possible and assumes a restriction to just the four basic directions.

Issue-4: What is top?

In the current working draft of the Box Module, the 'overflow-clip' property considers the orientation of top, left, bottom, and right to depend upon the direction of the inline progression. Should this proposal adopt that convention or continue to assume that top always refers to the same direction as the top of the viewport? Doing so would simplify the description of the default background gradient direction, but would complicate things otherwise.

<gradient>

A gradient value may be specified using either the keyword "none", or as <color> <color>? . All properties that use a <gradient> correspond to a property that uses a <color>. If the keyword "none" is used, there is no gradient effect and the normal result of the associated color property will occur. If one or two <color> values are specified, a linear gradient effect will be created for that particular portion of the element's style. If only one <color> is given for a <gradient> then the gradient uses the value of the associated property to provide the value of the second color. The stop points for the gradient are defined by with each property, but cover the entirety of the affected portion of the element’s style.

Note that if a gradient includes transparent or translucent colors, the corresponding color value is still not used. If its exists, the gradient replaces the solid color, it does not lie in a separate layer from the color. The points in between the start and end positions of a gradient receive a color determined by a linear interpolation of the sRGB and alpha values of the two colors. The interpolation is done before the the color is normalized to fall with the device gamut of the media in question.

'background-attachment'

The 'background-attachment' property is already defined in CSS 3 Backgrounds, and allows the position of the background image to be placed with respect to the document viewport ("fixed") and to the content area of the element ("scroll"). This proposal proposes another value ("clip") which causes the background image to be placed with respect to the clipping area of an overflowing element. When there is no overflow, the clipping area and the content area of an element are identical. When background gradients are supported, they are placed with respect to the area defined by the 'background-attachment' property.

'background-gradient'

Name:

Background-gradient

Value:

((bt | lr | rl | tb)? <gradient>) | inherit

Initial:

none

Applies to:

all elements

Inherited:

no

Percentages:

N/A

Media

visual

The background gradient extends across the entire box in either a vertical or horizontal direction. If the keyword "bt" is specified the gradient flows from the bottom to the top of the box with the bottom edge having the first color, the top edge having the second, and the points in between having a value for color that is the linear interpolation of the two values. Similarly the keywords "lr" "rl" and "tb" indicate left to right, right to left, and top to bottom respectively. If none of these keywords is included then the direction is determined based upon the value of the 'block-progression' and 'direction' properties for that element so that the gradient goes from the start of the inline-progression to the end of the inline-progression. This default was chosen because it appears to be the most common usage of background gradients in existing documents.

This is summarized in the table below:

default
background-gradient

bt

lr

rl

tb

block-progression

lr

rl

tb

tb

lr

rt

direction

ltr

rtl

ltr

ltr

rtl

ltr

'border-bottom-gradient', 'border-left-gradient', 'border-right-gradient', 'border-top-gradient', 'border-gradient'

Name:

border-bottom-gradient, border-left-gradient, border-right-gradient, 'border-top-gradient, border-gradient

Value:

<gradient> | inherit

Initial:

none

Applies to:

all elements

Inherited:

no

Percentages:

N/A

Media

visual

For each border the gradient is done from the outer (margin) edge to the inner (padding) edge. The border gradient properties are not used by the collapsed borders model for table layout, but are used by the separated borders model. If the second color value is not given in the gradient the corresponding border color is used. The 'border-gradient' property is a shorthand that sets all four of the border gradient properties. The following two declarations have the same effect on a user agent that supports the border-gradient properties, but will have a different effect if only the border color properties are supported by the user agent.:

e {
  border-gradient  : blue ;
  border-top-color : red  ;
}

e {
  border-bottom-gradient : blue ;
  border-left-gradient   : blue ;
  border-right-gradient  : blue ;
  border-top-gradient    : blue red;
}

'gradient'

Name:

gradient

Value:

((bt | lr | rl | tb)? <gradient>) | auto | inherit

Initial:

auto

Applies to:

all elements

Inherited:

no

Percentages:

N/A

Media

visual

The 'gradient' property works on the foreground in the same manner as the 'background-gradient does for the background. If the second <color> of the <gradient> is not specified then the value of the 'color' property is used. The "auto" keyword indicates that while a foreground gradient is not set for the element itself, it will use that of the closest ancestors element that has a value of 'gradient' other than "auto" so that its text appears to be part of the same smooth gradient as its parent. If the element is the root element, then "auto" is equivalent to "none"

'gradient-attachment'

Name:

gradient-attachment

Value:

fixed | scroll | clip | inherit

Initial:

scroll

Applies to:

all elements

Inherited:

no

Percentages:

N/A

Media

visual

If a gradient is specified, this property specifies whether it is positioned with regard to the viewport ("fixed"), the element’s content area ("scroll"), or the element’s clipping region ("clip") Note that unless the element overflows, the clipping area and the content area are the same. Note that if 'overflow' has the value "visible" and the 'gradient-attachment' is "clip" it is possible that a portion of the foreground will be outside of the clipping area. In that case the gradient continues on its same slope past the area of the clipping area to affect the entirely of the displayed foreground, even though the color stops of the given gradient are positioned with respect to the clipping area.

'outline-gradient'

Name:

outline-gradient

Value:

<gradient> | inherit

Initial:

none

Applies to:

all elements

Inherited:

no

Percentages:

N/A

Media

visual

The gradient is done from the outer edge to the inner edge of the outline. If the second <color> value for the <gradient> is not given, the value of 'outline-color' is used instead.