【问题标题】:Is anyone actually using css namespaces?有人真的在使用 css 命名空间吗?
【发布时间】:2012-05-29 00:26:32
【问题描述】:

人们似乎更喜欢 SMACSS 等技术来进行命名空间,而不是实际的 css namespaces 的原因是什么?

我已经用谷歌搜索了一段时间,但我一直无法找到任何好的资源。 (这让我担心我的 google-fu 是垃圾(很可能)或者 css 命名空间规范没用(不太可能))

【问题讨论】:

  • 我什至在When Can I Use? 上都没有看到它,而且我认为任何浏览器甚至都没有部分支持它......
  • @DominicBarnes — 处于推荐状态,这意味着它必须至少有两个独立的实现。
  • @Dominic Barnes:实际上,每个现代浏览器都支持它,包括 IE9+。我最近回答了一个关于 CSS 命名空间的问题,其中包含可以用来验证它是否有效的代码:stackoverflow.com/questions/9490155/… 我怀疑 CSS 命名空间没有出现在该站点上的主要原因是因为没有太多的实际用例它在当今的 Web 行业中,因为 HTML5 现在是很酷的新事物,它不以任何方式使用命名空间。
  • 好吧,xmlns 显然在 html5 中没有多大意义。 @Quentin 的回答将我引向规范的相关部分(第 3.2.3 节,编辑了他的答案以包含此内容),该部分解释了该属性基本上只是为了与 XHTML 解析器兼容。

标签: html css namespaces css-selectors


【解决方案1】:

它们涵盖了完全不同的用例。

CSS 命名空间用于将 CSS 应用于混合来自不同 XML 命名空间的元素的 XML 文档。例如这样您就可以毫无混淆地定位 <foo:p> 和 <bar:p>。

SMACSS 涵盖了编写不会干扰页面其他部分的稳健 CSS 的技术。例如这样地址簿 HTML 中的 .title 就不会与出版物 HTML 列表中的 .title 混淆。


更多详情来自spec:

注意:在 HTML 中,xmlns 属性绝对没有作用。它基本上是一个护身符。仅允许稍微轻松地迁移到 XHTML 和从 XHTML 迁移。当被 HTML 解析器解析时,属性最终没有命名空间,而不是像 XML 中的命名空间声明属性那样的“http://www.w3.org/2000/xmlns/”命名空间。

【讨论】:

  • @xiaoyi — HTML 没有命名空间。
  • HTML 确实有命名空间。就像使用 embed svg 和其他用例一样。
  • @xiaoyi:不,HTML 没有命名空间,因为 HTML 不是 XML。您可能在谈论 XHTML,它 基于 XML。
  • @xiaoyi — 嵌入 SVG 的 HTML 5 规则不使用命名空间。混合的 XHTML / SVG 文档仅处理 XML。
  • @Quentin 但是当与嵌入 SVG 交互时,您必须使用具有显式命名空间设置的 .createElementNS、.setAttributeNS。否则将无法正常工作。
【解决方案2】:

命名空间在 CSS 中有一种相当讨厌的语法,因为“:”命名空间字符必须用前导反斜杠转义以将其与伪类区分开来:

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

这只有在将 HTML 嵌入 XML 文档时才真正有用。添加 html 命名空间时,来自 HTML 命名空间的元素会正确显示,就像它们在 HTML 中的显示一样,允许访问 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>
    ...

在 HTML5 上下文中,我想不出您需要这个的任何情况。到目前为止,我在 CSS 中看到命名空间的唯一地方是 Webkit 用于 SVG 或 MathML 的默认 CSS,它们使用不同的语法:@namespace at-rule。

例如,这是来自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;
}

...

这是来自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
}

...

【讨论】:

    【解决方案3】:

    开始工作太麻烦了。解析 HTML 的浏览器会将所有内容都粘贴到默认命名空间中,但某些标记名称除外(例如:svg)。也就是说你可以在一个特殊的命名空间中创建一个元素:

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

    据我所知,HTML 解析器无法为您选择另一个命名空间。浏览器的 HTML 解析器创建的任何元素都是在默认命名空间中创建的。此外,一旦您转义 HTML 命名空间,它们就不再是 HTMLElement 元素。您不能只使用button 的标记名并期望它是具有所有样式、交互和属性的HTMLButtonElement。这也意味着没有像.innerText、.dir、.offsetTop 等HTML 属性。最大的一个是没有.style。这也意味着设置 style 属性什么都不做。您必须在 CSS 文件中指定所有样式。

    这实际上意味着这仅适用于非常有限的 XML 上下文,并不适用于一般的 HTML 内容。可能有一种方法可以让您的组件实现HTMLElement,尽管我还没有找到(也许是 Web 组件?)。尽管如此,这意味着您的所有元素都必须使用document.createElementNS 构建,这可能比寻找另一种方式来确定您的 CSS 组件范围要多得多。

    【讨论】:

      猜你喜欢
      • 2011-03-10
      • 2014-04-10
      • 1970-01-01
      • 2013-03-08
      • 2011-05-29
      • 2012-06-24
      • 2020-06-21
      • 2018-07-28
      • 1970-01-01
      相关资源
      最近更新 更多