【问题标题】:Is there a way to use SVG as content in a pseudo element ::before or ::after有没有办法在伪元素 ::before 或 ::after 中使用 SVG 作为内容
【发布时间】:2013-10-15 19:46:57
【问题描述】:

我想在一些选定元素之前放置一些 SVG 图像。我正在使用 jQuery,但这无关紧要。

我想让::before 元素为:

#mydiv::before {
  content: '<svg ... code here</svg>';
  display: block;
  width: 22px;
  height: 10px;
  margin: 10px 5px 0 10px;
}

如果我按照上面的方式进行操作,它只会显示字符串。我检查了规格,似乎对内容有一些限制。是否有解决此限制的方法?只有 CSS content 与我的问题相关。

【问题讨论】:

  • 用它作为背景图有问题吗?
  • 我想用它来生成指向 JQuery UI 工具提示的精美指针。我现在使用 CSS 伪元素 hack 来做到这一点,但这只给了我三角形。在这种情况下,背景图像将不起作用,因为我需要元素之外的东西。

标签: css svg pseudo-element


【解决方案1】:

是的,你可以!刚刚测试过,效果很好,太棒了!它仍然不适用于 html,但它适用于 svg。

在我的 index.html 中我有:

<div id="test" style="content: url(test.svg); width: 200px; height: 200px;"></div>

我的 test.svg 看起来像这样:

<svg xmlns="http://www.w3.org/2000/svg">
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
   <polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:3"/>
</svg> 

【讨论】:

  • 除非 SVG 是特殊的,否则您应该能够像对待图像一样对待它们:content: url(path/to/my.svg)。不过,这并不一定意味着它可以与 jQuery UI 工具提示库一起使用。
  • 您为什么要这样做?如果文件中已经有 svg 代码,则无需将其放入伪类中。伪类的全部意义在于当您想添加一些内容时减少 DOM 元素,但在您的情况下,如果您只是正常使用 svg 代码,它不会比将其放入伪类更糟糕(而且可能更干净) -class(这也可能是不可能的)。当然,除非你想把你的 svg 代码放在一堆位置,在这种情况下,你应该把你的 svg 代码放在一个单独的文件中,比如图像。
  • 不幸的是,我不相信这个解决方案适用于 SVG sprites。例如,content: url(mysprite.svg#my-icon) 实际上不会拉起您的图标。我很想被证明是错误的,但是:)
  • @watson,语义。 HTML = 结构,CSS = 展示。如果 SVG 是装饰性的,那么它不应该在 HTML 结构中,而应该在 CSS 中。
  • 其他回复中提到; 2020 年,SVG 也是如此:content:url("data:image/svg+xml,&lt;svg width='10' viewBox='0 0 8 8' xmlns='http://www.w3.org/2000/svg'&gt;&lt;circle cx='4' cy='4' r='4' fill='red'/&gt;&lt;/svg&gt;");
【解决方案2】:

您可以将 SVG 添加为空 :after:beforebackground-image

给你:

.anchor:before {
  display: block;
  content: ' ';
  background-image: url('../images/anchor.svg');
  background-size: 28px 28px;
  height: 28px;
  width: 28px;
}

【讨论】:

  • 在寻找了一段时间后,我发现这是最好的解决方案之一。您可以控制插入元素的每个方面,并以 CSS 样式表的正常工作方式工作,并具有分离的逻辑。很棒
  • ...啊,这让我充满希望,直到我意识到 Opera Mini 不支持 background-size。这太令人沮丧了。
  • 效果很好。 @deathlock,不应该需要背景尺寸,因为您在 svg 本身中定义尺寸,我不需要它。
  • 应该是公认的答案,因为问题说“在伪元素中:before or :after”
  • @NicolasBoisteault 我试过了,但实际上对我有用的是使用这个结构作为答案之一:url("data:image/svg+xml; utf8, &lt;svg.. code here&lt;/svg&gt;");
【解决方案3】:

使用 CSS sprites 和数据 uri 可以带来额外有趣的好处,例如快速加载和更少的请求,并且我们通过使用 image/base64 获得 IE8 支持:

Codepen sample using SVG

HTML

<div class="div1"></div>
<div class="div2"></div>

CSS

.div1:after, .div2:after {
  content: '';
  display: block;
  height: 80px;
  width: 80px;
  background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20height%3D%2280%22%20width%3D%22160%22%3E%0D%0A%20%20%3Ccircle%20cx%3D%2240%22%20cy%3D%2240%22%20r%3D%2238%22%20stroke%3D%22black%22%20stroke-width%3D%221%22%20fill%3D%22red%22%20%2F%3E%0D%0A%20%20%3Ccircle%20cx%3D%22120%22%20cy%3D%2240%22%20r%3D%2238%22%20stroke%3D%22black%22%20stroke-width%3D%221%22%20fill%3D%22blue%22%20%2F%3E%0D%0A%3C%2Fsvg%3E);
}
.div2:after {
  background-position: -80px 0;
}

对于 IE8,改为:

  background-image: url(data:image/png;base64,data......);

【讨论】:

  • 但这不可扩展,不是吗?我无法随意将其调整为 16px 或 320px。
  • @deathlock 当然可以缩放,虽然不是我的示例,因为它有一个固定的大小设置,80px 宽/高。
  • @deathlock 请问您是否因为上述示例无法扩展而投反对票?
  • 您将如何扩展?不,我没有。
  • @deathlock 谢谢,这是缩放 svg 的一种方法:jsfiddle.net/ess6ywce ... 使用百分比。另外,用scale svg搜索SO,你会发现更多方法
【解决方案4】:

您可以使用url() CSS 函数。

    #mydiv::before {
        content: url("data:image/svg+xml; utf8, <svg ... code here</svg>");
        display: block;
        width: 22px;
        height: 10px;
        margin: 10px 5px 0 10px;
    }

确保您的 SVG 不包含任何 # 符号。

【讨论】:

  • 由于 SVG 经常使用双引号,你也可以只使用外部单引号。如果您不想使用外部 SVG 文件,@Jenny 的建议是一个很好的方法。
  • 这很棒。不幸的是,它只适用于我的 Chrome(在 Chrome、Firefox 和 Edge 上测试)。
  • 我发现重要的是在 部分添加 xmlns='http://www.w3.org/2000/svg' 以在 Chrome 66.x 中工作。例如 - 小 V 形将是:content:url("data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' width='24px' height='24px' fill='white'&gt;&lt;path d='M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z' /&gt;&lt;/svg&gt;");
  • fyi # urlencodes 到 %23,并且还必须删除所有换行符。
  • 简单方法:使用yoksel.github.io/url-encoder 将 SVG 图像安全编码为 URL 数据(背景图像或内容属性)。
【解决方案5】:

注意所有其他答案在 IE 中都有问题。

让我们有这种情况 - 带有前置图标的按钮。所有浏览器都能正确处理这个问题,但 IE 会采用元素的宽度并缩放之前的内容以适应它。 JSFiddle

#mydiv1 { width: 200px; height: 30px; background: green; }
#mydiv1:before {
    content: url("data:url or /standard/url.svg");
}

解决方法是将 size 设置为 before 元素并将其保留在原处:

#mydiv2 { width: 200px; height: 30px; background: green; }
#mydiv2:before {
    content: url("data:url or /standard/url.svg");
    display: inline-block;
    width: 16px; //only one size is alright, IE scales uniformly to fit it
}

background-image + background-size 解决方案也可以,但有点不方便,因为您必须指定两次相同的大小。

IE11 中的结果:

【讨论】:

    【解决方案6】:
    <div class="author_">Lord Byron</div>
    

    .author_ {  font-family: 'Playfair Display', serif; font-size: 1.25em; font-weight: 700;letter-spacing: 0.25em; font-style: italic;
      position:relative;
      margin-top: -0.5em;
      color: black;
      z-index:1;
      overflow:hidden;
      text-align:center;
     
    }
    
    
    .author_:after{
       left:20px;
      margin:0 -100% 0 0;
      display: inline-block;
      height: 10px;
      content: url(data:image/svg+xml,%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120px%22%20height%3D%2220px%22%20viewBox%3D%220%200%201200%20200%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%223%22%20fill%3D%22none%22%20d%3D%22M1145%2085c17%2C7%208%2C24%20-4%2C29%20-12%2C4%20-40%2C6%20-48%2C-8%20-9%2C-15%209%2C-34%2026%2C-42%2017%2C-7%2045%2C-6%2062%2C2%2017%2C9%2019%2C18%2020%2C27%201%2C9%200%2C29%20-27%2C52%20-28%2C23%20-52%2C34%20-102%2C33%20-49%2C0%20-130%2C-31%20-185%2C-50%20-56%2C-18%20-74%2C-21%20-96%2C-23%20-22%2C-2%20-29%2C-2%20-56%2C7%20-27%2C8%20-44%2C17%20-44%2C17%20-13%2C5%20-15%2C7%20-40%2C16%20-25%2C9%20-69%2C14%20-120%2C11%20-51%2C-3%20-126%2C-23%20-181%2C-32%20-54%2C-9%20-105%2C-20%20-148%2C-23%20-42%2C-3%20-71%2C1%20-104%2C5%20-34%2C5%20-65%2C15%20-98%2C22%22%2F%3E%0A%3C%2Fsvg%3E%0A);
    }
    .author_:before {
      right:20px;
      margin:0 0 0 -100%;
      display: inline-block;
      height: 10px;
      content: url(data:image/svg+xml,%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120px%22%20height%3D%2220px%22%20viewBox%3D%220%200%201200%20130%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%223%22%20fill%3D%22none%22%20d%3D%22M55%2068c-17%2C6%20-8%2C23%204%2C28%2012%2C5%2040%2C7%2048%2C-8%209%2C-15%20-9%2C-34%20-26%2C-41%20-17%2C-8%20-45%2C-7%20-62%2C2%20-18%2C8%20-19%2C18%20-20%2C27%20-1%2C9%200%2C29%2027%2C52%2028%2C23%2052%2C33%20102%2C33%2049%2C-1%20130%2C-31%20185%2C-50%2056%2C-19%2074%2C-21%2096%2C-23%2022%2C-2%2029%2C-2%2056%2C6%2027%2C8%2043%2C17%2043%2C17%2014%2C6%2016%2C7%2041%2C16%2025%2C9%2069%2C15%20120%2C11%2051%2C-3%20126%2C-22%20181%2C-32%2054%2C-9%20105%2C-20%20148%2C-23%2042%2C-3%2071%2C1%20104%2C6%2034%2C4%2065%2C14%2098%2C22%22%2F%3E%0A%3C%2Fsvg%3E%0A);
    }
    	&lt;div class="author_"&gt;Lord Byron&lt;/div&gt;

    便捷的 SVG 编码工具url-encoder

    【讨论】:

      【解决方案7】:
      .myDiv {
        display: flex;
        align-items: center;
      }
      
      .myDiv:before {
        display: inline-block;
        content: url(./dog.svg);
        margin-right: 15px;
        width: 10px;
      }
      

      【讨论】:

      • 你应该多解释一下你的答案。仅从这一点,就很难判断您的答案如何或为什么有效。
      【解决方案8】:

      进一步扩展这个主题。如果你想添加 Font Awesome 5 图标,你需要添加一些额外的 CSS。

      图标默认具有svg-inline--fafa-w-* 类。

      还有修饰符类,如fa-lgfa-rotate-* 等。您需要检查 svg-with-js.css 文件并为此找到合适的 CSS。

      您需要为css图标添加自己的颜色,否则默认为黑色,例如fill='%23f00',其中%23编码为#

      h1::before{
      
        /* svg-inline--fa */
        display:inline-block;
        font-size:inherit;
        height:1em;
        overflow:visible;
        vertical-align:-.125em;
        
        /* fa-w-14 */
        width:.875em;
        
        /* Icon */
        content:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23f00' d='M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z'%3E%3C/path%3E%3C/svg%3E");
        
        /* Margin */
        margin-right:.75rem;
      }
      &lt;h1&gt;Lorem Ipsum&lt;/h1&gt;

      【讨论】:

        【解决方案9】:

        我今天刚刚注意到,这里的一家报纸使用将 SVG 直接注入 ::before 和 ::after 伪元素来为文章中突出显示的内容呈现风格化的引号。我试图通过whatcms.org 找到该论文的 CMS,但无济于事。但是我可以说,所有者报纸 - 大型全国性甚至国际性报纸使用名为 DM Polopoly 的 CMS。

        将 SVG 数据输入到内容元素中似乎比将内容空白并使用 SVG 作为背景图像要费力得多。我想知道他们为什么选择这种方法——这样做有什么好处。我在 Google 链接上看到一些人说,在将 SVG 图像悬停在 pseudo-element 上时,它可以很容易地操纵 SVG 图像。 . .但我没有看到这种“好处”的杀手级例子。

        This article 有一个更简单的方法来插入 SVG 作为内容。 它使用缩放属性来调整图像的大小。

        【讨论】:

          【解决方案10】:

          虽然这是很多年前的事了,但我也想分享一下。

          上面的答案都是正确的,你可以直接将编码后的 svg 字符串附加到 css content 属性中。对于那些对 URL 有任何问题的人,可能是由于空格和字符对此无效,在这种情况下,将解码的 SVG 代码粘贴到: https://mothereff.in/url

          使用编码的 SVG URL,它应该可以正常工作。 不正确和正确的例子:

          #incorrect::before {
            content: url(
              data:image/svg + xml,
              <svgid="Layer_1"data-name="Layer 1"xmlns="http://www.w3.org/2000/svg"viewBox="0 0 15.37 188.41"><defs><style>.cls-1{fill:#aeadad;}</style></defs><circleclass="cls-1"cx="7.69"cy="7.69"r="7.69"/><rectclass="cls-1"x="6.69"y="27.72"width="2"height="160.69"/></svg>
            );
          }
          
          #correct::before {
            content: url(data:image/svg+xml,%0A%3Csvg%20id%3D%22Layer%5f1%22%20data-name%3D%22Layer%201%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2015.37%20188.41%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23aeadad%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ccircle%20class%3D%22cls-1%22%20cx%3D%227.69%22%20cy%3D%227.69%22%20r%3D%227.69%22%2F%3E%3Crect%20class%3D%22cls-1%22%20x%3D%226.69%22%20y%3D%2227.72%22%20width%3D%222%22%20height%3D%22160.69%22%2F%3E%3C%2Fsvg%3E%0A);
          }
          

          【讨论】:

          • 它有效,谢谢!但是,我无法使用 css 修改几个 svg 属性。 :( 所以我需要将它的宽度硬编码为 html 属性,例如:&lt;svg width="30" ... 它的颜色或填充属性我也无法通过外部 css 表更改。定位至少有效。有什么想法吗?
          • 你是通过 class 还是 id 应用 css 属性?而且,袋子是否在 Object 元素中?如果是这样,将更改应用于对象 > svg - 此外,如果您通过内容方法渲染 svg ^ 您需要先将其应用于 svg,因为 css 不会影响内容属性,因为它是外部链接和路径等不会在页面内呈现
          • 明白了!作品。所以我们真的需要将每个属性(属性)添加到 svg html 本身。没有其他方法与外部 css.. 这里似乎有更多关于原因的详细信息:stackoverflow.com/a/4505130/9022150“生成的内容不会改变文档树。特别是,它不会反馈给文档语言处理器(例如,用于重新解析)。”再次感谢。
          • 因此,如果我选择通过内容方法注入 N 块 svg-s,然后稍后例如更改所有颜色的颜色,我需要将 svg 复制出来,url 解码,修改颜色属性,url 编码,粘贴回内容方法.. 哈哈,可能,谢谢不;)
          猜你喜欢
          • 2019-11-25
          • 2013-11-02
          • 2013-06-07
          • 1970-01-01
          • 2013-01-09
          • 2012-12-17
          • 2016-06-30
          相关资源
          最近更新 更多