在 CSS-Tricks 上,有很多信息告诉您 如何 奇妙的 SVG 是。 尽管我们希望说服您 SVG 适用于每个人,但 SVG 的使用并没有像我们希望的那样广泛。 事实上,有些人仍然(确实)无法理解 SVG。
也许他们被困在自 IT 人员离职六年后就没有更新过的办公室电脑上,也许他们使用的是翻新的二手手机,无法负担升级,或者也许他们只是不理解或不在乎更新到新浏览器。 无论原因是什么,大约有 5% 的用户使用无法显示 SVG 的 Web 浏览器浏览网页——在美国更是如此(根据 caniuse 数据)。
一些技术导向的网站(比如这个网站)可以负担得起只支持现代 Web 浏览器的说法。 但对于大多数网站来说,您不能无视 20 个潜在客户中的 1 个。 如果你想让 95% 使用现代浏览器的用户享受 SVG 的所有好处,同时仍然为其他人提供功能性体验,你需要一个回退计划。
本指南由 Amelia Bellamy-Royds 和我 Chris Coyier 撰写。 Amelia 和我在同一个会议上做主题演讲。 我们都涵盖了 SVG,但都没有全面介绍 SVG 回退。 毕竟,这是一个非常大的话题。 虽然我之前已经介绍过 SVG 回退,但已经过去几年了,我们认为现在可以更全面地介绍这个主题。 开始吧!
您需要哪种回退?
在开始研究实现回退的技术选项之前,先停下来想一想您需要哪种回退。
- 无回退。 如果 SVG 是一个图标,其含义可以通过文本标签清楚地表达,您可以让该图标消失,而不会影响网站的功能。
- 文本回退。 如果 SVG 是一个图标,其含义可以通过文本标签表达,您可能只需要确保替代文本显示在它的位置即可。
- 图像回退。 这是大多数人认为的 SVG 回退:一个 PNG 或 GIF 图像,代表相同的图形,只是文件大小更大,分辨率更差。
- 交互式回退。 对于替换动画和交互式 SVG,PNG 可能无法满足要求。 您需要使用具有交互式 DOM 的图形语言。
在交互式方面,您的选择有限。 您可以 将 SVG 转换为 Flash,然后在 ActionScript 中重新编写所有交互代码。 或者,您可以使用 Raphaël 来绘制和操作图形。 它为 SVG 和 Internet Explorer 6-8 支持的 VML 矢量图形提供了一个 JavaScript 接口。 这意味着 Raphaël 无法帮助解决旧版移动浏览器的问题,但它确实显著减少了不支持的用户数量。
本文的其余部分将介绍如何为您的 SVG 创建文本和图像回退。 您的选择几乎完全取决于您在网页中包含 SVG 的方式:作为嵌入对象、作为内联 SVG 代码、作为 HTML 中的图像,还是作为 CSS 中的图像。
<img>
的 SVG 回退
作为
<img>
的 SVG 回退SVG 可以像这样使用
<img src="image.svg" alt="">
以下是一些针对不支持该功能的浏览器的选项。
如何测试支持
即使该测试 应该测试 SVG 中的 <image>
元素,但由于 一些测试 我们已经证明,它适用于用作 <img>
元素源的 SVG。 它就是 如此简单
function svgasimg() {
return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
}
源代码交换
上面的测试是 SVGeezy 库 用来执行 SVG-as-img 回退的。 如果浏览器未能通过此测试,它将根据需要将 SVG 与 PNG 交换。 如 <img src="image.svg">
变为 <img src="image.png">
。 您自己创建 PNG 版本,并将它们放在同一个目录中。
- 优点:它很简单。 它有效。 您甚至可以非常轻松地编写自己的源代码交换 JavaScript。
- 缺点:不支持的浏览器可能会下载两个图像,这会影响性能。 它会下载 SVG 版本(至少要下载足以知道它无法使用它),然后下载 PNG 版本。
这是一个非常简单的无依赖项的源代码交换示例

在 Internet Explorer 6(!)中交换回退图像
如果由于某种原因您无法将其放到外部 JavaScript 中,而必须使用内联方式……
<img src="image.svg" onerror="this.src='image.png'; this.onerror=null;">
如果您使用 Modernizr 进行特性检测,并且在项目中也使用 jQuery,它可以像这样简单
if (!Modernizr.svg) {
$("img[src$='.svg']")
.attr("src", fallback);
}
SVGInjector 是一个 JavaScript 库,可以帮助在特定情况下进行 <img>
回退。 它的主要目的是用内联 SVG 替换 <img>
。
<img class="inject-me" src="image-one.svg">
var mySVGsToInject = document.querySelectorAll('img.inject-me');
var injectorOptions = {
pngFallback: 'assets/png'
};
SVGInjector(mySVGsToInject, injectorOptions);
SVGMagic 是另一个 JavaScript 库,它用 PNG 版本替换源,包括 <img>
、background-image 或甚至内联使用的 SVG。 它最大的优势是它可以根据请求自动创建 PNG 版本,并将其发送到第三方服务器。 因此,请注意依赖项(jQuery 和第三方)并测试速度和可靠性。
<picture>
元素
<picture>
元素允许在浏览器不支持指定图像格式时提供回退图像。
<picture>
<source type="image/svg+xml" srcset="image.svg">
<img src="image.png" alt="">
</picture>
不幸的是,当对 SVG 的支持远高于对 <picture>
的支持时,这并没有什么用处。
您可以使用 Picturefill 对 picture 元素进行 polyfill。 Sara Soueidan 有一篇关于此的文章。
- 优点:您不仅可以获得回退图像,还可以指定不同的回退,作为 picture 语法的一部分,针对不同的媒体查询。 意味着针对不同的屏幕、艺术指导等提供不同大小的回退。
- 缺点:需要 polyfill。 为了避免双重下载,您需要跳过
<picture>
中的<img>
的 src,这是无效的,这意味着您将永远需要 polyfill。
<image>
技巧
通过一些内联 SVG 技巧,我们可以实现这一点
<svg width="96" height="96">
<image xlink:href="image.svg" src="image.png" width="96" height="96" />
</svg>
请务必将大小属性添加到图像,使其填满整个 SVG,然后在 CSS 中设置 svg
(针对现代浏览器)和 image
(针对旧版浏览器)的大小。
除了排除一些可以支持 SVG 图像但不能支持内联 SVG 的旧版浏览器外,这里的另一个主要限制是,让图像在流式网站上显示正确的大小将需要更多工作。 您需要使用 与让 SVG 扩展到一致的纵横比相同的技巧,而不仅仅是设置 width: 100%;
并让高度自动调整。
- 优点:不需要 JavaScript 或任何其他依赖项。
- 缺点:在 IE 中触发多个(中止)请求。 旧版 iOS 即使支持 SVG,也可以显示回退。 测试。
<object>
的 SVG 回退
作为
<object>
的 SVG 回退随着内联 SVG 的支持度越来越高,SVG-as-<object>
已经不再流行。 从渐进增强/优雅降级的角度来看,这很不幸,因为这是提供回退内容的最简单方法。
如果 <object>
本身无法显示,则会显示其子内容。 该内容可以是 任何 html 内容:图像、格式化文本,甚至另一个对象(例如,包含动画 SVG 的 Flash 版本)。
<object type="image/svg+xml" data="svg-ok.svg">
<img src="svg-no.png" alt="No SVG support">
</object>
<object type="image/svg+xml" data="svg-ok.svg">
<p class="warning">
Your browser does not support SVG!
</p>
</object>
<object>
的另一个渐进增强优势:Internet Explorer 8(及以下)的一些用户将能够看到 SVG! 对象会触发插件,并且不再更新的 Adobe SVG Viewer 插件 仍然可以下载用于旧版 IE。
background-image
的 SVG 回退
作为 CSS
background-image
的 SVG 回退对于大多数 CSS 属性,您可以信任 CSS 错误处理,让浏览器忽略新的语法,并应用级联中之前声明的值。 但是,使用 SVG 图像文件的 CSS 规则的语法对于旧版浏览器来说是完全正确的。 因此,它们会应用该规则,下载文件,但随后不知道如何处理它。
这里的诀窍是找到支持 (几乎所有) 支持 SVG 的浏览器,但不支持旧版浏览器的语法。 以下是神奇之处
body {
background: url(fallback.png);
background: url(background.svg),
linear-gradient(transparent, transparent);
}
这将两个功能结合在一起,共同打造完美的组合。如果浏览器同时支持多个背景和线性渐变,它也支持 SVG。因此,我们在这里声明了一个完全透明的线性渐变的 SVG。如果在旧的浏览器中失败,上面声明的回退将生效。
您可能在现代浏览器上添加了轻微的性能损失,因为需要计算透明的渐变,但这可能微不足道。


<svg>
的回退
内联
<svg>
的回退内联 SVG 由于多种原因而流行。用于绘制所需内容的所有代码要么直接位于标记中(减少请求),要么从可缓存的文件中引用。您对内联的 SVG 有很多控制权。它位于 DOM 中,因此可以使用来自同一文档的 CSS 和 JavaScript 控制它。
如何测试支持
有一些来自 Modernizr 的很棒的测试,我们可以看看。您在内联 SVG 中提取到函数的最佳选择是这个
function supportsSvg() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg';
};
这测试了 HTML 解析器(用于解析发送到 innerHTML 的内容)是否可以正确生成 SVG 元素,基本上是通过创建元素,注入 SVG 并测试命名空间。
与<object>
一样,不支持<svg>
的浏览器会忽略您的 SVG 标记,并将它的内容视为 HTML。但这并不简单。使用<object>
,支持对象的浏览器将知道忽略子内容。对于内联 SVG,没有这样的内置回退。但是,您可以使用一些解决方法。
内联 SVG 中的纯文本回退
您可以在内联 SVG 代码中包含纯文本,并且任何支持 SVG 的浏览器都会忽略它,因为 SVG 文本必须包含在<text>
元素中。您甚至可以在该文本中包含超链接。
<svg viewBox="-20 -20 40 40">
<!--Text Fallback-->
I'm sorry, your browser does not support
<circle fill="limegreen" r="19" />
<path stroke="forestgreen" fill="none" stroke-width="6"
d="M-12,3 L-3,10 11,-12" />
<text dy="0.35em" text-anchor="middle" font-weight="bold"
font-size="18px" font-family="sans-serif"
fill="indigo">SVG</text>
<!--Fallback with links-->
Please upgrade to a <a href="http://browsehappy.com/?locale=en">modern browser</a>.
</svg>

注意事项
- SVG 文本(本演示中的“SVG”一词)成为回退文本的一部分。我们稍后将讨论如何避免这种情况。
- SVG
<title>
文本不会成为回退文本的一部分。这是因为不支持 SVG 的浏览器将此解释为无效的第二个 HTML 标题元素,并忽略它。
您不能在内联 SVG 中包含任何其他 HTML 内容:当现代浏览器中的 HTML 解析器遇到 HTML 标记时,它会假设您忘记关闭<svg>
标记,并为您关闭它。这意味着 (a) 您的 SVG 已损坏,并且 (b) 您的回退文本在现代浏览器中可见。您可以使用链接 (<a>
标记) 的唯一原因是,它们在 SVG 中是有效的标记,但不会自行绘制任何内容。
另一种方法是从 HTML 文本开始,并在使用 JavaScript 检测到它支持的情况下将其替换为内联 SVG。想象一下 HTML 中的“喜欢”按钮
<button aria-label="Like">
<span class="inline-svg" data-xlink="#icon-heart">♥</span> Like
</button>
带有 ♥ 的跨度是那里的回退。数据属性是我们将在回退中使用的属性,在本例中是<svg>
/<use>
元素。
if (supportsSvg()) { // see test above
var inlineSvgs = document.querySelectorAll('span.inline-svg');
for(i = 0; i < inlineSvgs.length; i++) {
var span = inlineSvgs[i];
var svgns = "http://www.w3.org/2000/svg";
var xlinkns = "http://www.w3.org/1999/xlink";
var svg = document.createElementNS(svgns, "svg");
var use = document.createElementNS(svgns, "use");
// Prepare the <use> element
use.setAttributeNS(xlinkns, 'xlink:href', span.getAttribute('data-xlink') );
// Append it
svg.appendChild(use);
// Prepare the SVG
svg.setAttribute('class', "inline-svg");
// Set a title if necessary.
if (span.getAttribute('title')) {
svg.setAttribute('title', span.getAttribute('title'));
}
// Inject the SVG
span.parentNode.insertBefore(svg, span);
// Remove fallback
span.remove();
}
}
内联 SVG 中的 HTML 格式化文本回退
您可以使用 HTML 文本格式标记,而不会破坏 SVG,方法是在 SVG<desc>
(描述)标记内包含它,这些标记允许来自其他命名空间的内容。
<svg viewBox="-20 -20 40 40">
<desc>
<p class="warning">
Fallback text.
</p>
</desc>
<!-- ... SVG content ... -->
</svg>

注意事项
<desc>
标记的主要目的是提供替代文本描述。确保标记的内容对屏幕阅读器有意义。- 为了让
<desc>
在所有浏览器上被辅助技术识别,它应该位于 SVG 的顶部,紧随<title>
之后。 - 您应该还可以使用 SVG
<metadata>
标记来包含所有类型的任意标记,而不会影响 SVG 或它的替代文本。但是,这在测试过的浏览器中不起作用(它们插入隐式</svg>
结束标记)。 - SVG 文本内容仍然包含在回退文本中。
您可以甚至在<desc>
中包含带有回退图像的<img>
标记,它将在旧浏览器中正确显示,而不会破坏新浏览器中的 SVG。不要这样做!虽然现代浏览器不会显示回退图像,但它们确实会下载它,我们总是试图避免双重下载。
内联 SVG 的background-image
回退
内联<svg>
回退的一种可能性是设置一个仅在浏览器不支持内联<svg>
时使用的背景图像。因此,使用上面的测试,您可以给自己一个可以使用的类
if (!supportsSvg()) {
document.documentElemement.classList.add("no-svg");
<em>// or even .className += " no-svg"; for deeper support</em>
}
然后假设您正在使用一些像这样的内联 SVG
<button>
<svg class="icon icon-key">
<use xlink:href="#icon-key"></use>
</svg>
Sign In
</button>
您可以使用该新类在需要时应用背景图像
html.no-svg .icon-key {
background: url(fallback-key.png) no-repeat;
}
演示
您将必须自己创建 PNG 并调整大小。这里有一篇关于使用 Grunticon 自动执行所有这些操作的CSS-Tricks 的介绍文章。
为了获得最深层的支持,您将<svg>
包装在<div>
中,并将背景应用于它,因此即使浏览器完全拒绝 SVG 元素,回退仍然可以在已知的<div>
元素上工作。
内联 SVG 中的<img>
回退
我们在上面的“<image>
技巧”部分中介绍了内联回退,但由于这实际上是使用内联 SVG,所以让我们在这里详细介绍。要在 SVG 中获得图像回退,无需额外下载,您需要一种包含图像的方法
- 旧浏览器会将其识别为有效的 HTML
- HTML 5 解析器将在
<svg>
内允许 - 现代浏览器不会将其解释为要下载的图像。
可能看起来很奇怪,但 SVG<image>
元素实现了这个目的。SVG<image>
元素用于在 SVG内嵌入其他图像文件。但是,在 HTML 中,每个测试过的浏览器都将<image>
识别为<img>
的非标准同义词。在 SVG 中,您使用xlink:href
属性指定图像文件的 URL。在 HTML 中,您使用src
属性指定它。
因此,在大多数浏览器中,在内联 SVG 中包含带有src
属性(指向您的回退图像)的<image>
标记就足够了:旧浏览器将下载回退,新浏览器不会。除了Internet Explorer,它即使不显示回退图像也会下载它。解决方法是在元素上放置一个空xlink:href
属性。IE 开发者工具仍然显示它请求回退,但它几乎立即中止(在 IE11 或 IE10/IE9 模拟模式下 < 1ms),在下载任何内容之前。它看起来像这样
<svg viewBox="-20 -20 40 40">
<!-- SVG code snipped -->
<image src="fallback.png" xlink:href="" />
</svg>

现在要解决那个剩余的回退问题:转储到屏幕上的 SVG 文本。它在某种程度上破坏了我们完美的回退图像替换。我们可以使用 CSS 来帮助我们解决这个问题,但这并不直接。我们不能使用简单的svg text { display: none; }
,因为这会破坏 SVG 图形。您可以使用检测 JavaScript 来设置类,这些类将根据需要隐藏或显示文本。但即使这样,您也会被 IE8 对无法识别的标记的非标准方法所阻碍:它们始终被视为没有子内容的空 void 标记。如果您想将它们视为可样式化的容器,则需要调整HTML5 Shiv代码以包含所有 SVG 标记。
一个不使用 JavaScript 的选项是将所有 SVG 图形代码(除了回退<image>
)包装在<a>
元素中。如果没有超链接目标,SVG 中的<a>
元素的行为与<g>
分组元素完全相同,因此对您的 SVG 代码没有影响。由于 IE8 将<a>
识别为有效的容器元素,因此应用于它的任何样式都将应用于它内部的所有文本。
因此,技巧是应用样式以隐藏 HTML 链接的内容,但对 SVG 组没有影响。绝对定位和隐藏溢出可以解决这个问题
.hide-on-fallback {
display: block;
position: absolute;
left: -100%;
height: 0;
width: 0;
overflow: hidden;
}

SVG for Everybody是一个用于内联 SVG 回退的 JavaScript 库。它的方法是从最现代的内联 SVG 开始:通过<use>
引用的内联 SVG,指向外部文件中定义的符号。
<svg role="img" title="CodePen">
<use xlink:href="spritemap.svg#codepen"></use>
</svg>
如果支持,它将什么也不做。在 IE 的情况下,它使用 Ajax 请求 spritemap 并注入它,使其在现代 IE 中工作,而通常它无法工作。在不支持 SVG 的浏览器的情况下,它可以帮助您注入 PNG。
它唯一的缺点是它执行的 UA 测试不太准确。您可能最好使用 Ajax 请求 SVG并始终注入它,这将带来良好的支持和浏览器缓存。
关于图标系统的说明
拥有一个图标系统的原因是它使图标高效且易于使用。SVG 是一个很棒的图标系统。您可能希望图标系统的回退仍然既高效又易于使用。这意味着像<image>
技巧这样的东西将是一个非常糟糕的回退。它使标记变得复杂,意味着每个单独的图标都是一个单独的请求。
您可能希望使用以下方法之一来处理图标系统回退
- 使用背景图像作为回退,但让它们成为CSS 雪碧,这样它仍然只是一个请求。
- 使用图标字体作为回退。您将需要一个空元素(建议的标记),但 @font-face 比 SVG 工作得更远,因此它可以作为一个很好的回退。
- 使用Grunticon,它让您从一个空元素开始,并逐步增强到 SVG,并处理回退(通过 JavaScript 测试)。如果您愿意,您也可以使用 Grunticon,但仍然从内联 SVG 开始,如本教程中所述
通常,任何这些回退都需要一些 JavaScript 才能工作。如果您目标是使用 SVG 图标系统回退,但无需 JavaScript(在 Android 2.2/2.3 中有效),以下是一种方法。
这需要一些额外的标记(<a>
除了<use>
之外)
<svg class="icon">
<a class="svg-status"></a>
<use xlink:href="#svg-status" />
</svg>
然后在 CSS 中
.icon a, .icon + a {
/* styles for every icon */
}
.icon .svg-status,
.icon + .svg-status {
/* styles for this particular icon */
}
第一个选择器用于 Android,第二个用于 IE。使用兄弟选择器是因为旧版 IE 不会将无法识别的元素视为容器。

如果您不喜欢额外的锚点元素,并且不介意在禁用 JavaScript 时丢失回退,另一种策略是使用 JavaScript 注入一个元素 (),旧版 Android 和旧版 IE 浏览器都可以对其进行样式设置。
该脚本通过查看带有标签名称“use”的元素是否具有 ownerSVGElement
属性 来测试内联 SVG 支持。使用您的图标 id
值(来自 <use>
元素的 xlink:href
属性)作为新跨度的类名,因此不需要额外的标记。
结论
您可以完全为 SVG 做回退。
全面而写得好的帖子,Amelia。=)
虽然这里没有涵盖更多技术,但我只想说明关于
<object>
部分回退的一些内容在
<object>
内执行<img>
将导致支持 SVG 的浏览器发出两次图像请求。 为了避免这种情况,您可以执行以下操作或甚至
或这
其中第二个内联
<svg>
将与嵌入的<object>
位于同一个主页面中。这将确保支持 SVG 的浏览器不会同时请求 SVG 和回退 PNG。忘记提到第二个选项有效的原因是,在内联
<svg>
内定义的样式将/可以影响在该 SVG 之外定义的元素,包括在同一页面上其他内联<svg>
内定义的元素。感谢您的警告,Sara。我甚至没有想过要测试那个——只是假设它是为回退而设计的,所以它应该正常工作! 我太傻了。
谢谢您,先生!
我向 Amelia 道歉。谢谢您,女士!
首先,文章很棒!将所有关键的回退技术集中在一个地方很有帮助。
我确实觉得这篇文章需要一个“您真的需要回退吗?”部分。如果您只针对支持 SVG 的现代浏览器,或者您正在开发使用嵌入式浏览器的移动应用程序,而您对该浏览器有控制权,那么您可能根本不需要回退。
我想读者(我自己)可以直接去 这里,但这篇文章表面上给读者的印象是,必须考虑某种形式的回退。
谢谢,Eric。在头两节中,有几个地方提到了不需要回退作为一种选择,要么是因为您的目标受众是使用最新浏览器的用户,要么是因为网页在没有 SVG 的情况下仍然有意义。我想它本来可以更强调一些。然而,这篇文章的重点更多地是帮助那些陷入“SVG 很酷,但我不能在我的大型商业项目中使用它,因为我们需要支持 IE8”这种心态的开发人员。
另一个问题是,对于图像被关闭(或以某种方式,只是 SVG 被关闭)的用户,确保您的网站在没有图像的情况下仍然可用。这绝对是一个更大的问题,应该在整体层面上解决(而不仅仅是关注图像),但这些技术可能有助于解决这个问题。
是的,我看到了这些参考资料,我想我只是太挑剔了。:D
我个人很喜欢感觉到放心,因为如果你能控制浏览器会查看网站/应用程序,那么就可以避免回退。再次感谢这篇文章!
精彩的文章……学到了很多……感谢您分享您的知识……
很棒的东西,Amelia!我想补充一点,如果有人确实计划使用
<object>
语法,您可能还想考虑使用新的<picture>
元素。Sara(上面)在这篇文章中对这种技术做了很好的介绍:http://sarasoueidan.com/blog/svg-picture/这里的权衡是,您需要能够接受包含一个 polyfill(http://scottjehl.github.io/picturefill/)以用于尚不支持新
picture
元素的浏览器。好吧,没关系。看来我错过了你包含那个方法的地方。:thumbsup
我可能有一个改进内联 SVG 文本残留隐藏的方法
http://codepen.io/Tigt/blog/inline-svg-fallback-without-javascript-take-2
在旧版浏览器中无障碍隐藏 SVG 内容
不需要 shiv
允许您使用任何 DOM 回退
避免了 SVG + jQuery IE 错误
允许在 SVG 内容中使用链接(在旧版浏览器中,将伪造的
<a>
围绕真正的链接进行包装可能会导致问题)允许 SVG 包含
<foreignObject>
它不漂亮,但从我的测试来看它运行得很好。
很棒的方法,Tigt!正如您所说,您的代码可能稍微复杂一些,但在处理更复杂的 SVG 时会更健壮。
我之前没有想过使用 CSS 命名空间作为一种无 JavaScript 的方法来将您的样式定位到现代浏览器。我唯一担心的是我不确定 CSS 命名空间支持相对于内联 SVG 支持的具体实现时间(canIUse 在这里没有帮助我)。可能有一些浏览器版本支持 SVG,但无法识别您的命名空间限定样式。但是,我怀疑这些版本在现代网络中将很少见。
是的,我只能在 MDN 上找到兼容性信息,但从那里看似乎很安全。
很棒的帖子!
我认为还需要考虑:我们真的需要支持 SVG 吗? 以及权衡支持 SVG 所需的时间和精力。 Can I Use 表示全球对 SVG 的支持率约为 94%。
我正在进行一个项目,其中使用了大量的 SVG,包括交互式 SVG。查看美国支持率(该网站只向美国发货,在美国的 SVG 支持率略高于全球支持率)以及自今年年初起使用的登录页面的分析数据(显示约 0.2% 的浏览器不支持 SVG),我们决定不对交互式 SVG 提供任何回退,除了某种“您需要一个更好的浏览器!”类型的消息。
对于那些使用 IE8 的大约 10 个人来说,即使他们在网站上购买了所有东西,也几乎弥补不了构建和维护回退的成本。
有时最好的选择就是“不支持它”。
但对于您想要支持的情况,这是一篇关于如何支持的很好的介绍!
哦,是的,我过去曾经使用
<desc>
元素来存储回退,但最终它对屏幕阅读器很不友好,HTML5 规范也发生了变化,不允许在其中包含任何标记。令人难过,因为这对它的预期用途本来是有用的。您能解释一下“对屏幕阅读器不友好”吗?您在使用简单的标记文本时(例如在 示例 中)遇到问题了吗?还是您试图嵌入诸如图像之类的复杂内容?
再次检查规范后,可能屏幕阅读器不会宣布不在其父元素顶部的
<desc>
元素。我想我得测试一下!啊,是的,
<title>
和<desc>
有一个很麻烦的限制——它们需要放在最前面,在任何子内容之前。这是规范编写时的一个性能问题;浏览器不想搜索这些元素。我怀疑性能问题现在已经不那么重要了,但即使我们在 SVG 2 中删除了这个要求,你仍然需要它来保证向后兼容性。我会修改示例以使用这种结构。
那老的 onError 属性技巧呢?
它就在那里。(Chris Coyier 为完整性添加了它。)在替换 SVG 作为
<img>
的部分。我倾向于使用一个函数来查找所有
<img>
元素并替换它们,而不是在每个元素的属性中编写代码。它也可能稍微快一点(注意:我没有测试过),使用 JS 测试而不是等待 SVG 文件请求返回并在旧浏览器上出错。嗨,
如果你
– 不介意检测“浏览器”而不是“功能”
– 在标签中使用 SVG
那么一个非常简单的方法是使用 .htaccess(或任何适合你的网络)将旧浏览器重定向到你的 svg 的 png 版本。
是的,服务器端嗅探测试始终是另一种选择,无论它多么不受欢迎。
我想,任何新出现的浏览器都不太可能不支持 SVG,所以上面的代码可能不会让你遇到麻烦。
很棒的文章。我一直在搜索 SVG 回退的“最佳”解决方案。现在我也有了一些替代方案。:) 我爱你们。
对于带有图像替换的内联 SVG,我通常这样做
if (!Modernizr.inlinesvg) {
$(‘#containing-div’).prepend(”);
}
只要我在 SVG 中删除了 xmlns 链接,IE8 就会忽略 SVG 块,而不会破坏页面,并加载 .png 回退。
那应该是
我想要一个在尽可能多的浏览器上都能正常工作的无依赖解决方案,用于网站的 logo。
到目前为止,我选择了
<object>
,使用 SVG 的内联 base64 数据 URI,并在一个带有加载 PNG 回退的 class 的<div>
内。该 CSS 设置在头部内联<style>
中。我添加了带有 role=”img” 和 aria-label 的包装
<div>
,用于可访问性。我一直在权衡图标系统的回退选项,这篇文章非常有用。非常感谢!
我准备使用
<image>
技巧,但现在我会考虑 Tigt 的 Pen,因为我想要一个无 JavaScript 的解决方案。我唯一希望看到的是你个人最喜欢的哪种方法。(似乎 Chris“直接上阵”,没有回退。)
我不能说我有一个个人最喜欢的,因为我不做很多生产工作——我的主要目标受众通常是学习 SVG 的人!
然而,更普遍地说,我认为这真的取决于你试图传达什么。我认为你不需要在每个浏览器上都使用相同的图像,但你需要传达信息,并确保你的网站仍然可以正常工作(尽可能)。
所以,一个基本的alt 文本通常足以用于图标。对于复杂的数据可视化,我建议提供数据的文本/表格版本,原因有很多,但这并不能传达精心设计的图表的所有信息。我倾向于尽可能多地使用无 JS 解决方案,所以
<image>
技巧将是我的下一个选择。而且我可能现在会使用 Tigt 的方法来隐藏额外的文本。