【问题标题】:Does :before not work on img elements?:before 不适用于 img 元素吗?
【发布时间】:2026-02-23 12:35:01
【问题描述】:

我正在尝试使用 :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>

我可以使用divp 元素代替span,并且浏览器正确地将我的图像覆盖在img 元素中的图像上,但是如果我将覆盖类应用于@987654331 @ 本身,它不起作用。

我想让这个工作,因为额外的 span 冒犯了我,但更重要的是,我有大约 100 篇博客文章我想修改,如果我可以一次性完成可以只修改样式表,但如果我必须返回并在aimg 元素之间添加一个额外的span 元素,这将是更多的工作。

【问题讨论】:

标签: html css


【解决方案1】:

不幸的是,大多数浏览器不支持在 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's answer

【讨论】:

  • 你的小提琴不见了。这就是 jsFiddle 链接的美妙之处。
  • 这个答案没有解释为什么 img 不能有之前或之后。此外,建议的 javascript 解决方案也不是它的合适替代品。
  • 建议的解决方案并不适用于所有场景。这只是一个如何规避问题的示例。如果您想提出更通用的解决方案,请随时发布答案。
  • 我最终实现了这个解决方案,但是我遇到了一个问题。运行后加载的某些内容(例如稍后加载的 ajax 内容)也需要再次运行。我在注意到这一点的页面上遇到了一些延迟加载的资产。这是解决问题的最佳方法。不幸的是,在搜索之前花了将近一个小时尝试调试 CSS 问题。
【解决方案2】:

before 和 after 伪选择器不插入 HTML 元素——它们在目标元素的现有内容之前或之后插入文本。因为图像元素不包含文本或没有后代,img:beforeimg:after 都不会对你有任何好处。出于同样的原因,&lt;br&gt;&lt;hr&gt; 等元素也是如此。

【讨论】:

  • Img 标签本身就是元素,但我们可以使用 :before 和 :after 伪选择器在其他元素之前或之后插入它们。这不在 css 规范中吗?
  • 这有点不同。您可以插入图像,但不能使用图像标签——您必须使用content: url(/img/foo.jpg); 语法。详情请见w3.org/TR/CSS21/generate.html
  • 小修正:他们插入伪元素,它们更像元素而不是文本节点。
  • 生成的内容成为 Shadow DOM 的一部分。那些新的元素、属性和文本节点是非常真实的。您可以看到它们,例如在 Chrome 的检查器中。
  • @coreyward 也许你会信任MDN (Replaced Element)
【解决方案3】:

我找到了一种在纯 css 中完成这项工作的方法:

我只是假内容-方法

启用 img:after 的纯 CSS 方法。

您可以查看 CodePen: I'm just fake content 或查看来源

来源和片段

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+

✓ Safari

不支持

⊗ Internet Explorer 8 / 9

请在其他浏览器中测试

【讨论】:

  • 所以基本上你只需将 content:"" 添加到 img 标签的样式中,并且 :before 和 :after 开始工作。很好的发现,我想知道它是如何跨浏览器的。
  • 我设置了一个图标测试jsbin.com/esewow/edit#html,live,我可以确认它不能在 IE8 上运行,但在 Chrome 和 Safari 上运行良好。
  • CodePen 示例仅在 img 标签的 src 无效的情况下在 Firefox 中有效 - 这会导致 alt 属性呈现为实际允许 :before 和 :after 的元素。如果 img src 存在,它将停止工作:codepen.io/anon/pen/EjtDu
  • 如果我错了就阻止我,但它似乎不再适用于 Chrome 46
  • img:before 和 img:after 在 Safari 中根本不起作用。甚至这个,最初让我兴奋的。不错的尝试。
【解决方案4】:

由于&lt;img&gt;replaced element 的性质,文档样式不会影响它。

无论如何都要引用它,&lt;picture&gt; 提供了一个理想的本地包装器,可以附加伪元素,如下所示:

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>

【讨论】:

  • 这是可行的,但如果我们需要确切的 img 标签,那么这个解决方案将无济于事。
【解决方案5】:

这是另一个使用 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;
} 

要查看它的实际效果,请查看我创建的fiddle。只是为了让您知道这是跨浏览器友好的,并且无需使用“虚假内容”来欺骗代码。

【讨论】:

  • 申请display: inline-block#img_container很有帮助。这将使容器的宽度等于所有屏幕尺寸的图像。因此,您最终不会让 :after 内容漂浮在图像之外。
【解决方案6】:

::before 和 ::after 生成的伪元素包含在元素的格式化框内,因此不适用于 img 等替换元素或 br 元素。

https://developer.mozilla.org/en-US/docs/Web/CSS/::after

【讨论】:

    【解决方案7】:

    我认为了解为什么这不起作用的最佳方法是 :before 和 :after 在您应用它们的标签内的内容之前或之后插入它们的内容。因此它适用于 div 或 span(或大多数其他标签),因为您可以将内容放入其中。

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

    然而,img 是一个自包含、自闭合的标签,由于它没有单独的闭合标签,所以你不能在里面放任何东西。 (这需要看起来像 &lt;img&gt;Content&lt;/img&gt;,但这当然行不通。)

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

    【讨论】:

      【解决方案8】:

      ::after可以用于显示图片的后备图片


      参见下面的示例,前 2 个 img 标记指向损坏的 url。但是第二个显示的是后备图像,而不是浏览器中默认的损坏徽标。但是,我不确定这是否实用,我觉得让它正常工作有点棘手。

      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">

      【讨论】:

      • 结果如下:i.imgur.com/TyG2zxy.png。但它看起来只适用于第二个 img,因为它是一个损坏的 img。第三个 img 没有损坏,所以 ::after 不起作用。
      • @fudu 这是我认为的预期
      【解决方案9】:

      这个对我有用:

      html

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

      CSS

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

      【讨论】:

        【解决方案10】:

        试试这个代码

        .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
        }
        

        【讨论】:

          【解决方案11】:

          在前一个元素上尝试 ::after

          【讨论】:

          • 你能详细说明你的帖子吗?
          【解决方案12】:

          我尝试并找到了一种更简单的方法。这是 HTML:

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

          我所做的是在我的图像标签之后放置一个空的&lt;p&gt; 标签。现在我将使用 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');
          }
          

          试试看。

          【讨论】:

            【解决方案13】:

            只需给图像“位置:相对”,它就会起作用

            【讨论】:

            • 这个解决方案不起作用。
            最近更新 更多