12

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

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

4

3 回答 3

18

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

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

您可以得到的最接近的方法是将实际元素包装在您想要使用容器为其设置样式的元素周围......这可以通过例如 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 预览

但是,有一些警告:

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

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

    article > p
    

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

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

于 2012-05-03T03:55:36.783 回答
2

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

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

没有这么多变量或函数调用,它更干净更简单。

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

在li里面添加ap,避免了破坏子选择器的问题

于 2012-11-16T16:33:06.527 回答
2

我终于将此片段添加到我的页面:

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

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

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

于 2012-05-03T10:55:37.493 回答