【问题标题】:CSS Background Color on an <IMG> using external SVG as the SRC<IMG> 上的 CSS 背景颜色,使用外部 SVG 作为 SRC
【发布时间】:2014-03-04 02:22:05
【问题描述】:

我有一个 SVG 正方形,中间有一个形状切口(想想饼干切割器)。 SVG 是在 Illustrator 中创建的,形状的边缘延伸到画板的边缘。

形状的颜色与背景颜色相同。

要更改 SVG 形状的颜色,我只需在 CSS 中更改 IMG 的背景颜色。这很好用,但是您会注意到形状外部有半像素颜色泄漏,就好像它是边框一样。

根据为 IMG 指定的大小,边框消失或重新出现。关于如何摆脱它的任何线索?

工作示例:http://jsfiddle.net/ja6Tx/

HTML:

<div class="container">

     <img class="logo" src="http://toobulo.com/img/logo-icon.svg" />

 </div>

CSS:

 body {background:#252525;}

 img.logo {background:yellow;}

更新:我决定以更简单的形式复制该问题,以排除任何像素小数问题并且问题仍然存在。 (在任何屏幕上)。

请看这里:http://jsfiddle.net/w7vrs/

我们现在有一个 320x240 的矩形。请注意,如果容器的宽度具有相同的纵横比(160、640 等),则问题永远不会发生。一旦您将 .img-container 的宽度更改为 451px 之类的东西,问题就会再次出现。

所有这一切的重点是 SVG 是可扩展的,所以我不应该指定精确的像素宽度来利用 SVG。

如您所见,新 SVG 的代码几乎没有:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="320px" height="240px" viewBox="0 0 320 240" style="enable-background:new 0 0 320 240;" xml:space="preserve">
<style type="text/css">
<![CDATA[
    .st0{fill:#020202;}
]]>
</style>
<rect class="st0" width="320" height="240"/>
</svg>

【问题讨论】:

  • 如果可能,您可以在 Photoshop 中打开您的 Illustrator 文件并修剪掉所有透明像素。从 Illustrator 导出时,我在位图中遇到了流氓透明像素。如果这不起作用,也许打开一个新的画板并将艺术品放入新文件中,然后调整为新画布的全宽/高度。您还可以尝试对艺术品使用剪贴蒙版,并在导出时确保您的艺术品没有任何透明/未填充区域。

标签: css html vector svg


【解决方案1】:

这是一个奇怪的错误,可能与内联元素周围的填充有关。这是我发现的处理它的方法。将您的 svn 放入“图像容器”div 中,如下所示:

<div class = 'img-container'>
    <img class="logo" src="http://toobulo.com/img/logo-icon.svg" />
</div>

然后你把图片宽度设置为100%,将容器上的宽度设置为你真正想要的宽度:

.img-container {
    width: 200px;
}

img.logo {background:yellow;
    width:100%;
}

工作小提琴:http://jsfiddle.net/ja6Tx/5/

【讨论】:

  • 不幸的是,这种技术仍然存在于不同的设备上。在我的常规显示器上显示良好 - 但在 Retina MacBook Pro 屏幕上查看时问题仍然存在 - 以及 iPhone。
  • @DamienBlack 我在 Debian Linux 上的 Firefox 17.0.11esr 中看到图像底部有一条黄线。
【解决方案2】:

外部 SVG 图像的宽度为 237.104 像素。如果您将所有出现的237.104 更改为237,那么问题就会消失。

用以下内容替换前几行应该可以解决问题:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="237px" height="400px" viewBox="0 0 237 400" enable-background="new 0 0 237 400" xml:space="preserve">
<path fill="#252525" d="M65.375,258.523c-0.013-0.014-0.026-0.026-0.04-0.041l0.088,0.1
    C65.388,258.543,65.375,258.527,65.375,258.523z"/>
<path fill="#252525" d="M60.655,171.371C60.631,171.387,60.166,171.83,60.655,171.371L60.655,171.371z"/>
<path fill="#252525" d="M0,0v400h237V0H0z M229.401,236.861c-1.209,3.683-2.285,7.473-3.723,11.129

(可能还有其他问题,但清理 SVG 文件并坚持像素网格应该可以解决所有问题。)


更新:您的替代 SVG 仍在框外绘制 (d="M0,0v400h237.104V0H0z)。这是 SVG 的清理版本,可以更轻松地查看发生了什么:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="237" height="400" viewBox="0 0 237 400"
   enable-background="new 0 0 237 400" xml:space="preserve">
<path fill="#252525" d="M0,0v400h237v-400H0z M198,290.5c-25.667,25.667-54.125,35.125-85.625,35.125
  c-31.25,0-61.375-15.5-78.708-32.792C17.146,276.353,1.5,253.458,1.5,215.125c0-32.875,19.625-62.375,36.5-75.958
  c12.874-10.362,33.917-20,58.25-20c22.5,0,43.5,11.208,54.271,20.827c10.41,9.295,25.965,28.007,25.965,55.315
  c0,26-14.236,43.691-25.283,51.748c10-13.333,12.464-28.223,12.464-37.89c0-13.542-4.667-27.042-13.667-37.667
  c-8.537-10.078-26.334-20.667-44.333-20.667c-20.167,0-33.575,8.098-44,18.905c-9.417,9.761-16.263,27.011-16.263,41.428
  c0,18.833,7.346,34.708,16.93,44c10.497,10.178,28.333,21.666,50.667,21.666c25.125,0,46.33-10.434,60.667-31
  c12.083-17.333,17-33.333,17-51.334c0-23.625-9.126-48.455-30.134-67.54C137.875,106.375,109.875,97.2,84.443,97.2
  c-28.068,0-56.693,10.425-76.109,25.657C36.625,86,74.79,75.289,105.789,75.289c33.336,0,69.919,14.419,94.586,41.086
  S234,171.25,234,201.833C234,228.167,223.667,264.833,198,290.5z"/>
</svg>

&lt;path&gt; 元素的第一部分是边界矩形M0,0v400h237v-400H0z。现在坐标都是整数,所以应该没有任何问题。 (虽然 Damien 的建议值得考虑。)


好的,我再试一次:-)

我无法在您发布的 JSFiddle 中重现该问题,但如果允许 SVG 随视口大小缩放,那么它有时会出现黄色边框。

为了解决这个问题,我将 SVG 图像的背景扩展了一个超出视图框尺寸的像素。 This seems to have fixed the problem (in Chrome, at least).

所以为了解决你原来的问题,我想你需要做的就是将路径数据的第一部分更改为M-1,-1v402h239v-402H-1z,如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="237" height="400" viewBox="0 0 237 400"
   enable-background="new 0 0 237 400" xml:space="preserve">
<path fill="#252525" d="M-1,-1v402h239v-402H-1z M198,290.5c-25.667,25.667-54.125,35.125-85.625,35.125
  c-31.25,0-61.375-15.5-78.708-32.792C17.146,276.353,1.5,253.458,1.5,215.125c0-32.875,19.625-62.375,36.5-75.958
  c12.874-10.362,33.917-20,58.25-20c22.5,0,43.5,11.208,54.271,20.827c10.41,9.295,25.965,28.007,25.965,55.315
  c0,26-14.236,43.691-25.283,51.748c10-13.333,12.464-28.223,12.464-37.89c0-13.542-4.667-27.042-13.667-37.667
  c-8.537-10.078-26.334-20.667-44.333-20.667c-20.167,0-33.575,8.098-44,18.905c-9.417,9.761-16.263,27.011-16.263,41.428
  c0,18.833,7.346,34.708,16.93,44c10.497,10.178,28.333,21.666,50.667,21.666c25.125,0,46.33-10.434,60.667-31
  c12.083-17.333,17-33.333,17-51.334c0-23.625-9.126-48.455-30.134-67.54C137.875,106.375,109.875,97.2,84.443,97.2
  c-28.068,0-56.693,10.425-76.109,25.657C36.625,86,74.79,75.289,105.789,75.289c33.336,0,69.919,14.419,94.586,41.086
  S234,171.25,234,201.833C234,228.167,223.667,264.833,198,290.5z"/>
</svg>

【讨论】:

  • 与下面的答案一样,它似乎可以解决问题,直到您在不同的设备(Retina Macbook Pro 和 iPhone 屏幕)上查看它。使用整数资源更新 SVG 的新小提琴:jsfiddle.net/KWhB9
  • 对于视网膜和 iphone 尝试将其设为可被 2 整除的数字... 238
  • @DamienBlack 不错的建议,但是这并不能提供一致的结果(似乎更多的是与运气有关)。查看更新的问题和这个小提琴:jsfiddle.net/w7vrs
  • @Joe 链接的问题与此答案有关,与您的问题无关,因此我将它们发布在这里。我玩了一会儿小提琴,我确定这是浏览器错误。当您在 Firefox 中向下滚动一点时,黄线会消失。它们也有亚像素大小——尝试设置img {display: block; outline: 1px solid red;} 并使用放大镜。如果是跨浏览器问题,很可能所有浏览器厂商都犯了同样的错误。例如。也许图像大小总是存储为浮点数,从而产生舍入误差。尝试使用 2 的幂作为维度。
【解决方案3】:

我想我找到了一个奇怪的小技巧。

body {
    background:#252525;
    margin:-1px;
}

.img-container {
    width: 199px;
    height:338px;
    overflow:hidden;
}

img.logo {background:yellow;
    width:200px;
    height:340px;
}

使容器比您的图像小一到两个像素并隐藏溢出。在解决这个问题时,我有一个理论,即您的 SVG 的大小介于像素大小之间。我有这种感觉,因为当我在 Safari 中玩这个时,固定宽度会导致高度的相同偏移,反之亦然。也许真正的解决方案是确保您的图像以像素精确缩放的大小构建和导出。

但这个 CSS 似乎至少在短期内解决了这个问题。如果您愿意,我还可以花一些时间在 illustrator 中重新制作 svg,看看是否可以使用不同的文档设置修复它。

http://jsfiddle.net/ENVKA/

更新: 能够确认 SVG 的宽度在整个像素之间。通过将文档单位设置为像素并将画板设置为 237 像素(之前的设置为 237.1 像素),图像可以正常工作。无需 CSS hack!

http://jsfiddle.net/JB9Cc/

【讨论】:

  • 很遗憾没有!看起来确实存在 SVG 错误,而解决它的唯一方法是裁剪 hack。我更新了你的小提琴,你可以通过调整 CSS 中的高度看到发生了什么:jsfiddle.net/JB9Cc/1
【解决方案4】:

我指的是您的更新。
看来这主要是 Firefox 中的问题(我可以在其中重现该问题),而在 Chrome 中该问题未出现。

我猜这是浏览器内部计算的一些“舍入误差”造成的。

避免这种情况的一种简单方法是使用clip 作为图像:

img.logo {
   clip:rect(0 0 auto 452px);
}

通过这样做,“问题”消失了(在 FF 中) - 请参阅 JSFiddle

【讨论】:

    【解决方案5】:

    正如其他人所指出的,这与不同浏览器舍入小数的方式有关。查看这篇关于不同浏览器如何处理子像素的帖子:http://ejohn.org/blog/sub-pixel-problems-in-css/

    我认为处理此问题的最佳方法是不为图像指定颜色。而是做大多数人在这种情况下会做的事情,只使用背景 div。像

    http://jsfiddle.net/ja6Tx/50/

        <div class="container">
    
            <div class="logo">
                <div class="bg"></div>
                <img src="http://toobulo.com/img/logo-icon.svg" />
             </div>
        </div>
    
        .logo{
            position: relative;
            height: 400px;
            width: 237px;
        }
        .bg {
            position: absolute;
            top:10px;
            left: 1px;
            height: calc(100% - 20px);
            width: calc(100% - 1px);
            background:yellow;
        }
    
        img{
            position: absolute;
            width:100%;
        }
    

    在我对我的 macbook pro 视网膜的测试中,它没有显示任何黄色边框,而且这只是处理与 SVG 不一致相关问题的最合乎逻辑的方法。

    【讨论】:

      【解决方案6】:

      使用伪元素创建背景。然后,您可以将背景放置在距离图像边缘一个像素的位置,如下所示:

      .logo {
          position: relative;
      }
      
      .logo::before {
          background: yellow;
          bottom: 1px;
          content: '';
          display: block;
          left: 1px;
          position: absolute;
          right: 1px;
          top: 1px;
          z-index: -1;
      }
      

      【讨论】:

        【解决方案7】:

        通过简单地使用最近的 HTML5 &lt;svg&gt; 元素,不会出现错误:

        http://jsfiddle.net/ja6Tx/55/

        似乎浏览器使用不同的渲染器取决于 SVG 的来源(svg、对象或图像元素,或在样式表中定义为背景图像)。

        【讨论】:

          【解决方案8】:

          我知道这已经有一年多了,但我遇到了同样的问题,并考虑了 Paul LeBeau 在另一个线程中关于在 viewBox 之外扩展的建议。下面是一个显示问题和修复的示例。

          Icons with background colors showing issue and showing fix

          徽章图标不显示出血,而勋章图标显示。

          Side-by-side image of icons within viewBox and extended beyond viewBox

          在 Illustrator 中查看左侧的 SVG,图像的背景到达 viewBox 的最边缘。

          在 Illustrator 中查看正确的 SVG,图像的背景超出了 viewBox 的边缘。

          修复您的 SVG 以使纯色背景延伸到 viewBox 之外将解决您的问题。

          【讨论】:

            猜你喜欢
            • 2014-08-03
            • 2015-07-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-25
            • 2019-06-30
            • 2021-12-04
            相关资源
            最近更新 更多