Vector Graphics in CSS (Proposal)

22 January 2006

This version:
Latest version:
Previous version:
L. David Baron (, Mozilla Corporation

Status of this Document

This document is a work in progress. If you want to implement it or a part of it, please ask the author in advance how stable the parts you are interested in are.

This is a draft in the early stages of development. It is being shared publicly by the author (not on behalf of any organization) to gauge interest and see if others are interested in helping develop the specification. If it is developed further, the author hopes to develop it within a standards organization.

Comments on this draft should be sent to the (Subscribing) mailing list, which is archived on the NNTP server If you want more reliable archival of comments, cc: (Archive).


[SVG] is a presentational markup language for two-dimensional vector graphics, animation, and interaction. This document proposes additions to CSS to make a subset of the features of SVG available for semantic markup. It extends CSS, and therefore does not add features that overlap with existing CSS features. However, it attempts to re-use as many SVG features as possible. However, the additional CSS properties defined in SVG are largely unnecessary for this use, since they duplicate existing features of CSS (such as borders and backgrounds) and features better added as values (such as those in [css3-color]).

Gradients and Patterns

CSS1 and CSS2 have provided the ability to specify colors for text, borders, and backgrounds and the ability to specify patterns for backgrounds. The mechanism used for patterns in CSS1 and CSS2 (the background-* properties) has a number of disadvantages: the division into multiple properties means that the properties cascade separately when the background should generally cascade atomically, the use of patterns applies only to backgrounds and not to borders and text, and the mechanism is extremely difficult to extend to multiple backgrounds or to background fallback (and especially both), as in [css3-background].

This proposal offers an alternative mechanism: the use of @-rules to define patterns and gradients that can be additional values of any property accepting colors (e.g., 'color', 'border-color', 'border-*-color', 'background-color', 'background'). This would allow the 'background-*' properties to be deprecated.

Complex fills: the @fill rule

"Complex fills" isn't a very good title, although I think it's a little more informative than SVG's "paint servers". Need better one.

fill-rule ::= '@fill' S* IDENT S* '{' S* fill-descriptor-list '}'

The @fill rule allows stylesheet authors to define a named fill that can be used to fill a region where a solid color might otherwise be used. The name is given by the identifier following @fill. An @fill rule must precede all style rules and @media rules in a stylesheet; any @charset rules, @import rules or @namespace rules following @fill rules must be ignored.

Intermixing with @namespace rules might actually be better. I don't have strong feelings on any of the scoping rules, really, but it needs to be defined.

It's not entirely clear how fallback and multiple layers should be nested. This proposal puts fallback on the outside and multiple layers on the inside, although it could be done the other way around or with arbitrary combinations. I haven't thought it through very closely, though.

fill-descriptor-list ::= fill-descriptor-decl ( S* ';' S* fill-descriptor-decl? )*
fill-descriptor-decl ::= ( color-descriptor-decl |
                           gradient-descriptor-decl |
                           pattern-descriptor-decl |
                           toplevel-unknown ) S*
fill-fallback ::= '@fallback' S* '{' S* fill-descriptor-list '}'

A descriptor list provides a list of descriptor declarations, each of which is a layer of the fill, in order from topmost (closest to the user) to bottommost. Note that, unlike CSS declarations, repeated descriptor declarations using the same descriptor are meaningful.

Fills are defined to paint into a fill rectangle, and the result of this painting is clipped to a smaller region if necessary. Each fill descriptor painted as part of the process of painting a fill must be painted into this fill rectangle. To paint a fill or a fallback, user agents must paint its fill descriptor list. To paint a fill descriptor list that has a fallback, user agents must paint either the descriptors or the fallback. The user agent must paint the fallback if and only if the fallback is present and either one of the descriptors is not able to paint or the toplevel-unknown token was used when parsing the descriptor list. (This means that a parse error in a descriptor causes the fallback to be used if it is present, but allows the other descriptors to paint if there is no fallback.)

To paint the descriptors of a fill descriptor list, user agents must... (bottommost layer to topmost is last to first)

The toplevel-unknown token should be defined in a future version of the css3-syntax module.

fill-function ::= 'fill(' S* IDENT S* ')'

The fill() function is used in the syntax of some properties to refer to a named fill. The definition of each property whose value can be a fill() function defines a clipping region for the fill and a fill rectangle that contains the fill. When a fill() function is the computed value of such a property, user agents must paint the associated fill into the fill rectangle and clip the result to the clipping region.

The associated fill for a fill() function is the first fill whose name is the argument to the fill() function defined in the stylesheet containing the declaration in which the fill() function was specified. If there is no such fill, then the declaration containing the fill() function must be ignored as though it contained a parser error. This error handling behavior seems good for stylesheet authors but bad for the CSSOM.

Should @fill rules be @import-able? It might be useful.

Here's some potential example syntax. This needs to be written formally and then these need to be turned into examples.

@fill logoback {
  gradient: 90deg red blue;

#logo {
  background-color: fill(logoback);

@fill one {
  gradient: 0deg red green blue; /* assumed evenly spaced when color not preceded by % */

@fill two {
  image: url(foo.png) repeat-y;
  color: orange;
  @fallback {
    color: red;

@fill three {
  gradient: 0% red 60% orange 80% yellow; /* pick one of SVG's options for incomplete gradient */

Need to define error-handling points within so, e.g., an implementation that can't parse rgba() colors can have an image as fallback and a solid color as fallback behind that.

Have a section about the syntax, and mark the error-handling points with a special notation. (When using fallback lists, it's clear that descriptors sholudn't be error handling points. Should they be when not using fallback lists?)

Color descriptors

color-descriptor-decl ::= 'color' S* ':' S* MORE HERE

To paint a color descriptor into a fill rectangle, user agents must fill that rectangle with the descriptor's color. Color descriptors are always able to paint.

Gradient descriptors

gradient-descriptor-decl ::= 'gradient' S* ':' S* MORE HERE

Should there be only linear gradients or also radial gradients?

Define an at-rule equivalent to SVG's gradient definitions. Don't allow mixing of percentages and lengths. Must be nondecreasing stops (allows doubling at a point for a hard shift).

To paint a gradient descriptor into a fill rectangle, user agents must... MORE HERE

Gradient descriptors are always able to paint.

Pattern descriptors

pattern-descriptor-decl ::= 'image' S* ':' S* MORE HERE

CSS has previously supported patterns only for backgrounds. This at-rule syntax provides considerable overlap with existing properties, but allows patterns to be used for borders and text and has the advantage of atomic cascading for the background use cases.

To paint a pattern descriptor into a fill rectangle, user agents must... MORE HERE

Pattern descriptors are able to paint when MORE HERE

Extensions to existing CSS properties

Cite SVG. Extend 'background' and 'background-color' with paint() values (since url() is taken), and obsolete the CSS3 multiple backgrounds proposal with this. Do the same for 'color', 'border-color'. Define fill rectangle and clipping region for each.


Add introductory text about shapes.

Shape values

Basic shapes

How many basic shapes are needed? Paths can do all of this, right?


Reuse SVG syntax, but without SVG's unitless lengths extension.

'block-shape' property

Describe block-shape property ([ content | padding | border | margin ]? <shape>) | none

To find the others of the margin, border, padding, and content edges from the one that was given, use the algorithm used in the SVG spec for stroking a path with a given width (with specific values of 'stroke-linejoin' and 'stroke-miterlimit'). Unfortunately, the SVG spec doesn't actually define this.

The block-shape property doesn't affect how the block influences anything outside of itself. (Or should it for floats?) Should it affect blocks inside of itself?

Extensions to 'clip' property

Should the clip property be extended to support shapes in this version?

Text along a path

Should there be mechanisms for text along a path in this version?


Should filters be added in this version?


Write. Refer to RFC 2119. Have user-agent, author, and editor conformance requirements.


This draft benefited from various discussions in the W3C CSS working group, and especially from hearing requirements raised in those discussions.

Changes from 20060119 version

Normative references

Jon Ferraiolo, 藤沢 淳, and Dean Jackson. Scalable Vector Graphics (SVG) 1.1 Specification. 14 January 2003. W3C Recommendation. URL:

Informative references

Tantek Çelik, Chris Lilley. CSS3 Color Module. 14 May 2003. W3C Candidate Recommendation. URL:
Tim Boland, Bert Bos. CSS3 Backgrounds and Borders Module. 16 February 2005. W3C Working Draft. URL: