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.

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 must be the style sheet media type of the style sheet.

Which specification defines what the media type of a style sheet is?

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 UAs 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 2.1 specification. [CSS21]

Introduction

A CSS style sheet consists of zero or more statements. A statement is either a ruleset or an at-rule. A ruleset consists of a group of selectors with a declaration block associated with it. A declaration block consists of multiple declarations. A declaration consists of a property and a value.

Each at-rule has its own syntax.

This specification generally refers to statements as rules or CSS rules.

Do we need pointers here, explaining each?

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 that holds references to each top level CSSRule in the style sheet, including rule sets and at-rules.
insertRule(rule, index), method
This method must raise a SYNTAX_ERR exception if rule contains a syntax error. If the rule is valid, but is inserted at a point where it can't occur (@import is inserted after a normal rule set) a HIERARCHY_REQUEST_ERR exception must be raised. If the specified index is not a valid insertion point a INDEX_SIZE_ERR exception must be raised. Otherwise, the rule must be inserted at given index.
deleteRule(index), method
This method must raise a INDEX_SIZE_ERR exception if the given index does not correspond to a rule in the style sheet. Otherwise, it must remove the rule at index.

The CSSRuleList Interface

In bindings that allow it, enumerating a CSSRuleList object must enumerate through the currently stored and accessible 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 rules in the object.
item, method
This method must return the CSSRule in the list given by index using an ordinal index or null otherwise.

Interfaces For CSS Rules

This section defines several specific interfaces and one generic for different types of CSS rules.

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 any of the defined constants.
cssText of type DOMString

This attribute must be a live textual representation of the style rule.

On setting a SYNTAX_ERR exception must be raised if the given rule has a syntax error (was not parsable per CSS). When set to a different type of rule a INVALID_MODIFICATION_ERR exception must be raised. Otherwise, the value becomes the setted value.

Formatted how? When would you get a HIERARCHY_REQUEST_ERR exception here?

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
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 one 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
This attribute must contain a textual representation of the group of selectors for the declaration block. On setting, a SYNTAX_ERR exception must be raised if the selector was not parsable. Otherwise, it must be set to the specified value.
style of type CSSStyleDeclaration, readonly
This attribute must be a live reference to the declaration block for the current rule set.

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 MediaList containing a list of media types for which the style sheet to be imported may be used.
styleSheet of type CSSStyleSheet, readonly
This attribute must be the StyleSheet object loaded or null otherwise.

The CSSMediaRule Interface

The @media at-rule is represented as a single statement in the CSS style sheet that contains zero or more rulesets (not at-rules) 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
This method must raise a SYNTAX_ERR exception if rule contains a syntax error. If the rule is valid, but is inserted at a point where it can't occur (any at-rule) a HIERARCHY_REQUEST_ERR exception must be raised. If the specified index is not a valid insertion point a INDEX_SIZE_ERR exception must be raised. Otherwise, the rule must be inserted at given index and the index must be returned.
deleteRule(index), method
This method must raise a INDEX_SIZE_ERR exception if the given index does not correspond to a rule in the style sheet. Otherwise, it must remove the rule at index.

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 rule set.

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 the computed style ([CSS21]) 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 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

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, in DOMString priority);
  readonly attribute unsigned long    length;
  DOMString          item(in unsigned long index);
  readonly attribute CSSRule          parentRule;
};

...

The CSS2Properties Interface

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

The CSSStyleDeclarationProperties Interface

interface CSSStyleDeclarationProperties {
           // This list will be updated when more CSS property related
           // specifications become stable (for example, W3C Recommendation).

           attribute CSSAngleValue    azimuth;
           attribute CSSColorValue    backgroundColor;
           attribute CSSURLValue      backgroundImage;
           // backgroundPosition?
           // borderSpacing?
           attribute CSSColorValue    borderTopColor;
           attribute CSSColorValue    borderRightColor;
           attribute CSSColorValue    borderBottomColor;
           attribute CSSColorValue    borderLeftColor;

           // what is border takes a percentage as value in CSS3/CSS4???
           // perhaps percent should be part of length but sometimes disabled
           // based on binding specific knowledge
           attribute CSSLengthValue   borderTopWidth;
           attribute CSSLengthValue   borderRightWidth;
           attribute CSSLengthValue   borderBottomWidth;
           attribute CSSLengthValue   borderLeftWidth;

           attribute CSSLengthAndPercentageValue  bottom;

           // clip?
           attribute CSSColorValue    color;
           // content?

           attribute CSSURLValue      cueAfter;
           attribute CSSURLValue      cueBefore;
           attribute CSSURLValue      cursor;
           attribute CSSAngleValue    elevation;
           attribute CSSLengthAndPercentageValue  fontSize;
           // Number fontWeight?
           attribute CSSLengthAndPercentageValue  height;
           attribute CSSLengthAndPercentageValue  left;
           attribute CSSLengthValue   letterSpacing;
           // lineHeight CSSLengthAndPercentageAndNumberValue???!
           attribute CSSURLValue      listStyleImage;

           // \/ TRouBLe, haha
           attribute CSSLengthAndPercentageValue  marginTop;
           attribute CSSLengthAndPercentageValue  marginRight;
           attribute CSSLengthAndPercentageValue  marginBottom;
           attribute CSSLengthAndPercentageValue  marginLeft;

           attribute CSSLengthAndPercentageValue  maxHeight;
           attribute CSSLengthAndPercentageValue  maxWidth;
           attribute CSSLengthAndPercentageValue  minHeight;
           attribute CSSLengthAndPercentageValue  minWidth;
           // orphans ...
           attribute CSSColorValue    outlineColor;
           attribute CSSLengthValue   outlineWidth;
           attribute CSSLengthAndPercentageValue  paddingTop;
           attribute CSSLengthAndPercentageValue  paddingRight;
           attribute CSSLengthAndPercentageValue  paddingBottom;
           attribute CSSLengthAndPercentageValue  paddingLeft;

           attribute CSSTimeAndPercentageValue  pauseAfter;
           attribute CSSTimeAndPercentageValue  pauseBefore;
           // pitchRange?
           attribute CSSFrequencyValue  pitch;

           attribute CSSURLValue      playDuring;
           // Number richness?

           attribute CSSLengthAndPercentageValue  right;
           // speechRate?
           // stress?

           attribute CSSTimeAndPercentageValue  textIndent;
           attribute CSSLengthAndPercentageValue  top;
           attribute CSSLengthAndPercentageValue  verticalAlign;

           attribute CSSLengthAndPercentageValue  width;
           // volume?
           // widows?

           attribute CSSLengthValue   wordSpacing;
           // z-index?

};

CSS value related interfaces

...

The CSSPropertyValue Interface

interface CSSPropertyValue {
           attribute DOMString        cssText;
};

...

The CSSColorPropertyValue Interface

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

The CSSURLPropertyValue Interface

interface CSSURLPropertyValue : CSSPropertyValue {
           attribute DOMString        url;
  readonly attribute DOMString        absoluteUrl;
};

The CSSLengthPropertyValue Interface

interface CSSLengthPropertyValue : CSSPropertyValue {
           attribute float            em;
           attribute float            ex;
           attribute float            px;
           attribute float            cm;
           attribute float            mm;
           attribute float            pt;
           attribute float            pc;
};

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

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. Otherwise, this must be 0.
outerHeight
In web browsers, this attribute must be the height of the browser window. 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.

The terminology used in this subsection is that of Media Queries. [MQ]

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.
height
This attribute must be the height of the output device.
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;

};

interface TextRectangleList {
  readonly attribute unsigned long    length;
  TextRectangle      item(index);
};

interface TextRectangle {
  readonly attribute float            top;
  readonly attribute float            right;
  readonly attribute float            bottom;
  readonly attribute float            left;
}

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