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 a n 'outline-gradient' property.

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.

<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. When gradients are supported it also applies to the gradient.

'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:

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 | 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 fixed with regard to the viewport ("fixed") or scrolls along with the document ("scroll").

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