我希望能够使用::outside
伪元素,但显然没有主流浏览器支持它(基于我今天的测试)。
是否有某种JS polyfill启用此选择器?或者有一种很好的模拟技术吗?
答案 0 :(得分:18)
你是对的:现有的浏览器都没有实现古代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;
}
但是有一些警告:
这在很大程度上取决于DOM;根据具体情况,你将无法将某些元素包裹在其他元素周围。即使你可以,那些包装元素也可能最终干扰行为甚至是实际父元素的样式。
例如,它会阻止您在以下情况下使用子选择器:
article > p
您打算jQuery.wrap()
这些p
元素的位置,因为那些包装元素会破坏article
和p
之间的父子关系。
规范声明::outside
伪元素(如::before
和::after
)应该从生成它们的元素继承样式。如果使用JavaScript / jQuery添加包装器,那些包装器将继承其父元素的样式,而不是它们包装的样式。在填充::before
和::after
时,这一直是一个问题,因为它们无论如何都应该作为子元素插入,通常遵循继承规则。
答案 1 :(得分:2)
我最后将这个代码段添加到了我的页面:
$('ol > li').each(function(){
var $this = $(this);
var $content = $($this.contents());
$content.wrapAll('<p class="liwrap"/>');
});
这会在p
中添加li
,这可以避免破坏子选择器的问题,并且需要为类提供深奥的名称(因为没有父选择器)。它还避免了不继承样式的问题,因为::outside
可以替换为::before
。
要获得正确的视觉效果,需要使用负边距将内部p
提升到生成内容的级别。
答案 2 :(得分:2)
看起来你正在使用jQuery,在这种情况下,我建议对你的代码进行一些小修改
$('ol > li').wrapInner("<p class='liwrap' />");
如果没有那么多变量或函数调用,它会更简洁,更简单。
编辑: 正如我们正确地指出的那样,这是对Marcins解决方案的优化......
在li中添加了一个p,这避免了破坏子选择器的问题