Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.
While they seem like two parts of the same thing, CSS can style more than HTML. Think about other XML dialects like MathML and SVG, which can be used in the same document as HTML.
The @namespace
at-rule can make a stylesheet target only one of those dialects. It works by declaring which dialect to scope using a namespace, which can be prefixed to match specific selectors, or non-prefixed to match every selector in the stylesheet.
/* Unprefixed @namespace */
@namespace "http://www.w3.org/1998/Math/MathML";
* {
/* Styles for only MathML elements */
}
*|p {
/* Styles for p elements in any namespace*/
}
Syntax
@namespace <namespace-prefix>? [ <string> | <url> ] ;
<namespace-prefix> = <ident>
Per spec, “Any @namespace
rules must follow all @charset
and @import
rules and precede all other non-ignored at-rules and style rules in a style sheet.” In short, write your @namespace
before using any selector.
Arguments
/* Non-Prefixed */
@namespace "http://www.w3.org/1998/Math/MathML";
@namespace url("http://www.w3.org/2000/svg");
/* Prefixed */
@namespace math "http://www.w3.org/1998/Math/MathML";
@namespace svg url("http://www.w3.org/2000/svg");
<namespace-prefix>
: This is an ident used to match specific selectors to the namespace. If skipped, then all selectors will be on the declared namespace.- Namespace URI: This is the direction of the desired namespace. It can be enclosed in an
url()
or just written as a string.
While the namespace URI is formatted as a URL, it is treated as a string to identify each namespace. For example, if we visit the SVG Namespace URL, we will be greeted by a short explanation of SVG, not actual code, so @namespace
doesn’t retrieve anything from the web. Why are they written as URLs then? Just by convention and because URLs were a familiar way to write unique identifiers.
@namespace
?
Why even In my years-long relationship with CSS, I don’t think I have ever written a single @namespace
rule, and you probably haven’t either. Some even think that @namespace
is an outdated feature, and while it isn’t the most used, I assure you that’s far from the truth.
As Bert Bos, CSS Lead since 1995 in the W3C, explained:
The Namespaces module is very small, very simple, and probably rarely needed, but just because it is simple, it doesn’t cost much to add it to CSS. Indeed, many browsers have supported it for a long time already. The only thing it defines is how to declare an XML Namespace prefix in CSS. That is needed if you want to use selectors that only match elements in a certain namespace.
While paradoxical, we can write more than HTML in a .html
document. Think about SVG, which is directly written in the markup and follows a similar tag/attribute syntax as HTML, but is an XML dialect. Each supported XML dialect is tied with a namespace: an identifier in the shape of a URL. For example, SVG uses "http://www.w3.org/2000/svg"
and MathML (a dialect to display math equations) uses "http://www.w3.org/1998/Math/MathML"
Having more than one XML dialect in the same document brings the question, how do we style each one in CSS? Especially when SVG shares some elements with HTML, like the <a>
tag. Here is when @namespace
comes in, allowing us to scope our CSS to a specific namespace so it only matches elements from that XML dialect.
Basic usage
If we are planning to write HTML involving MathML, we may want a dedicated stylesheet. To do so, we can write the @namespace
at-rule followed by the "http://www.w3.org/1998/Math/MathML"
namespace, so all selectors on that stylesheet only match MathML elements. So something like the universal selector (*
) will match all MathML elements instead of all the HTML elements:
@namespace "http://www.w3.org/1998/Math/MathML";
* {
background-color: lch(80 80 340deg);
font-size: 20px;
}
In the same stylesheet, we can opt out and select elements from any other namespace using the namespace separator selector (|
). On its left side, it takes the namespace to target, and on its right side, the selectors to match. In this case, we can use the universal namespace (*
) on the left to match any namespace:
*|p {
/* Styles any <p> elements */
}
We can prefix our @namespace
rules so it only scopes specific selectors. For example, if we bring the "http://www.w3.org/2000/svg"
namespace and prefix it with a svg
name, we can specify which selectors it should scope using the namespace separator (|
), with the corresponding prefix on its left.
@namespace svg "http://www.w3.org/2000/svg";
svg|a {
/* Only svg <a> elements */
}
a {
/* All <a> elements */
}
If we only want to target HTML elements we can use the HTMLX namespace ("http://www.w3.org/1999/xhtml"
), which isn’t exactly HTML but does hold all HTML tags.
@namespace svg "http://www.w3.org/2000/svg";
@namespace html "http://www.w3.org/1999/xhtml";
html|a {
/* Only html <a> elements */
}
svg|a {
/* Only svg <a> elements */
}
Namespaces are scoped to the stylesheet in which they are declared, so it doesn’t affect any stylesheet we import, or other stylesheets applied to the same document.
List of namespaces
There are a lot of XML dialects, but just a few can be directly written in HTML 5 and even fewer are commonly used. Then 99% of the time you’ll use one of these namespaces:
- The HTML namespace is: http://www.w3.org/1999/xhtml
- The MathML namespace is: http://www.w3.org/1998/Math/MathML
- The SVG namespace is: http://www.w3.org/2000/svg
- The XML namespace is: http://www.w3.org/XML/1998/namespace
Demo
Specification
While namespaces are a XML-related term declared in other web documents, the @namespace
at-rule is declared in the CSS Namespaces Module Level 3, currently on Editor’s Draft.
Browser support
More information
- Spacing Out on CSS Namespaces (Divya Manian)