Marcus Stade
Marcus Stade

Reputation: 4984

Is anyone actually using css namespaces?

What are the reasons that people seem to prefer techniques such as SMACSS for namespacing, over actual css namespaces?

I've googled this for a bit, but I've been unable to come up with any good resources. (It makes me worried that either my google-fu is crap (very likely) or the css namespace spec is useless (less likely))

Upvotes: 31

Views: 27480

Answers (3)

ShortFuse
ShortFuse

Reputation: 6814

It's too much hassle to get working. Browsers that parse HTML stick everything into the default namespace with the exception of some tag names (eg: svg). That said you can create an element within a special namespace:

<html>
<head>
  <style>
    @namespace foo "http://foo";
    foo|div { color: red; }
  </style>
</head>
<body>
    <div>I'm an HTMLDIVElement</div>
</body>
<script>
  const div = document.createElementNS('http://foo', 'div');
  div.textContent = 'I am namespaced.';
  document.body.appendChild(div);
</script>
</html>

As far as I know, there's no way for the HTML parser to pick another namespace for you. Any element created by the browser's HTML parser is created in the default namespace. Also, once you escape the HTML namespace, they're no longer HTMLElement elements. You can't just use the tagname of button and expect it to be an HTMLButtonElement with all the stylings, interactions, and properties. That also means means no HTML properties like .innerText, .dir, .offsetTop, etc. And the biggest one is no .style. That also means setting a style attribute does nothing. You must specify all your styles in the CSS file.

This really mean this is just for really limited XML contexts and really not meant for general HTML content. There might be a way to make your components implement HTMLElement, though I haven't found one (maybe Web Components?). Still, that would mean all your elements must be constructed with document.createElementNS which is probably far more work than finding another way to scope your CSS components.

Upvotes: 0

John Slegers
John Slegers

Reputation: 47101

Namespaces have a rather nasty syntax in CSS, because the ":" namespace character must be escaped by a leading backslash to differentiate it from a pseudo-class:

html\:img {
  border: 2px solid black;
}
html\:a:visited html\:img {
  border-color: grey;
}

This is only really useful when embedding HTML inside an XML document. When adding the html namespace, elements from the HTML namespace are correctly displayed as they would appear in HTML, allowed access to capabilities that are not yet provided by CSS.

<story xmlns:HTML="http://www.w3.org/Profiles/XHTML-transitional">
  ...
  <restaurant>
    <name>Red Apple Inn</name>
    <logo>
      <HTML:A href="javascript:alert('Visit the Red Apple Inn!')">
        <HTML:IMG src="red-apple.gif" height="50" width="200"/>
      </HTML:A>
    </logo>
    ...

In an HTML5 context, I can't think of any cases where you would need this. The only place where I've seen namespaces in CSS so far, is Webkit's default CSS for SVG or MathML, and they use a different syntax : the @namespace at-rule.

For example, this is code from WebKit/webkit/blob/master/Source/WebCore/css/mathml.css :

@namespace "http://www.w3.org/1998/Math/MathML";

math {
    -webkit-line-box-contain: glyphs replaced;
    text-indent: 0;
    direction: ltr;
}
mtext {
    line-height: 1.0;
}

...

This is code from WebKit/webkit/blob/master/Source/WebCore/css/svg.css :

@namespace "http://www.w3.org/2000/svg";
@namespace html "http://www.w3.org/1999/xhtml";

svg:not(:root), symbol, image, marker, pattern, foreignObject {
    overflow: hidden
}

svg:root {
    width: 100%;
    height: 100%
}

text, foreignObject {
    display: block
}

...

Upvotes: 5

Quentin
Quentin

Reputation: 943769

They cover completely different use cases.

CSS namespaces are for applying CSS to XML documents that mix elements from different XML namespaces. e.g. so you can target <foo:p> and <bar:p> without confusion.

SMACSS covers techniques for writing robust CSS that doesn't interfere with other parts of the page. e.g. so that .title in your address book HTML doesn't get muddled with .title in your list of publications HTML.


Further details from the spec:

Note: In HTML, the xmlns attribute has absolutely no effect. It is basically a talisman. It is allowed merely to make migration to and from XHTML mildly easier. When parsed by an HTML parser, the attribute ends up in no namespace, not the "http://www.w3.org/2000/xmlns/" namespace like namespace declaration attributes in XML do.

Upvotes: 30

Related Questions