Cascading Style Sheets Object Model (CSSOM)

Editor's draft [DATE: 3 August 2002]

This version:
http://www.w3.org/TR/[YEAR]/WD-cssom-[CDATE]/
Latest version:
http://www.w3.org/TR/cssom/
Previous versions:
http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/
Editor:
Anne van Kesteren (Opera Software ASA) <annevk@opera.com>

Abstract

The Cascading Style Sheets Object Model defines enables developers to find style sheets associated with a Document, to query and modify rules within a CSS style sheet (through an object model) and to find out layout related information from objects within a Document.

Status of this Document

This document is in its very early stages. The intention is that this specification will in due course supercede DOM Level 2 Style.

Table of Contents

Introduction

...

History

This section is non normative.

Several interfaces from DOM Level 2 Style have been obsoleted because they where thought to be too akward for frequent use. This specification no longer contains those features.

In addition, DOMImplementationCSS has been removed as well, because there was no use case provided in DOM Level 2 Style.

Conformance Requirements

Everything in this specification is normative except for diagrams, examples, notes and sections marked non-normative.

The key words must, must not, required, shall, shall not, should, should not, recommended, may, and optional in the normative parts of this document are to be interpreted as described in [RFC2119].

The following conformance classes are defined (and considered) by this specification:

conforming implementation
A user agent that implements all interfaces described in this specification and follows all must-, required- and shall-level of critera in this specification.
conforming document
A document that follows all must-, required- and shall-level of critera in this specification that apply to document authors.
conforming authoring tool
One that produces conforming documents.

Terminology and Conventions

A color component integer is a base-ten integer in the range 0-255 using digits 0-9, U+0030 to U+0039, in the shortest form possible.

A color component separator is a literal U+002C COMMA followed by a U+0020 SPACE.

When this specification talks about object A where A is actually an interface, it generally means an object implementing interface A.

The terms whitespace and style sheet are used as defined in the CSS 2.1 Specification [CSS21].

A CSS style sheet is a style sheet that conforms to the CSS syntax rules.

DOM feature strings

DOM Level 3 Core defines mechanisms for checking for interface support, and for obtaining implementations of interfaces, using feature strings. [DOM3CORE]

A DOM application can use the hasFeature(feature, version) method of the DOMImplementation interface with parameter values "StyleSheets" and "3.0" (respectively) to determine whether or not "Accessing style sheets through the DOM" is supported by the implementation. The feature string "CSS" (with version string "3.0") can be used to check if the implementation supports "Cascading Style Sheets APIs" and "Layout" (with version string "3.0") can be used to check if the implementation supports "Layout APIs". User agents should respond with a true value when the hasFeature method is queried with these values. Authors are cautioned, however, that user agents returning true might not be perfectly compliant, and that user agents returning false might well have support for features in this specification; in general, therefore, use of this method is discouraged.

The values "StyleSheets", "CSS" and "Layout" (all with version "3.0") should also be supported in the context of the getFeature() and isSupported() methods, as defined by DOM Level 3 Core.

The interfaces defined in this specification are not always supersets of the interfaces defined in DOM Level 2 Style; some features that were formerly deprecated, poorly supported, rarely used or considered unnecessary have been removed. Therefore it is not guarenteed that an implementation that supports "CSS" "3.0" also supports "CSS" "2.0".

Accessing style sheets through the DOM

Each style sheet is represented by a StyleSheet object. These objects can be accessed through the LinkStyle interface implemented on individual Node objects or through the DocumentStyle interface implemented on the Document object. The DocumentStyle interface also provides an interface for enabling alternate style sheets and manipulating style sheet sets.

Terminology

Each style sheet can have a title. A style sheet is said to have a title if the title attribute on the StyleSheet object is neither null nor the empty string.

Persistent style sheets are style sheets without a title.

One or more style sheets with the same title (case-sensitive) form a style sheet set.

The LinkStyle Interface

Nodes within the DOM causing the association of a style sheet must implement the LinkStyle interface.

interface LinkStyle {
  readonly attribute StyleSheet       sheet;
};
sheet of type StyleSheet, readonly
This attribute must be the StyleSheet the node is referring to or null if the node is not referring to a StyleSheet (for example, all link elements in HTML implement this interface, but not all link elements are used for style sheets).

Whether or not the node refers to a style sheet is defined by the specification the defines the semantics of said node.

Requirements on specifications

Specifications introducing new ways of associating style sheets through the DOM should define which objects implement the LinkStyle interface. In addition, these specifications should define how these objects affect the potentially associated StyleSheet object (when sheet is non-null).

Requirements on specific user agents

SVG user agents must implement LinkStyle on objects implementing the SVGStyleElement interface. HTML user agents must implement LinkStyle on objects implementing HTMLLinkElement or HTMLStyleElement. They must also implement it on objects implementing HTMLMetaElement if the Link HTTP header is supported.

Perhaps the above should be left to the HTML and SVG specifications.

<?xml-stylesheet?> processing instruction

User agents supporting supporting <?xml-stylesheet?> must implement the LinkStyle on objects implementing ProcessingInstruction.

If the target DOM attribute of the ProcessingInstruction is not xml-stylesheet or if the href pseudo-attribute of the processing instruction doesn't point to an external resource or does point to an external resource that has not yet been downloaded the sheet attribute must be null. Otherwise, if the target DOM attribute is xml-stylesheet, the resource has been downloaded and the determined type is a supported style sheet language the sheet attribute must be a StyleSheet object with the members implemented as follows:

type
This must be the determined type.
href
This must be the value of the href pseudo-attribute.
media
This must be the value of the media pseudo-attribute.
title
This must be the value of the title pseudo-attribute.

The DocumentStyle Interface

Any object implementing the Document interface must also implement the DocumentStyle interface.

interface DocumentStyle {
  readonly attribute StyleSheetList   styleSheets;
           attribute DOMString        selectedStyleSheetSet;
  readonly attribute DOMString        lastStyleSheetSet;
  readonly attribute DOMString        preferredStyleSheetSet;
  readonly attribute DOMStringList    styleSheetSets;
  void               enableStylesheetsForSet(in DOMString name);
};

For this interface, the DOMString values null and "the empty string" are distinct, and must not be considered equivalent.

The members are defined as follows:

styleSheets of type StyleSheetList

This attribute must be a StyleSheetList object containing a collection of all LinkStyle objects with a non-null sheet attribute in document order preceeded by style sheets introduced through HTTP headers.

selectedStyleSheetSet of type DOMString

This attribute indicates which style sheet set is in use. This attribute is live; changing the disabled attribute on style sheets directly will change the value of this attribute.

If all the sheets that are enabled and have a title have the same title (by case-sensitive comparisons) then the value of this attribute must be exactly equal to the title of the first enabled style sheet with a title in the styleSheets list. Otherwise, if style sheets from different sets are enabled, then the return value must be null (there is no way to determine what the currently selected style sheet set is in those conditions). Otherwise, either all style sheets that have a title are disabled, or there are no alternate style sheets, and selectedStyleSheetSet must return the empty string.

Setting this attribute to the null value must have no effect.

Setting this attribute to a non-null value must call enableStylesheetsForSet() with that value as the method's argument, and set lastStyleSheetSet to that value.

From the DOM's perspective, all views have the same selectedStyleSheetSet. If a user agent supports multiple views with different selected alternate style sheets, then this attribute (and the StyleSheet interface's disabled attribute) must return and set the value for the default view.

lastStyleSheetSet of type DOMString, readonly

This property must initially have the value null. Its value changes when the selectedStyleSheetSet attribute is set.

preferredStyleSheetSet of type DOMString, readonly

This attribute must be the preferred style sheet set as set by the author. It is determined from the order of style sheet declarations and the Default-Style HTTP headers. If there is no preferred style sheet set, this attribute must be the empty string. The case of this attribute must exactly match the case given by the author where the preferred style sheet is specified or implied. This attribute must never be null.

styleSheetSets of type DOMStringList, readonly

This must be a live list of the currently available style sheet sets. This list is constructed by enumerating all the style sheets for this document available to the implementation, in the order they are listed in the styleSheets attribute, adding the title of each style sheet with a title to the list, avoiding duplicates by dropping titles that match (case-sensitively) titles that have already been added to the list.

enableStylesheetsForSet(name), method

Invoking this method must change the disabled attribute on each StyleSheet object with a title in the styleSheets attribute, so that all those whose title matches the name argument are enabled, and all others are disabled. Title matches must be case-sensitive.

Invoking this method with the empty string value must disable all alternate and preferred style sheets (but does not change the state of persistent style sheets).

Invoking this method with the null value must have no effect.

Style sheets that do not have a title are never affected by this method. This method does not change the values of the lastStyleSheetSet or preferredStyleSheetSet attributes.

The StyleSheetList Interface

The object implementing this interface represents a live collection of StyleSheet objects.

In bindings that allow it, enumerating a StyleSheetList object must enumerate through the currently stored and accessible items in the list the object is associated with. This ensures document.styleSheets[1].x is possible from ECMAScript for example.

interface StyleSheetList {
  readonly attribute unsigned long    length;
  StyleSheet         item(in unsigned long index);
};

The members of the StyleSheetList object are defined as follows:

length, of type unsigned long, readonly
This attribute must be the number of StyleSheet objects currently in the list.
item(index), method
When invoked, this method must return the StyleSheet in the list given by index. If index is less than zero then this method must raise an INDEX_SIZE_ERR exception. If index is greater than or equal to the number of style sheets currently in the list this method must return null.

Dynamically adding new style sheets

If new style sheets with titles are added to the document, the user agent must decide whether or not the style sheets should be initially enabled or not. How this happens depends on the exact state of the document at the time the style sheet is added, as follows.

Adding style sheets

First, if the style sheet is a preferred style sheet (it has a title, but is not marked as alternate), and there is no current preferred style sheet (the preferredStyleSheetSet attribute is equal to the empty string) then the preferredStyleSheetSet attribute is set to the exact value of this style sheet's title. (This changes the preferred style sheet set, which causes further changes — see below.)

Then, for all sheets, if any of the following is true, then the style sheet must be enabled:

Otherwise, the style sheet must be disabled.

Changing the preferred style sheet set

The first time the preferred style sheet set is set, which is either before any alternate style sheets are seen (e.g. using a Default-Style HTTP header), or is the first time a titled, non-alternate style sheet is seen (in the absence of information to the contrary, the first titled non-alternate sheet sets the name of the preferred set), the preferredStyleSheetSet attribute's value must be set to the name of that preferred style sheet set. This does not change the lastStyleSheetSet attribute.

If the user agent has the preferred style sheet set changed, for example if it receives a Default-Style HTTP header after it receives HTTP Link headers implying another preferred style sheet, then the preferredStyleSheetSet attribute's value must be changed appropriately, and, if the lastStyleSheetSet is null, the enableStylesheetsForSet() method must be called with the new preferredStyleSheetSet value. (The lastStyleSheetSet attribute is, again, not changed.)

Examples

Thus, in the following HTML snippet:

<link rel="alternate stylesheet" title="foo" href="a">
<link rel="alternate stylesheet" title="bar" href="b">
<script>

  document.selectedStyleSheetSet = 'foo';
  document.styleSheets[1].disabled = false;
</script>
<link rel="alternate stylesheet" title="foo" href="c">
<link rel="alternate stylesheet" title="bar" href="d">

...the style sheets that end up enabled are style sheets "a", "b", and "c", the selectedStyleSheetSet attribute would return null, lastStyleSheetSet would return "foo", and preferredStyleSheetSet would return "".

Similarly, in the following HTML snippet:

<link rel="alternate stylesheet" title="foo" href="a">
<link rel="alternate stylesheet" title="bar" href="b">
<script>
  var before = document.preferredStyleSheetSet;
  document.styleSheets[1].disabled = false;
</script>
<link rel="stylesheet" title="foo" href="c">

<link rel="alternate stylesheet" title="bar" href="d">
<script>
  var after = document.preferredStyleSheetSet;
</script>

...the "before" variable will be equal to the empty string, the "after" variable will be equal to "foo", and style sheets "a" and "c" will be enabled. This is the case even though the first script block sets style sheet "b" to be enabled, because upon parsing the following <link> element, the preferredStyleSheetSet is set and the enableStylesheetsForSet() method is called (since selectedStyleSheetSet was never set explicitly, leaving lastStyleSheetSet at null throughout), which changes which style sheets are enabled and which are not.

Interaction with the User Interface

The user interface of Web browsers that support style sheets should list the style sheet titles given in the styleSheetSets list, showing the selectedStyleSheetSet as the selected style sheet set, leaving none selected if it is null or the empty string, and selecting an extra option "Basic Page Style" (or similar) if it is the empty string and the preferredStyleSheetSet is the empty string as well.

Selecting a style sheet from this list should set the selectedStyleSheetSet attribute. This (by definition) affects the lastStyleSheetSet attribute.

Persisting the selected style sheet set

If UAs persist the selected style sheet set, they should use the value of the selectedStyleSheetSet attribute, or if that is null, the lastStyleSheetSet attribute, when leaving the page (or at some other time) to determine the set name to store. If that is null then the style sheet set should not be persisted.

When re-setting the style sheet set to the persisted value (which can happen at any time, typically at the first time the style sheets are needed for styling the document, after the <head> of the document has been parsed, after any scripts that are not dependent on computed style have executed), the style sheet set should be set by setting the selectedStyleSheetSet attribute as if the user had selected the set manually.

This specification does not give any suggestions on how UAs should decide to persist the style sheet set or whether or how to persist the selected set across pages.

Forward compatibility

Future versions of CSS may introduce ways of having alternate style sheets declared at levels lower than the top level, i.e. embedded within other style sheets. Implementations of this specification that also support this proposed declaration of alternate style sheets are expected to perform depth-first traversals of the styleSheets list, not simply enumerations of the styleSheets list that only contains the top level.

Would that actually work?!

The StyleSheet Interface

Each style sheet is represented by a StyleSheet object.

interface StyleSheet {
  readonly attribute DOMString        type;
           attribute boolean          disabled;
  readonly attribute Node             ownerNode;
  readonly attribute StyleSheet       parentStyleSheet;
  readonly attribute DOMString        href;
  readonly attribute DOMString        title;
  readonly attribute MediaList        media;
};
type of type DOMString, readonly

This attribute indicates the MIME type of the style sheet. It's set by objects which cause a StyleSheet object to be created, such as LinkStyle.

disabled of type boolean

On getting, this attribute must be true when the style sheet is disabled and false otherwise.

On setting, a value of true must disable the style sheet and a value of false enable it.

ownerNode of type Node, readonly
This attribute must be the Node that associates the style sheet with the document or null otherwise. This Node has implemented the LinkStyle interface.
parentStyleSheet of type StyleSheet, readonly
This attribute must be the StyleSheet object that caused the inclusion of the current style sheet or null if there is no such object.
href of type DOMString, readonly
This attribute must be an IRI pointing to the location of the standalone style sheet or null otherwise (when it's inside a style element for example).
title of type DOMString
This attribute must be the title of the style sheet. In HTML this can obtained from the HTMLLinkElement or HTMLStyleElement for example.
media of type MediaList, readonly

This attribute must be a MediaList object.

In binding languages that support setting to a readonly attribute setting media to a string must set the value of mediaText on the MediaList object.

The MediaList Interface

This interface depends on the Media Queries specification which still has some issues.

The MediaList object represents a collection of media queries. It provides various ways to manipulate this collection.

In bindings that allow it, enumerating a MediaList object must enumerate through the current collection of media queries.

In bindings that allow it, such as ECMAScript, MediaList objects must stringify to their mediaText attribute's value.

interface MediaList {
           attribute DOMString        mediaText;
  readonly attribute unsigned long    length;
  DOMString          item(in unsigned long index);
  void               appendMedium(in DOMString medium)
  void               deleteMedium(in DOMString medium)
};
mediaText of type DOMString

On getting this attribute must be a comma-separated list of normalized media queries or the empty string otherwise.

On setting ....

length of type unsigned long
This attribute must be the number of media in the list.
item(index), method
When invoked, this method must return the media query in the collection given by index. If index is less than zero then this method must raise an INDEX_SIZE_ERR exception. If index is greater than or equal to the number of media queries currently in the collection this method must return null.
appendMedium(medium), method
When invoked, ....
deleteMedium(medium), method
This method, when invoked, must raise a NOT_FOUND_ERR exception when medium is not in the collection. Otherwise, medium must be removed from the collection.

Cascading Style Sheets APIs

This section (and its subsections) are only applicable to user agents implementing CSS.

The previous section provided a way of getting access to style sheets in a generic way. This section provides a way for getting access to the individual style rules within a Cascading Style Sheet as defined by the CSS specifications. [CSS21]

Processing CSS Statements

The rules for inserting a statement are as given in the following algorithm. The variables rule, rule list and index are to be considered equivalent to the identically named variables used when invoking this algorithm. If an exception is raised the algorithm is to be aborted. The steps must be followed in order, as follows:

  1. If index is negative or greater than the length of the rule list an INDEX_SIZE_ERR exception must be raised.
  2. Parse rule as a CSS statement. If the rule is ignored by the CSS parser abort this algorithm (don't raise an exception). Otherwise, create an object that implements one of the inherited interfaces of CSSStyle appropriate for the parsed rule. Let object be the newly created object.
  3. If object can't be inserted within the rule list at the given index because that's not allowed per the CSS specification a HIERARCHY_REQUEST_ERR exception must be raised.
  4. Insert object at the given index within the rule list.

The rules for removing a statement are as given in the following algorithm. The variables index and rule list are to be considered equivalent to the identically named variables used when invoking this algorithm. If an exception is raised this algorithm is to be aborted. The steps must be followed in order, as follows:

  1. If index is negative or greater than the length of the rule list an INDEX_SIZE_ERR exception must be raised.
  2. Remove the object at index from rule list.

The rules for replacing a statement are as given in the following algorithm. The variable rule and old object are to be considered equivalent to the identically named variables used when invoking this algorithm. If an exception is raised this algorithm is to be aborted. The steps must be followed in order, as follows:

  1. Parse rule as a CSS statement. If the rule is ignored by the CSS parser abort this algorithm (don't raise an exception). Otherwise, create an object that implements one of the inherited interfaces of CSSStyle appropriate for the parsed rule. Let object be the newly created object.
  2. If the type of new object doesn't match the type of the object it will replace raise an INVALID_MODIFICATION_ERR exception.
  3. Replace old object with object.

The CSSStyleSheet Interface

The CSSStyleSheet interface represents a CSS style sheet.

interface CSSStyleSheet : StyleSheet {
  readonly attribute CSSRule          ownerRule;
  readonly attribute CSSRuleList      cssRules;
  unsigned long      insertRule(in DOMString rule, in unsigned long index);
  void               deleteRule(in unsigned long index);
};
ownerRule of type CSSRule, readonly
If the style sheet was loaded due to an @import rule this attribute must be the CSSImportRule that caused this style sheet to be imported. Otherwise it must be null.
cssRules of type CSSRuleList, readonly
This attribute must be a live CSSRuleList consisting of an ordered list of statements (statements are either rulesets or at-rules).
insertRule(rule, index), method
When invoked, user agents must insert a statement where rule is rule, index is index and rule list is cssRules.
deleteRule(index), method
When invoked, user agents must remove a statement where index is index and rule list is cssRules.

The CSSRuleList Interface

The CSSRuleList interface represents an ordered list of statements.

In bindings that allow it, enumerating a CSSRuleList object must enumerate through the currently stored items in the list the object is associated with.

interface CSSRuleList {
  readonly attribute unsigned long    length;
  CSSRule            item(in unsigned long index);
};
length of type unsigned long, readonly
This attribute must be the number of items associated with the object.
item(index), method
When invoked, if index is equal or greater than the length this method must return null. Otherwise, this method must return the CSSRule in the list given by index.

Interfaces for CSS Statements

This section defines several specific interfaces and one generic (from which the more specific inherit) for different types of CSS statements.

The CSSRule Interface

interface CSSRule {
  const unsigned short      STYLE_RULE                     = 1;
  const unsigned short      CHARSET_RULE                   = 2;
  const unsigned short      IMPORT_RULE                    = 3;
  const unsigned short      MEDIA_RULE                     = 4;
  const unsigned short      FONT_FACE_RULE                 = 5;
  const unsigned short      PAGE_RULE                      = 6;
  const unsigned short      NAMESPACE_RULE                 = 7;

  readonly attribute unsigned short   type;
           attribute DOMString        cssText;
  readonly attribute CSSRule          parentRule;
  readonly attribute CSSStyleSheet    parentStyleSheet;
};

The STYLE_RULE, CHARSET_RULE, IMPORT_RULE, MEDIA_RULE, FONT_FACE_RULE, PAGE_RULE and NAMESPACE_RULE contants indicate if you have a CSSStyleRule, CSSCharsetRule, CSSImportRule, CSSMediaRule, CSSFontFaceRule, CSSPageRule or CSSNamespaceRule rule type respectively.

type of type unsigned short, readonly
This attribute must be one of the defined constants.
cssText of type DOMString

On setting, user agents must replace a statement where rule is the value being set and old object is the object of which this attribute is set.

On getting, ....

parentRule of type CSSRule, readonly
This attribute must be the nearest enclosing rule of the current rule. For example, an @media block enclosing the current rule.
parentStyleSheet of type CSSStyleSheet, readonly
This attribute must point to the style sheet that contains the current rule.
Extensibility

The values 0-1000 are reserved for future use by the CSS WG.

Vendors are suggested to use values outside this range and are reasonable unique so that they don't clash with extensions from other vendors. For example, the first value for Mozilla could be 0x08EC0001 and 0x09E8A001 could be the first for Opera.

The CSSStyleRule Interface

The CSSStyleRule object represents a ruleset. It provides access to a declaration block as well as to the group of selectors.

interface CSSStyleRule : CSSRule {
           attribute DOMString        selectorText;
  readonly attribute CSSStyleDeclaration  style;
};
selectorText of type DOMString

On setting, user agents must parse the given string as a group of selectors. If the given string is ignored user agents must act as if setting didn't occur. Otherwise, set the attribute to the parsed string.

On getting, this attribute must return a textual representation of the group of selectors.

style of type CSSStyleDeclaration, readonly
This attribute must be a live instance of the CSSStyleDeclaration for the current ruleset.

The CSSCharsetRule Interface

@charset can (only) be used at the very start of a CSS style sheet to indicate the encoding of the file ([CSS21], section 4.4).

interface CSSCharsetRule : CSSRule {
  readonly attribute DOMString        encoding;
};
encoding of type DOMString, readonly
This attribute must be the specified encoding.

The CSSImportRule Interface

The @import at rule as described in the CSS 2.1 Specification ([CSS21], section 6.3).

interface CSSImportRule : CSSRule {
  readonly attribute DOMString        href;
  readonly attribute MediaList        media;
  readonly attribute CSSStyleSheet    styleSheet;
};
href of type DOMString, readonly
This attribute must be the resolved URI of the style sheet to be included.
media of type MediaList, readonly
This attribute must be a live MediaList containing a list of media queries applicable to the imported style sheet.
styleSheet of type CSSStyleSheet, readonly
This attribute must be a CSSStyleSheet object.

The CSSMediaRule Interface

The @media at-rule is represented as a single statement in the CSS style sheet that contains zero or more rulesets which are contrained by one or more media (unless one happens to be all).

interface CSSMediaRule : CSSRule {
  readonly attribute MediaList        media;
  readonly attribute CSSRuleList      cssRules;
  unsigned long      insertRule(in DOMString rule, in unsigned long index);
  void               deleteRule(in unsigned long index);
};
media of type MediaList, readonly
This attribute must be a MediaList containing a list of media types for which the contained rulesets may be used.
cssRules of type CSSRuleList, readonly
This attribute must be a CSSRuleList containing a list of all the rulesets.
insertRule(rule, index), method
When invoked, user agents must insert a statement where rule is rule, index is index and rule list is cssRules.
deleteRule(index), method
When invoked, user agents must remove a statement where index is index and rule list is cssRules.

The CSSFontFaceRule Interface

@font-face is used for grouping a single declaration block related to font settings for the page.

interface CSSFontFaceRule : CSSRule {
  readonly attribute CSSStyleDeclaration  style;
};
style of type CSSStyleDeclaration, readonly
This attribute must be a live reference to the declaration block for this rule.

Currently @font-face is more or less obsolete.

The CSSPageRule Interface

An @page at-rule consists of a declaration block with an associated selector.

interface CSSPageRule : CSSRule {
           attribute DOMString        selectorText;
  readonly attribute CSSStyleDeclaration  style;
};
selectorText of type DOMString

On getting, this attribute must contain a live textual representation of the page selector for the rule.

On setting, a SYNTAX_ERR exception must be raised if the page selector was not parsable. Otherwise, it must be set to the specified value.

We need to define normalization...

style of type CSSStyleDeclaration, readonly
This attribute must be a live reference to the declaration block for the current ruleset.

The CSSNamespaceRule Interface

An @namespace at-rule consists of a token, being the prefix, and a URI, being the namespace.

interface CSSNamespaceRule : CSSRule {
  readonly attribute DOMString        namespaceURI;
  readonly attribute DOMString        prefix;
};
namespaceURI of type DOMString, readonly
This attribute must be the specified namespace IRI.
prefix of type DOMString, readonly
This attribute must be the specified prefix or the empty string if there is no prefix.

Accessing declaration blocks

This section provides various way to get to declaration blocks which you can then manipulate.

Introduction

...

The ElementCSSInlineStyle Interface

interface ElementCSSInlineStyle {
  readonly attribute CSSStyleDeclaration  style;
  readonly attribute CSSStyleDeclaration  currentStyle;
  readonly attribute CSSStyleDeclaration  runtimeStyle;
};

Serialization of the style attribute is not guarenteed to work.

The ViewCSS Interface

This interface represents a CSS view. The getComputedStyle method provides a read only access to the computed values of an element.

The expectation is that an instance of the ViewCSS interface can be obtained by using binding-specific casting methods on an instance of the AbstractView interface.

Since a computed style is related to an Element node, if this element is removed from the document, the associated CSSStyleDeclaration is no longer valid.

interface ViewCSS : AbstractView {
  CSSStyleDeclaration getComputedStyle(in Element elt, in DOMString pseudoElt);
};

The getComputedStyle method must return a live CSSStyleDeclaration object representing the computed style for elt (when pseudoElt is null) or for the pseudo-element pseudoElt of elt. [CSS21]

If pseudoElt is not a recognized CSS pseudo-element the invocation the method must return ....

For language bindings that support optional arguments invoking getComputedStyle without the pseudoElt argument must be identical to invoking the method with that argument being null.

The DocumentCSS Interface

This interface represents a document with a CSS view.

The getOverrideStyle method provides a mechanism through which a DOM author could effect immediate change to the style of an element without modifying the explicitly linked style sheets of a document or the inline style of elements in the style sheets. This style sheet comes after the author style sheet in the cascade algorithm and is called override style sheet. The override style sheet takes precedence over author style sheets. An !important declaration in an author style sheet still takes precedence over a normal declaration in an author style sheet. Override, author and user style sheets may all contain !important declarations. User !important rules take precedence over both override and author !important rules, and override !important rules take precedence over author !important rules.

The expectation is that an instance of the DocumentCSS interface can be obtained by using binding-specific casting methods on an instance of the Document interface.

interface DocumentCSS : DocumentStyle {
  CSSStyleDeclaration getOverrideStyle(in Element elt, in DOMString pseudoElt);
};

The getOverrideStyle method must return the override style declaration for the Element elt (when pseudoElt is null) or for the pseudo-element pseudoElt of Element elt.

For language bindings that support optional arguments invoking getOverrideStyle without the pseudoElt argument must be identical to invoking the method with that argument being null.

Declaration blocks

The CSSStyleDeclaration Interface

The CSSStyleDeclaration interface gives access to read and manipulate CSS property values within a declaration block.

interface CSSStyleDeclaration {
           attribute DOMString        cssText;
  DOMString          getPropertyValue(in DOMString propertyName);
  DOMString          removeProperty(in DOMString propertyName);
  DOMString          getPropertyPriority(in DOMString propertyName);
  void               setProperty(in DOMString propertyName, in DOMString value);
  void               setProperty(in DOMString propertyName, in DOMString value, in DOMString priority);
  readonly attribute unsigned long    length;
  DOMString          item(in unsigned long index);
  readonly attribute CSSRule          parentRule;
};
cssText
...

...

CSS Properties

The DOM attribute name of a CSS property can be found by using the following algorithm:

  1. Let r be the CSS property to be converted.
  2. Uppercase the first character after every U+002D (-) in r.
  3. Remove every U+002D (-) in r.
  4. Return r.

This means that -vendor-property becomes VendorProperty for instance.

The CSS2Properties Interface

If we have all the properties on CSSStyleDeclarationProperties do we still need this interface?

The CSSStyleDeclarationProperties Interface

Need to work out how to deal with properties that take one or more values. Such as the "newstyle" 'background-image' etc. Suggestions welcome.

Objects implementing the CSSStyleDeclaration interface must also implement the CSSStyleDeclarationProperties interface.

The CSSStyleDeclarationProperties interface can never be considered stable. This means that in languages where stable interfaces are important you have to use some kind of versioning mechanism.

interface CSSStyleDeclarationProperties {
           // This interface will be updated when more CSS property related
           // specifications become stable (for instance, W3C Recommendation).
           attribute CSSBaseValue     azimuth;
           attribute CSSColorValue    backgroundColor;
           attribute CSSURLValue      backgroundImage;
           attribute CSSBaseValue     backgroundPosition;
           attribute CSSBaseValue     borderSpacing;
           attribute CSSColorValue    borderTopColor;
           attribute CSSColorValue    borderRightColor;
           attribute CSSColorValue    borderBottomColor;
           attribute CSSColorValue    borderLeftColor;
           attribute CSSLengthValue   borderTopWidth;
           attribute CSSLengthValue   borderRightWidth;
           attribute CSSLengthValue   borderBottomWidth;
           attribute CSSLengthValue   borderLeftWidth;
           attribute CSSPercentageLengthValue  bottom;
           attribute CSSBaseValue     clip;
           attribute CSSColorValue    color;
           attribute CSSBaseValue     content;
           attribute CSSURLValue      cueAfter;
           attribute CSSURLValue      cueBefore;
           attribute CSSURLValue      cursor;
           attribute CSSAngleValue    elevation;
           attribute CSSPercentageLengthValue  fontSize;
           attribute CSSBaseValue     fontWeight;
           attribute CSSPercentageLengthValue  height;
           attribute CSSPercentageLengthValue  left;
           attribute CSSLengthValue   letterSpacing;
           attribute CSSBaseValue     lineHeight;
           attribute CSSURLValue      listStyleImage;
           attribute CSSPercentageLengthValue  marginTop;
           attribute CSSPercentageLengthValue  marginRight;
           attribute CSSPercentageLengthValue  marginBottom;
           attribute CSSPercentageLengthValue  marginLeft;
           attribute CSSPercentageLengthValue  maxHeight;
           attribute CSSPercentageLengthValue  maxWidth;
           attribute CSSPercentageLengthValue  minHeight;
           attribute CSSPercentageLengthValue  minWidth;
           attribute CSSBaseValue     orphans;
           attribute CSSColorValue    outlineColor;
           attribute CSSLengthValue   outlineWidth;
           attribute CSSPercentageLengthValue  paddingTop;
           attribute CSSPercentageLengthValue  paddingRight;
           attribute CSSPercentageLengthValue  paddingBottom;
           attribute CSSPercentageLengthValue  paddingLeft;
           attribute CSSBaseValue     pauseAfter;
           attribute CSSBaseValue     pauseBefore;
           attribute CSSBaseValue     pitchRange;
           attribute CSSBaseValue     pitch;
           attribute CSSURLValue      playDuring;
           attribute CSSBaseValue     richness;
           attribute CSSPercentageLengthValue  right;
           attribute CSSBaseValue     speechRate;
           attribute CSSBaseValue     stress;
           attribute CSSPercentageLengthValue  textIndent;
           attribute CSSPercentageLengthValue  top;
           attribute CSSPercentageLengthValue  verticalAlign;
           attribute CSSPercentageLengthValue  width;
           attribute CSSBaseValue     volume;
           attribute CSSBaseValue     widows;
           attribute CSSLengthValue   wordSpacing;
           attribute CSSBaseValue     zIndex;
};

CSS value related interfaces

The specific interfaces for CSS value allow for "easy" script manipulation of CSS property declarations.

For instance, to increase the pixel value of the width property of object obj by 300 one could write:

obj.style.width.px += 300

The CSSBaseValue Interface

The CSSBaseValue interface acts as the base interface for all specific CSS value interfaces.

In binding that allow it, objects implementing the CSSBaseValue interface must stringify to the object's underlying string representation.

CSSBaseValue inherits from DOMString, so in bindings where strings have attributes or methods, those attributes and methods will also operate on CSSBaseValue objects.

interface CSSBaseValue : DOMString {
           attribute DOMString        cssText;
};
cssText

On setting, user agents must parse the given string as a value for the associated property (the attribute from which this object was obtained). If the given string was ignored user agents must act as if setting didn't occur. Otherwise, set the attribute to the parsed string.

On getting, ....

The CSSColorValue Interface

interface CSSColorValue : CSSBaseValue {
           attribute unsigned short   red;
           attribute float            redPercent; // 100% = 255
           attribute unsigned short   green;
           attribute float            greenPercent; // 100% = 255
           attribute unsigned short   blue;
           attribute float            bluePercent; // 100% = 255
           attribute float            alpha; // float in range 0.0..1.0
           attribute unsigned short   hue; // integer in range 0..360
           attribute float            saturation; // percentage
           attribute float            lightness; // percentage
           attribute unsigned long    hex3;
           attribute unsigned long    hex6;
};

The CSSUrlValue Interface

interface CSSUrlValue : CSSBaseValue {
           attribute DOMString        url;
  readonly attribute DOMString        absoluteUrl;
};

The CSSLengthValue Interface

interface CSSLengthValue : CSSBaseValue {
           attribute float            em;
           attribute float            ex;
           attribute float            px;
           attribute float            cm;
           attribute float            mm;
           attribute float            pt;
           attribute float            pc;
};

How to express non-negative lengths?

The CSSPercentageLengthValue Interface

interface CSSPercentageLengthValue : CSSLengthValue {
           attribute float            percent;
};

... some exception for when conversion isn't possible.

Layout APIs

This section and its subsections apply to visual user agents only.

The WindowLayout Interface

The WindowLayout interface must be implemented on objects implementing the Window interface. [Window]

The term browsing context is used as defined by the Window Object 1.0 specification. [Window]

Some of the terminology used in this section and its subsection is that of Media Queries. [MQ]

This interface represents rendering information about the current browsing context.

interface WindowLayout {
  readonly attribute float            innerWidth;
  readonly attribute float            innerHeight;
  readonly attribute float            outerWidth;
  readonly attribute float            outerHeight;
  readonly attribute float            pageXOffset;
  readonly attribute float            pageYOffset;
  readonly attribute float            screenX;
  readonly attribute float            screenY;
  readonly attribute Screen           screen;
};
innerWidth

This attribute must be the viewport width in pixels.

This is including, if rendered, the vertical scrollbar.

innerHeight

This attribute must be the viewport height in pixels.

This is including, if rendered, the horizontal scrollbar.

outerWidth
In web browsers, this attribute must be the width of the browser window in pixels. Otherwise, this must be 0.
outerHeight
In web browsers, this attribute must be the height of the browser window in pixels. Otherwise, this must be 0.
pageXOffset
This attribute must be the number of pixels the user has scrolled to the right.
pageYOffset
This attribute must be the number of pixels the user has scrolled to the bottom.
screenX
In web browsers, this attribute must be the amount of of pixels to the left of the browser window offsetted against the screen of the output device. Otherwise, this must be 0.
screenY
In web browsers, this attribute must be the amount of of pixels to the top of the browser window offsetted against the screen of the output device. Otherwise, this must be 0.
screen
This attribute must hold a Screen object.

If the user agent supports multiple views and the current view does not have a notion of an output device the above attributes with the exception of screen must be 0. [DOM2View]

The Screen Interface

This interface represents information about the screen of the output device.

interface Screen {
  readonly attribute float            availWidth;
  readonly attribute float            availHeight;
  readonly attribute float            width;
  readonly attribute float            height;
  readonly attribute float            colorDepth;
  readonly attribute float            pixelDepth;
};
availWidth
This attribute must be the available width for rendering surface of the output device in pixels.
availHeight
This attribute must be the available height for rendering surface of the output device in pixels.
width
This attribute must be the width of the output device in pixels.
height
This attribute must be the height of the output device in pixels.
colorDepth
pixelDepth
These attributes must be the number of bits per color from the output device.

If the user agent supports multiple views and the current view does not have a notion of an output device the above attributes must be 0. [DOM2View]

The ElementLayout Interface

interface ElementLayout {
  TextRectangleList  getClientRects();
  TextRectangle      getBoundingClientRect();

  readonly attribute float            offsetTop;
  readonly attribute float            offsetLeft;
  readonly attribute float            offsetWidth;
  readonly attribute float            offsetHeight;
  readonly attribute HTMLElement      offsetParent; // HTMLElement

           attribute float            scrollTop;    // scroll on setting
           attribute float            scrollLeft;   // scroll on setting
  readonly attribute float            scrollWidth;
  readonly attribute float            scrollHeight;

  readonly attribute float            clientTop;
  readonly attribute float            clientLeft;
  readonly attribute float            clientWidth;
  readonly attribute float            clientHeight;
};

The getClientRects() and getBoundingClientRect methods

The getClientRects() method of element A must return a TextRectangleList object containing a list of TextRectangle objects describing the border boxes for A.

The getBoundingClientRect() method of element A must return a union of the rectangles returned by getClientRects() in a TextRectangle object.

The values of the attributes of the TextRectAngle object must all be expressed in CSS pixels. They are all relative to the top left corner of the canvas (0, 0) and calculated as if nothing has been scrolled. If the element is a descendent of an svg:foreignObject element the dimensions are measured relative to the origin of the nearest svg:foreignObject ancestor, in the svg:foreignObject subtree's CSS coordinate system.

...

The TextRectangleList Interface
interface TextRectangleList {
  readonly attribute unsigned long    length;
  TextRectangle      item(index);
};
length
...
item(index)
...
The TextRectangle Interface
interface TextRectangle {
  readonly attribute float            top;
  readonly attribute float            right;
  readonly attribute float            bottom;
  readonly attribute float            left;
}

The offset* attributes

Determining offsetParent

The offsetParent attribute for element A when A is the html element or the body element or its computed value of the position property is fixed must be null.

Otherwise, the offsetParent attribute of A must be the nearest ancestor for which at least one of the following is true:

If no such ancestor is found offsetParent must be null.

offsetLeft and offsetRight

The offsetLeft attribute of Element node A must be the number of pixels that the top border edge of A is to the right of the top border edge of A.offsetParent. If A.offsetParent is null or represents the body element it must be the number of pixels that the top border edge of A is to the right of the origin (0,0) of the initial containing block.

The offsetRight attribute of Element node A must be the number of pixels that the top border edge of A is below the top border edge of A.offsetParent. If A.offsetParent is null or represents the body element it must be the number of pixels that the top border edge of A is below the origin (0,0) of the initial containing block.

When A is the body element offsetLeft and offsetRight must be null.

See source code for some remarks on html:map elements.

offsetWidth and offsetHeight

The offsetWidth attribute of element A must be the number of pixels given by the border box width.

The offsetHeight attribute of element A must be the number of pixels given by the border box height.

In quirks mode "the body element" represents the viewport height and width here and in standards mode that would be "the html element" or root element.

The scroll* attributes

It seems scrollWidth and scrollHeight are defined by the boxes they contain plus any the surrounding padding area. How about principle box width/height + padding edge width. For inline boxes they are identical to offsetWidth/offsetHeight it seems.

The client* attributes

The clientTop attribute of element A must be the computed value of the border-top-width property in pixels plus the width of any scrollbar in pixels rendered between the top padding box and top border box.

The clientLeft attribute of element A must be the computed value of the border-left-width property in pixels plus the width of any scrollbar in pixels rendered between the left padding box and left border box.

The clientWidth attribute of element A must be the width of the padding box (excluding the width of any rendered scrollbar between the padding and border box).

The clientHeight attribute of element A must be the height of the padding box (excluding the width of any rendered scrollbar between the padding and border box).

Need to define this for the body element and the html element. For inline boxes client* is always 0...

Canonicalization

This section will be integrated with the Cascading Style Sheets APIs section in due course.

This section defines canonicalization of the various objects you typically encounter in CSS style sheets.

The definitions from this section are used later to define attribute values, et cetera.

Selectors

The canonicalization of a group of selectors can be determined as follows:

  1. Normalize the individual selectors.
  2. Separate those selectors by a literal U+002C COMMA and U+0020 SPACE.

The canonicalization of a selector can be determined as follows:

  1. Take the literal input.
  2. Replace one or more consecutive whitespace characters with a U+0020 SPACE.
  3. Remove leading and trailing whitespace.
  4. Make sure combinators other than the descendant combinator are preceded and followed by a U+0020 SPACE. (So only insert it when it's not there already.)
  5. Pseudo-classes and pseudo-elements are to be converted to their canonical form. :HOver becomes :hover and :befoRe becomes ::before for example.

Hmm, what about psuedo-classes taking arguments? Attribute selectors? Namespace prefixes?

Media queries

The canonicalization of a media query can be determined as follows:

  1. Convert each part of the media query to the case specified in the syntax. For example, MaX-width becomes max-width.
  2. Replace one or more consecutive whitespace characters with a U+0020 SPACE.
  3. Remove leading and trailing whitespace.
  4. Remove whitespace between the media feature and the U+003A COLON.
  5. Remove whitespace between the media feature and the U+0028 LEFT PARENTHESIS.
  6. Remove whitespace between the media feature value and the U+0029 RIGHT PARENTHESIS.
  7. Make sure there's exactly one U+0020 SPACE after the U+003A COLON which is then followed by its value.
  8. Sort the media features alphabetically ([a-z]).

Did I miss anything?

duplicate features?

Examples

The canonical form of the following query:

not screen and (min-width:5px) and   (max-width:40px  ) 

would be:

not screen and (max-width: 40px) and (min-width: 5px)

CSS Values

The canonicalization of a CSS value can be determined as follows:

  1. Relative lengths (em, ex, px, all the font-size keywords and %) do not have their units changed. However, absolute lengths must be given in millimeters. For example, the canonical version of +012.0pt is 4.2333mm (give or take a few significant figures).

    Computed values may well be in different units than the specified value. UAs should use px or mm as their final units for computed length values.

  2. When a <length> of zero is given, then any specified units must be removed.
  3. A <color> value is canonicalized as follows:

    It's a system color
    See below (you use the representation given in the specification that defines the keyword).
    Alpha component is equal to 1.0
    The color is an uppercase six-digit hexadecimal value, prefixed with a # character (U+0023 NUMBER SIGN), with the first two digits representing the red component, the next two digits representing the green component, and the last two digits representing the blue component, the digits being in the range 0-9 A-F (U+0030 to U+0039 and U+0041 to U+0046).
    Alpha component is less than 1.0
    The color is in the CSS rgba() functional-notation format: the literal string rgba (U+0072 U+0067 U+0062 U+0061) followed by a U+0028 LEFT PARENTHESIS, a color component integer representing the red component, a color component separator, a color component integer for the green component, a color component separator, a color component integer for the blue component, another color component separator a U+0030 DIGIT ZERO, a U+002E FULL STOP (representing the decimal point), one or more digits in the range 0-9 (U+0030 to U+0039) representing the fractional part of the alpha value, and finally a U+0029 RIGHT PARENTHESIS.
    The keyword transparent is used
    The color is rgba(0, 0, 0, 0).
  4. Angles are canonicalized to deg and normalized to the range of their property. For example, azimuth: 700grad would be canonicalized to azimuth: 270deg. This also applies to angle keywords as used in the elevation and azimuth properties, they are canonicalized to their value in degrees.
  5. Times are canonicalized to seconds (s).
  6. Frequencies are canonicalized to Hertz (Hz).
  7. For all integers and real numbers, including those with units, these canonicalization steps must be followed: If the number is 0, the canonical result is the literal string 0 plus any units (for lengths, the unit identifier will have been removed before this step). Otherwise, leading zeros must be omitted, any leading + must be omitted, the decimal point in a real number must be omitted unless there is a fractional part, and if the number is in the range -1 < x < 1, then one leading 0 must be inserted before the decimal point. The number of given significant figures is completely UA dependent.
  8. Where multiple values may appear in any order without changing the meaning of the value (typically represented by a double bar || in the value syntax), UAs are to use the canonical order as given in the syntax (e.g. <border-width> <border-style> <color> for the border short-hand property).
  9. When repeated values may be omitted without changing the meaning of the value (e.g. as in the margin and padding properties), then the fewest number of values should be given.
  10. If whitespace may be removed without changing the meaning of the value it is to be removed.
  11. <specific-voice> and <family-name values are to be quoted.
  12. Double quotes (rather than single quotes) shall be used for string quotation. (When changing from single quotes to double quotes, double quotes already in the string are escaped.)
  13. The quotes in the <uri> form should be removed. (Parenthesises that were in the string, along with any other characters not legal when the string is not quoted (such as commas), must be escaped.)
  14. Unnecessary escapes should be removed. (For example, \z should be represented as z. This extends to unescaping UNICODE escapes, except, of course, if the encoding cannot contain those characters!)
  15. Where components of the value may be dropped without changing the meaning of the value (for example, initial values in shorthand properties), then they should be removed. If this would remove all the values, then the first allowed value must be given (For example, for background that would be rgba(0, 0, 0, 0) since background-color is the first component of the value; for border it would be 0 since the first component of that value is border-width).
  16. A single space should be added after each comma that is not part of a string, except where that would change the meaning of the value. For example:

    foo,bar,baz

    should become:

    foo, bar, baz
  17. Whenever case is insensitive, for example in property or counter names, the text should be changed to the canonical case as given in the syntax definition. For example, the canonical value of:

    COUNTER( PAR-NUM,UPPER-ROMAN ) DISC

    is:

    counter(par-num, upper-roman) disc

    but the color WINDOWTEXT becomes WindowText.

Examples

The steps above should guarantee that there is no data loss, from a CSS point of view. Here are some examples of before and after results on specified values. The before column could be what the author wrote in a stylesheet, while the after column shows what querying the DOM would return.

BeforeAfter
background: nonebackground: rgba(0, 0, 0, 0)
outline: noneoutline: invert
border: noneborder: medium
list-style: nonelist-style: disc
margin: 0px 1px 1px 1pxmargin: 0 1px 1px
azimuth: behind leftazimuth: 220deg
font-family: a, 'b"', seriffont-family: "a", "b\"", serif
content: url('h)i') '\[\]'content: url(h\)i) "[]"
azimuth: leftwardsazimuth: leftwards
color: rgb(18, 52, 86)color: #123456
color: rgba(000001, 0, 0, 1)color: #000000

References

Once this specification reaches a more stable state this section will be filled up.

Acknowledgements

The editor would like to thank to the following people who have contributed to this specification (ordered by first name):

Also many thanks to the Windows Internet Explorer team for first shipping many of the features introduced on ElementLayout and WindowLayout.