启用对 CSS3 ::outside 伪元素的支持

Posted

技术标签:

【中文标题】启用对 CSS3 ::outside 伪元素的支持【英文标题】:Enable support for CSS3 ::outside pseudoelement 【发布时间】:2012-05-12 06:33:59 【问题描述】:

我希望能够使用::outside 伪元素,但显然没有主流浏览器支持它(根据我今天的测试)。

是否有某种 JS polyfill 可以启用此选择器?或者有没有很好的技术来模拟这个?

【问题讨论】:

::outside?我从来没有听说过这个选择器。您是否有指向某种解释它的文档的链接? @animuson w3.org/TR/css3-content/#wrapping @animuson:所有从 CSS3 开始的新伪元素都被移到了它们各自的模块中,所以::outside从未出现在选择器中。 @Marcin:您应该添加对 ::outside 伪元素的用途的解释。我认为它应该是CSSWG GitHub issue tracker 上要求的包装元素。 确实有。 css3-content 现在重定向到带有最新草稿的 css-content-3,近一年来,该草稿仅在 drafts.c​​sswg.org 上可用。 @Sebastian Zartner:你仍然可以在这里找到旧的草稿:w3.org/TR/2003/WD-css3-content-20030514 【参考方案1】:

您是对的:现有的浏览器没有实现古老的CSS3 Generated and Replaced Content module 中的任何新功能,因此您将无法尝试建议的伪元素。事实上,他们正计划重写模块本身,因此当前的工作草案应该被视为放弃,不幸的是,这些提议的功能的命运尚无定论。

无论如何,我也不知道有任何 JS polyfill 可用于这些伪元素,因此您在 CSS 中使用 ::outside 编写选择器时运气不佳。

你能得到的最接近的方法是用容器将实际元素包裹在你想要为其设置样式的元素周围......这可以通过例如 jQuery 的.wrap().wrapAll() 以低成本实现。

所以,不要这样做:

p::outside 
    display: block;
    border: 3px solid #00f;

你会这样做:

$('p').wrap('<div class="outside-p" />');
/* 
 * Notice that you can't select only .outside-p that contains p:only-child,
 * so you'll have to come up with esoteric class names.
 */
.outside-p 
    border: 3px solid #00f;

jsFiddle preview

不过,有一些注意事项:

这在很大程度上取决于 DOM;根据具体情况,您将无法将某些元素包裹在其他元素周围。即使可以,这些包装元素最终也可能会干扰实际父元素的行为甚至样式。

例如,它会阻止您在以下情况下使用子选择器:

article > p

您打算将jQuery.wrap() 那些p 元素放在哪里,那么这些包装元素将破坏articlep 之间的父子关系。

规范指出::outside 伪元素,如::before::after,应该从生成它们的元素继承样式。如果您使用 javascript/jQuery 添加包装器,这些包装器将继承其父元素的样式,而不是它们正在包装的元素。这在填充 ::before::after 时从来都不是问题,因为它们无论如何都打算作为子元素插入,通常遵循继承规则。

【讨论】:

查看我的答案,我认为它解决了围绕::outside 的目标的几个问题。 为什么是低优先级?它不会让编写真正干净的 html 变得轻而易举吗?我讨厌有时您只需要将元素包装在 div 中即可获得所需的样式效果。 @Cameron Martin:显然,人们更关心动画、flexbox 和所有爵士乐。 值得注意的是,您预测的重写已经发生,而这似乎不再存在。【参考方案2】:

我终于把这个 sn-p 添加到我的页面了:

  $('ol > li').each(function()
        var $this = $(this);
        var $content = $($this.contents());
        $content.wrapAll('<p class="liwrap"/>');
  );

这在li 内部添加了一个p,这样就避免了破坏子选择器的问题,并且需要对类进行深奥的名称(因为没有父选择器)。也避免了不继承样式的问题,因为::outside可以替换为::before

然而,为了获得正确的视觉效果,需要负边距来将内部p 提升到生成内容的水平。

【讨论】:

【参考方案3】:

看起来您正在使用 jQuery,在这种情况下,我建议对您的代码进行一些小修改

$('ol > li').wrapInner("<p class='liwrap' />");

它更简洁,更简单,没有那么多变量或函数调用。

编辑: 正如 awe 正确指出的那样,这是对 Marcins 解决方案的优化......

在li里面加一个p,避免了破坏子选择器的问题

【讨论】:

澄清一下:这是对Marcins answer 中解决方案的改进。有关如何解决原始问题的更多详细信息,请参阅他的答案。

以上是关于启用对 CSS3 ::outside 伪元素的支持的主要内容,如果未能解决你的问题,请参考以下文章

CSS3 选择器

伪类和伪元素

CSS中一个冒号和两个冒号的区别

css3的伪(伪类和伪元素)大合集

CSS3 伪元素的使用

CSS3伪元素伪类选择器