Firefox 4: -moz-any() 选择器分组

这是来自 David Baron 博客 的转载文章。此功能已加入 Mozilla Central(主干),目前仅在 Firefox Nightly Build 中可用。

昨晚,我完成了对 :-moz-any() 选择器分组的支持。这允许在组合器之间提供备选方案,而不是必须重复整个选择器以改变其中一部分。例如,它允许将我们用户代理样式表中的以下规则

/* 3 deep (or more) unordered lists use a square */
ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
menu ol menu, menu ul menu, menu menu menu, menu dir menu,
menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
  list-style-type: square;
}

替换为以下规则

/* 3 deep (or more) unordered lists use a square */
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
  list-style-type: square;
}

理论上,我甚至可以使用

/* 3 deep (or more) unordered lists use a square */
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
  list-style-type: square;
}

但这样做会更慢,因为它不再属于 标签桶。(如果 :-moz-any() 变得流行,我们可以添加额外的代码使其同样快,但我还没有这样做。)

:-moz-any() 允许包含包含多个简单选择器的选择器(使用 css3-selectors 对简单选择器的定义,而不是 CSS 2.1 的定义),但不允许包含组合器或伪元素。因此,您可以编写 :-moz-any(p.warning.new, p.error, div#topnotice):-moz-any(:link, :visited).external:-moz-any(:active, :focus),但不能在 :-moz-any() 中放入“div p”或“div > p 或“:first-letter”。

使用 -moz- 前缀有两个原因。首先,它只是一个提案,还没有进入任何规范。其次,它还没有完全准备好投入使用,因为它还没有 正确处理特异性

注意:在 HTML5 上下文中,当涉及到部分和标题时,这将非常有用。由于 sectionarticleasidenav 可以嵌套,因此对不同深度的所有 h1 元素进行样式化可能会非常复杂。

/* Level 0 */
h1 {
  font-size: 30px;
}
/* Level 1 */
section h1, article h1, aside h1, nav h1 {
  font-size: 25px;
}
/* Level 2 */
section section h1, section article h1, section aside h1, section nav h1,
article section h1, article article h1, article aside h1, article nav h1,
aside section h1, aside article h1, aside aside h1, aside nav h1,
nav section h1, nav article h1, nav aside h1, nav nav h1, {
  font-size: 20px;
}
/* Level 3 */
/* ... don't even think about it*/

使用 -moz-any()

/* Level 0 */
h1 {
  font-size: 30px;
}
/* Level 1 */
-moz-any(section, article, aside, nav) h1 {
  font-size: 25px;
}
/* Level 2 */
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav) h1 {
  font-size: 20px;
}
/* Level 3 */
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav) h1 {
  font-size: 15px;
}

关于 Paul Rouget

Paul 是 Firefox 开发人员。

Paul Rouget 的更多文章…


27 条评论

  1. Warren Parsons

    很棒的想法!我真的希望它能流行起来,并且其他浏览器厂商将来也能采用它。

    IE?也许在 13 版本……也许。

    2010 年 5 月 18 日 下午 10:07

  2. JD

    我认为应该有一个功能来定义一组颜色,例如

    DEFINE(primaryColor:#CC3333);
    DEFINE(secondaryColor:#333333);

    .class{color:primaryColor;background:secondaryColor;}

    2010 年 5 月 18 日 下午 10:51

    1. Magne Andersson

      这以前被多次提出,称为“CSS 变量”。但是,最后决定这应该不属于 CSS 标准,至少不属于 CSS3 及以下版本。

      (可能是因为 CSS 应该是一种非常简单易用的语言,这很好,但仍然在某些方面限制了你。)

      2010 年 5 月 18 日 下午 2:35

  3. Magne Andersson

    这确实很棒,而且可能略微加快了渲染速度,但我对 -moz-cycle()/cycle() 表达式抱有最高期望(https://bugzilla.mozilla.org/show_bug.cgi?id=363250) ;-)

    2010 年 5 月 18 日 下午 12:38

  4. Andy L

    感谢您提供 moz-any(),Mozilla!

    我希望 Google Chrome/WebKit 也能尽快实现它,这样我就可以在 Web 应用程序中使用它。(对于 IE,我将使用 Chrome Frame。)

    Magne Andersson
    cycle() 确实会很有用!+1。

    2010 年 5 月 18 日 下午 2:29

  5. Barryvan

    我同意 Warren 的观点——看到这项功能传播到其他浏览器中将很棒。我特别欣赏的是它使 CSS 编写更简单——CSS3 的大部分内容都是关于用更少的标记和更好的语义使页面更漂亮,但很少有人关注使 CSS 本身更简单、更清晰、更优雅。

    干得好。

    2010 年 5 月 18 日 下午 5:01

  6. semper

    谢谢,干得好(一如既往),但有一点…

    > 首先,它只是一个提案,还没有进入任何规范。
    > 其次,它还没有完全准备好投入使用,因为它还没有
    > 正确处理特异性。

    我想知道这些是否是它使用 -moz- 前缀的真正原因?比较

    /* Level 2 */
    section section h1, section article h1, section aside h1, section nav h1,
    article section h1, article article h1, article aside h1, article nav h1,
    aside section h1, aside article h1, aside aside h1, aside nav h1,
    nav section h1, nav article h1, nav aside h1, nav nav h1, {
    font-size: 20px;
    }

    /* Level 2 */
    -moz-any(section, article, aside, nav)
    -moz-any(section, article, aside, nav) h1,
    -webkit-any(section, article, aside, nav)
    -webkit-any(section, article, aside, nav) h1,
    -o-any(section, article, aside, nav)
    -o-any(section, article, aside, nav) h1 {
    font-size: 20px;
    }

    是的,第二个仍然更短,但你知道我的意思。我同意前缀对于梯度之类的东西很有用,因为不同的解释和不同的语法是可能的,但在这里——它不是多余的吗?

    2010 年 5 月 19 日 上午 3:02

    1. voracity

      如果您在供应商前缀上执行等效于“:any”的操作将很棒。例如

      /* Level 2 */
      -[moz,webkit,o,none]-any(section, article, aside, nav)
      -[moz,webkit,o,none]-any(section, article, aside, nav) h1 {
      font-size: 20px;
      }

      这将使很多事情变得更轻松…

      2010 年 5 月 19 日 上午 4:52

      1. voracity

        实际上,稍微扩展一下这个想法

        .box {
        border-[left,top]: white 1px solid;
        border-[right,bottom]: black 1px solid;
        }

        2010 年 5 月 19 日 上午 4:56

        1. CyberSkull

          我喜欢你的想法!这将简化许多定义!:D

          2010 年 7 月 7 日 下午 10:11

    2. Magne Andersson

      根据 CSS 工作组的规定,在规范达到候选推荐状态之前,需要使用前缀。我们必须将其应用于受影响的属性。

      2010 年 5 月 19 日 上午 8:23

      1. zoe somebody

        在实现新的 HTML5 默认标记方案时,我发现 Firefox UA 样式表实际上已经使用 any() 选择器来调整嵌套在 html5 分区容器中的 h1 标签的大小,如上文所述(来自 html.css)

        h3, *:-moz-any(article, aside, nav, section) *:-moz-any(article, aside, nav, section) h1 { display: block; font-size: 1.17em; font-weight: bold; margin: 1em 0; }

        在测试我的标记方案之前,我发现 h1 标签在 FF 中与其他所有浏览器的尺寸并不相同。实际上,嵌套的 h1 被缩小到 h3 和 h4 的尺寸。

        虽然我个人非常欣赏 any() 选择器,并且希望出于这个原因使用它,但在 UA 样式表中实现它是不幸的,因为现在它又成了浏览器之间需要规范化的另一个东西。

        我支持将 any() 选择器纳入规范,但我不会希望浏览器在该额外格式化内容标准化之前应用任何额外格式化。

        我只是想在这里发布一下,因为当我开始弄清楚这个问题时,这是第一个搜索结果。

        2011 年 8 月 28 日 下午 10:43

        1. Paul Rouget

          这不是任何额外的格式化。这是规范的一部分(嵌套标题更小)。我们使用 :-moz-any 不会改变任何东西。我们可以使用更复杂的 selector 来实现相同的效果。

          2011 年 8 月 29 日 上午 2:24

  7. semper

    这是 RFC 2119 中的 MUST 吗?还是其他什么?我的意思是,它的真正意义是什么?
    对我来说,Web 如此棒,是因为这里的决定往往非常理性,而不是商业驱动、营销驱动,或其他任何驱动。
    顺便说一句,前缀问题之前已经被提出并积极讨论过(例如,请参阅 http://www.quirksmode.org/blog/archives/2010/03/css_vendor_pref.html)。

    2010 年 5 月 19 日 下午 2:37

    1. Magne Andersson

      这是 CSS 工作组的决定,所以是的,它是 MUST。

      2010 年 5 月 20 日 上午 0:59

  8. Giorgio

    供应商前缀是一件好事,因为并非所有实现都显示相同的结果,尤其是在非推荐功能上

    但如果 css 提供了用于浏览器嗅探的媒体查询

    @media user-agent matches(/blabla/) { }

    前缀可以删除… 我讨厌它们,但现在是唯一的方法

    2010 年 5 月 19 日 下午 3:49

  9. Matzipan

    您为什么要使用它呢?对我来说,这是一个无用的 selector,为什么要有组合列表?开发人员有责任保持 css 整洁,而不是浏览器添加更多功能并降低速度。

    2010 年 6 月 23 日 上午 10:57

  10. [...] 原作者: Paul Rouget – 返回原文 [...]

    2010 年 6 月 24 日 上午 8:30

  11. ZhouQi

    性能如何?

    2010 年 7 月 8 日 下午 8:47

  12. Steve

    我个人认为 any() 选择器将是 CSS 的一个很棒的补充,只要它对页面加载和渲染时间没有影响。另一方面,如果它被接受,我想它可能会进入 IE15,也许吧,而且会有 bug。
    感谢您如此简洁地解释。

    2010 年 12 月 23 日 上午 9:23

  13. 使用类别名称 […] 并不理想。为了让生活更轻松,以及让你的 CSS 更加易读,Mozilla 提出了一个 -any() 伪选择器。使用 -any(),我们可以像 […] 一样改写上面的公式。

    2011 年 4 月 8 日 上午 1:20

  14. Anton Agestam

    我希望语法更直观,为什么不直接去掉整个关键词部分,而是像这样写呢?

    (section|nav|aside) (section|nav|aside) h1{font-size:20px;}

    2011 年 4 月 11 日 上午 5:19

  15. Lars Gunther

    示例代码中 -moz-any 前面不是缺少冒号吗?

    2011 年 6 月 29 日 上午 8:42

  16. […] -moz-any() 选择器分组是 Mozilla 引入的,但它不是任何 CSS 规范的一部分(目前?);它是 […]

    2011 年 8 月 17 日 下午 10:45

  17. Poderwac

    感谢这些技巧,这正是我一直在寻找的… 我只希望它们也能在 Firefox 7 中工作。

    2011 年 10 月 3 日 上午 6:21

  18. Dave

    这以前被多次提出,称为“CSS 变量”。但是,最后决定这应该不属于 CSS 标准,至少不属于 CSS3 及以下版本。

    (可能是因为 CSS 应该是一种非常简单易用的语言,这很好,但仍然在某些方面限制了你。)
    4G LTE 手机

    2011 年 11 月 19 日 上午 9:57

  19. […] des W3C[2] http://www.w3.org/TR/selectors4/Selectors Level 4,W3C 工作草案[3] https://hacks.mozilla.ac.cn/2010/05/moz-any-selector-grouping/Mozillas 对 -moz-any() 选择器[4] http://dev.w3.org/csswg/css4-text/Selectors […]

    2012 年 2 月 13 日 上午 8:38

这篇文章的评论已关闭。