CSS Namespace Enhancements (Proposal)

W3C Working Draft 25 June 1999

This version
Latest version
Peter LinssNetscape Communications


This is a proposal for making CSS namespace-aware; such that styles can be applied to XML documents which use multiple namespaces, correctly selecting by the namespace used, regardless of the namespace prefix which happens to be used.

Status of this document

This document forms one part of a modular set of Working Drafts which will, when complete, define the next level of CSS. There is consensus in the W3C Working Group on CSS&FP that the functionality described in this document is important to improve formatting, especially printing, from the Web. There is not yet consensus on the CSS syntax for describing multicolumn layouts.

The W3C Membership and other interested parties are invited to review this public specification and report implementation experience. Please send comments to the publicly archived list www-style@w3.org (archive). We welcome experimental implementation experience reports, although the CSS Working Group will not allow early implementation to constrain its ability to make changes to this specification prior to final release.

This Working Draft may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than "work in progress". A list of current W3C Recommendations and other technical documents can be found at http://www.w3.org/TR.

Table of Contents

1. Objective

The goal is to provide the ability for CSS selectors to operate effectively against XML documents that make use of XML namespaces. This document defines a new at-rule, additional selector modifiers and a modification to the attr() value for the 'content' property. The following user/author needs are addressed:

  1. Ability to specify type selectors that apply to element types within a given namespace.
  2. Ability to specify attribute selectors that apply to attributes within a given namespace.
  3. Ability to address attributes within a given namespace with the attr() function.

For more information about XML namespaces, see Namespaces in XML.

1.1 Reasons For This Proposal

In XML namespaces, a namespace is identified solely by a URI reference. A prefix mechanism is defined to bind namespace URIs to XML names forming qualified names (see Namespaces in XML, Declaring Namespaces). Since namespace prefixes are defined within the XML document, and furthermore only apply to a limited scope within the document, the prefixes are not suitable for use outside the XML markup. Since a style sheet author can not, in general, know a priori which prefixes an XML author will map to a particular namespace, or to which namespace a particular prefix is bound in any given context, the stylesheet author must have some mechanism to identify namespaces by their URI.

In order to save stylesheet authors from using fully qualified URIs everywhere the use of a namespace is required, this proposal provides a mechanism for declaring a namespace prefix similar to that provided for XML. Note that, as in XML, the namespace prefix is merely a placeholder for the actual namespace URI, and all matching should be done based on the namespace URI, not the prefix.

While it is possible, given complete knowledge of the application of a given stylesheet, to construct a stylesheet that would properly match elements based on their qualified names, this is not generally recommended since it is trivial to construct scenarios where improper matching would be done. See section 5 for more information on constructing stylesheets that match elements without the use of namespace URIs.

1.2 Outstanding Issues

This is a work in progress, and as such, has not yet addressed all issues that have been raised with respect to adding namespace support to CSS. The following issues remain to be resolved:

  1. Allowing a default namespace construct in CSS.
  2. Application of selectors without namespace information.
  3. Adding a default namespace construct to @import as well as other style sheet linking mechanisms.

2. New At-rule

The @namespace rule allows the style sheet author to declare a namespace prefix and associate it to a given namespace URI. Any @namespace rules must follow all @import and @charset rules and precede all other rule sets in a style sheet. This is to avoid any confusion or issues regarding the scope of the declared namespace.

The syntax for the @namespace rule is as follows (using the CSS2 spec appendix D notations):


  : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*





With the new token:

"@namespace"              {return NAMESPACE_SYM;}

And the following modification to the stylesheet grammar:


  : [ CHARSET_SYM S* STRING S* ';' ]?

    [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*

    [ namespace [S|CDO|CDC]* ]*

    [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]*


If the optional namespace prefix is omitted, then the namespace URI is considered to be the default namespace. The default namespace applies only to type selectors that have no explicit namespace prefix declared.

A prefix, once declared, may be used in selectors and property values as described in the remainder of this document. Any use of a namespace prefix that has not been properly declared will result in the effected rule or property to be considered invalid and ignored.

If a namespace prefix is declared more than once, in accordance with normal cascading, the last occurrence will be used.


@namespace html url(http://www.w3.org/Profiles/xhtml1-strict);

@namespace url(http://www.w3.org/Profiles/xhtml1-transitional);

The first rule declares a namespace prefix "html" that is used to apply the namespace "http://www.w3.org/Profiles/xhtml1-strict" to selectors where the "html" namespace prefix is used in accordance with sections 3 and 4.

The second rule declares a default namespace "http://www.w3.org/Profiles/xhtml1-transitional" to be applied only to type selectors that have no explicit namespace component (see section 3.1).

3. Addition(s) To Current Selector Syntax

3.1 Type Selectors

Type selectors will be enhanced to allow an optional namespace component. A namespace prefix that has been previously declared (via @namespace) may be prepended to the element name separated by the namespace separator "|". The namespace component may be left empty to indicate that the selector is only to match elements with no declared namespace. Furthermore, an asterisk may be used for the namespace prefix, indicating that the selector is to match elements in any namespace (including elements with no namespace). Element type selectors that have no namespace component (no namespace separator), are considered to match without regard to the element's namespace (equivalent to "*|") unless a default namespace has been declared, in that case, selector will match only elements in the default namespace.

An alternative approach would be to define element type selectors that have no namespace component to match only elements that have no namespace (unless a default namespace has been declared in the CSS). This would make the selector "h1" equivalent to the selector "|h1" as opposed to "*|h1". The downside to this approach is that legacy style sheets (those written without any namespace constructs) will fail to match in all XML documents where namespaces are used throughout, i.e. all XHTML documents.

It should be noted that if a namespace prefix used in a selector has not been previously declared, then the selector must be considered invalid and the entire style rule will be ingored in accordance with the standard error handling rules.

It should further be noted that in a namespace aware client, element type selectors will only match against the local part of the element's qualified name. See section 5 for notes about matching behaviors in down-level clients.


@namespace foo url(http://www.foo.com);

foo|h1 { color: blue }

foo|* { color: yellow }

|h1 { color: red }

*|h1 { color: green }

h1 { color: green }

The first rule will match only "h1" elements in the "http://www.foo.com" namespace.

The second rule will match all elements in the "http://www.foo.com" namespace.

The third rule will match only "h1" elements without any declared namespace.

The last two rules are equivalent and will match "h1" elements in any namespace (including those without any declared namespace).

To accommodate namespace components of type selectors, the following modifications to the grammar are required:


  : [[ namespace_selector ]? element_name ]? [ HASH | class | attrib | pseudo ]* S*



  : [ namespace_prefix | '*' ]? '|'


3.2 Attribute Selectors

Attribute selectors will be enhanced to allow an optional namespace component to the attribute name. A namespace prefix that has been previously declared (via @namespace) may be prepended the the attribute name separated by the namespace separator "|". In keeping with the Namespaces in XML recommendation, default namespaces do not apply to attributes, therefore attribute selectors without a namespace component apply only to attributes that have no declared namespace (equivalent to "|attr"). An asterisk may be used for the namespace prefix indicating that the selector is to match all attribute names without regard to the attribute's namespace.


@namespace foo "http://www.foo.com";

[foo|att=val] { color: blue }

[*|att] { color: yellow }

[|att] { color: green }

[att] { color: green }

The first rule will match only elements with the attribute "att" in the "http://www.foo.com" namespace with the value "val".

The second rule will match only elements with the attribute "att" regardless of the namespace of the attribute (including no declared namespace).

The last two rules are equivalent and will match only elements with the attribute "att" where the attribute is not declared to be in a namespace.

To accommodate namespace components of attribute selectors, the following modifications to the grammar are required:


  : '[' S* [ namespace_selector ]? IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*

     [ IDENT | STRING ] S* ]? ']'


4. Addition(s) To Current Property Values

4.1 attr() Function

The attr() function (from the 'content' property) will be enhanced to allow an optional namespace component in the same manner as attribute selectors.


@namespace foo url(http://www.foo.com);

h1:before { content: attr(foo|att) }

The generated content to be inserted before "h1" elements will be the content of the element's "att" attribute declared in the "http://www.foo.com" namespace.

5. Information Regarding Down-Level Clients

An important issue is the interaction of CSS selectors with XML documents in web clients that were produced prior to this proposal. Unfortunately, due to the fact that namespaces must be matched based on the URI which identifies the namespace, not the namespace prefix, some mechanism is required to identify namespaces in CSS by their URI as well. Without such a mechanism, it is impossible to construct a CSS stylesheet which will properly match selectors in all cases against a random set of XML documents. However, given complete knowledge of the XML document to which a stylesheet is to be applied, and a limited use of namespaces within the XML document, it is possible to construct a stylesheet in which selectors would elements and attributes correctly.

It should be noted that a down-level CSS client will (if it properly conforms to CSS forward compatible parsing rules) ignore all @namespace rules, as well as all style rules that make use of namespace qualified element type or attribute selectors. The syntax of delimiting namespace prefixes in CSS was deliberately chosen so that down-level CSS clients would ignore the style rules rather than possibly match them incorrectly.

The use of default namespaces in CSS, makes it possible to write element type selectors that will function in both namespace aware CSS clients as well as down-level clients. It should be noted that down-level clients may incorrectly match selectors against XML elements in other namespaces.

The following are scenarios and examples in which it is possible to construct stylesheets which would function properly in web clients that do not implement this proposal.

  1. The XML document does not use namespaces.
  2. The XML document defines a single, default namespace used throughout the document. No namespace prefixes are used in element names.
  3. The XML document does not use a default namespace, all namespace prefixes used are known to the stylesheet author and there is a direct mapping between namespace prefixes and namespace URIs (a given prefix may only be mapped to one namespace URI throughout the XML document, there may be multiple prefixes mapped to the same URI).

In other scenarios: when the namespace prefixes used in the XML are not known in advance by the stylesheet author; or a combination of elements with no namespace are used in conjunction with elements using a default namespace; or the same namespace prefix is mapped to different namespace URIs within the same document, or in different documents; it is impossible to construct a CSS stylesheet that will function properly against all elements in those documents, unless, the stylesheet is written using a namespace URI syntax (as outlined in this document or similar) and the document is processed by a CSS and XML namespace aware client.