:before是否不适用于img元素?


262

我正在尝试使用:before选择器将图像放置在另一个图像上,但是我发现将图像放置在一个img元素之前(仅放置在其他元素上)根本不起作用。具体来说,我的风格是:

.container
{
   position: relative;
   display: block;
}

.overlay:before
{
    content: url(images/[someimage].png);
    position: absolute;
    left:-20px;
    top: -20px;
}

我发现这很好用:

<a href="[url]" class="container">
  <span class="overlay"/>
  <img width="200" src="[url]"/>
</a>

但这不是:

<a href="[url]" class="container">
  <img width="200" src="[url]" class="overlay"/>
</a>

我可以使用divor p元素代替它span,浏览器可以将我的图像正确地覆盖在该img元素中的图像上,但是如果我将overlay类应用于img自身,则无法正常工作。

我希望这项工作能够成功进行,因为这会让我感到不span舒服,但更重要的是,我有大约100个我想修改的博客文章,如果可以修改样式表,我可以一次性完成,但是如果我必须返回并spanaimg元素之间添加一个额外的元素,这将需要做更多的工作。


5
这很奇怪,尤其是因为CSS标准本身给出了一个示例:使用IMG元素之前:…


@chharvey:这个问题是在这个问题之后提出的。
约书亚·弗兰克

Answers:


262

不幸的是,大多数浏览器不支持在img标签上使用:after:before

http://lildude.co.uk/after-css-property-for-img-tag

但是,您可以使用JavaScript / jQuery完成所需的工作。看看这个小提琴:

http://jsfiddle.net/xixonia/ahnGT/

$(function() {

    $('.target').after('<img src="..." />');

});

编辑

由于不支持此功能的原因,请查看coreyward的答案


3
你的小提琴不见了。这就是jsFiddle链接的优点。
Roko C. Buljan

解决它。对于那个很抱歉。
cwharris 2013年

1
这个答案没有解释为什么img之前或之后都没有。此外,建议的javascript解决方案也不适合替代它。
贾斯珀·肯尼斯

3
建议的解决方案并非在所有情况下都适用。这只是一个如何解决问题的示例。如果您想提出一个更通用的解决方案,请随时发布答案。
cwharris

141

之前和之后的伪选择器不会插入HTML元素,而是在目标元素的现有内容之前或之后插入文本。由于图像元素不包含文本或有后代,既不img:before或者img:after将你带来任何好处。这也是相同的元件的情况下<br><hr>出于同样的原因。


Img标签显然是其本身的元素,但是我们仍然可以使用:before和:after伪选择器在其他元素之前或之后插入它们。这不是CSS规范吗?
cwharris

13
有点不同。您可以插入图片,但不能使用图片标签-您必须使用content: url(/img/foo.jpg);语法。有关详细信息,请参见w3.org/TR/CSS21/generate.html
coreyward 2011年

4
较小的更正:它们插入伪元素,它们更像元素而不是文本节点。
克里斯·卡洛

生成的内容成为Shadow DOM的一部分。这些新元素,属性和文本节点非常真实。您可以在Chrome的检查器中查看它们。
Marc Diethelm 2014年

@coreyward也许您会相信MDN(已替换元素)的
Marc Diethelm

41

我找到了一种在纯CSS中实现此功能的方法:

我只是假的内容 -方法

启用img:after的纯CSS方法。

您可以查看 CodePen:我只是伪造的内容或查看

来源和摘要

img {
    /* hide the default image */
    height:0;
    width:0;

    /* hide fake content */
    font-size:0;
    color:transparent;

    /* enable absolute position for pseudo elements */
    position:relative;

    /* and this is just fake content */
    content:"I'm just fake content";
}

/* initial absolute position */
img:before,
img:after {
    position:absolute;
    top:0;
    left:0;    
}

/* img:before - chrome & others */
img:before {
    content:url(http://placekitten.com/g/250/250);
}

/* img:before - firefox */
body:not(:-moz-handler-blocked) img:before {
    padding:125px;
    background:url(http://placekitten.com/g/250/250) no-repeat;
}

/* img:after */
img:after {
    /* width of img:before */
    left:250px;

    content:url(http://lorempixel.com/350/200/city/1);
}
<img
    alt="You are watching the ~ I'm just fake content ~ method"  
/>

浏览器支持

✓Chrome 10以上版本

✓Firefox 11+

✓Opera 9.8+

✓野生动物园

没有支持

⊗Internet Explorer 8/9

请在其他浏览器中进行测试


1
因此,基本上,您只需在img标签的样式以及:before和:after的样式中添加content:“”即可开始工作。很好的发现,我想知道它是如何跨浏览器的。
w00t 2012年

2
我设置了一个图标测试jsbin.com/esewow/edit#html,live,我可以确认它在IE8上不起作用,但在Chrome和Safari上可以正常工作。
w00t 2012年

14
如果img标记的src无效,则CodePen示例仅在Firefox中有效-这会导致alt属性呈现为实际上允许:before和:after的元素。如果img src存在,它将停止工作:codepen.io/anon/pen/EjtDu
thenickdude

2
如果我错了,就阻止我,但似乎它不再适用于Chrome 46
Gyum Fox

5
img:before和img:after根本无法在Safari中使用。甚至没有,最初让我兴奋的是。好尝试。
Wray Bowling

9

由于<img>替换元素的性质,文档样式不会影响它。

无论如何要引用它,<picture>提供了一个理想的本机包装器,可以在其上附加伪元素,如下所示:

img:after, picture:after{
    content:"\1F63B";
    font-size:larger;
    margin:-1em;
}
<img src="//placekitten.com/110/80">

<picture>
    <img src="//placekitten.com/110/80">
</picture>


3

这是使用div容器存储img的另一种解决方案,同时:hover::after用于实现效果。

HTML如下:

<div id=img_container><img src='' style='height:300px; width:300px;'></img></div>

CSS如下:

#img_container { 
    margin:0; 
    position:relative; 
} 

#img_container:hover::after { 
    content:''; 
    display:block; 
    position:absolute; 
    width:300px; 
    height:300px; 
    background:url(''); 
    z-index:1; 
    top:0;
} 

要查看实际效果,请查看我创建的小提琴。如此您就知道这是跨浏览器友好的,并且无需使用“伪造的内容”来欺骗代码。


适用display: inline-block#img_container。这将使容器的宽度等于所有屏幕尺寸的图像。因此,您最终不会使:after内容漂浮在图像之外。
匿名

1

我认为,查看为什么此方法无效的最佳方法是:before和:after在将它们应用到的标记内的内容之前或之后插入它们的内容。因此,它可以与div或spans(或大多数其他标签)一起使用,因为您可以将内容放入其中。

<div>
:before
Content
:after
</div>

但是,img是一个自包含的,自动关闭的标签,并且由于它没有单独的关闭标签,因此您不能在其中添加任何内容。(那应该看起来像<img>Content</img>,但当然不起作用。)

我知道这是一个古老的话题,但是它首先出现在Google上,因此希望它可以帮助其他人学习。


1

这对我有用:

html

<ul>
    <li> name here </li>
</ul>

的CSS

ul li::before {
    content: url(../images/check.png);
}


1

::after 用于显示图像的后备图像


参见下面的示例,前2个img标记指向断开的网址。但是第二个显示的是备用图片,而不是浏览器中默认的损坏徽标。但是,我不确定这是否可行,我觉得要使其正常工作有点棘手。

img {
  position: relative;
  display: inline-block;
  width: 300px;
  height: 200px;
  vertical-align: top;
}
img:not(:first-child)::after {
  position: absolute;
  left: 0; top: 0; right: 0; bottom: 0;
  content: "<" attr(alt) "> NOT FOUND";
  border: 1px dashed #999;
  background: url(https://cdn.dribbble.com/users/1012566/screenshots/4187820/topic-2.jpg) center/100%;
}
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100x75" alt="logo">


0

试试这个代码

.button:after {
    content: ""
    position: absolute
    width: 70px
    background-image: url('../../images/frontapp/mid-icon.svg')
    display: inline-block
    background-size: contain
    background-repeat: no-repeat
    right: 0
    bottom: 0
}

-1

我尝试过,发现了一种更简单的方法。这是HTML:

    <img id="message_icon" src="messages2.png">
    <p id="empty_para"></p>

我要做的是<p>在图片标签之后放置一个空标签。现在,我将使用p :: before显示图像并根据需要定位。这是CSS:

#empty_para
{
    display:inline;
    font-size:40;
    background:orange;
    border:2px solid red;
    position:relative;
    top:-400px;
    left:100px;
}
#empty_para::before
{
    content: url('messages.png');
}

试试吧。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.