如果字体下载被阻止,从FontAwesome回退

29

我正在开发一个网页,并发现 FontAwesome 是一种非常好的添加漂亮图标的方法,但是默认情况下Firefox浏览器中的 NoScript插件 会阻止字体下载。

对于普通字体,这不会成为问题,但FontAwesome使用的unicode字符故意位于大多数字体的可打印范围之外,因此向CSS添加字体堆栈(例如: font-family: FontAwesome, sans-serif;)将不起作用,因为所有图标都只呈现为十六进制方块。

我知道我可以调整NoScript以允许字体下载,但这并不适用于所有用户-我宁愿使页面优雅地降级。

当然,使用Javascript / jQuery很容易实现这一点,但如果是 NoScript 在阻止下载,则无济于事,并且如果用户没有启用javascript,则测试将失败。

理想情况是有一些CSS样式/规则,可以作为任何FontAwesome对象的回退,用基本字符替换它们,甚至什么也不显示。

对于那些不熟悉FontAwesome / TL;DR的人:

所有FontAwesome图标都有CSS类“fa”:

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
}

FontAwesome使用以下方式加载自定义字体(我已经删除了一些内容)

@font-face {
    font-family: "FontAwesome";
    font-style: normal;
    font-weight: normal;
    src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff?v=4.0.3") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.0.3") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular") format("svg");
}

然后特定的FontAwesome图标将有自己特定的类,插入相关的Unicode字符,例如:

.fa-star:before {
    content: "";
}

图标的HTML代码如下:

<i class="fa fa-star"></i>

所以这里的问题是: 我们需要一种方式,最好是在CSS中,以替换、删除或隐藏那些带有CSS类名“fa”的内容,如果字体“FontAwesome”没有被加载。


我认为在CSS中不可能实现。 - Marcin Nabiałek
你可以设置默认字体:sans-serif,FontAwesome;当CSS加载时,通过使用JS将其转换为字体:FontAwesome,sans-serif;因此,如果JS被阻止,则默认字体将起作用。 - Faraz
@Faraz 默认的sans-serif字体将如何工作?FontAwesome使用特殊的Unicode字符... - BenM
@BenM 这是我的解决方案 http://jsfiddle.net/farazilu/BG5J7/ - Faraz
1
@Faraz,如果FontAwesome未加载(即启用<noscript>标签),则您只需获取一个正方形> http://jsfiddle.net/BG5J7/4/。 - BenM
显示剩余2条评论
4个回答

10

嗯,我认为我通过你们指引的正确方向解决了这个问题:

在头部,我放置了这个:

<noscript>
    <style>
        [class*="fa-"]:before
        {
            content:"+";
        }
    </style>
</noscript>

这将选择每个fa-icon类项目,这些项目都定义在该模式中:

.fa-heart:before {
  content: "\f004";
}

将内容替换为通用字符或其他我们想要插入的内容(包括空白)。

这样做是否合理,还是我忽略了一些可怕的副作用?

我意识到有一种可能性是某些人已经阻止字体加载但启用了 JavaScript,但目前我很乐意忽略那些客户群体 ;)

编辑添加:

经过这么长时间,这个答案仍然在得到投票(谢谢!),显然这仍然是一个问题,所以我想发布这个链接,介绍极大地改进(和精简)FontAwesome 的各种方法: FontAwesome Fixed

我的最爱实际上是将所选图标嵌入行内 Base64 编码 SVG 中,无论是在 HTML 中还是在 CSS 中。这似乎相当优雅和高效,尤其是如果您只需要从集合中选择几个图标。对我而言,FA 仍然感觉像一个欺骗。


5
因为这并没有真正回答问题,所以被投下了负分。禁用JavaScript和禁用Web字体是完全不同的两件事情。只有NoScript插件才能同时实现两者。您可以在所有主要浏览器中禁用Web字体(出于各种原因,如安全性或可访问性),但仍然启用JavaScript。在这种情况下应用<noscript>只是一个非常有限的解决方法,它并没有触及问题的核心。 - tomasz86
1
这不是故意的 :( 我先在手机上看到了这个问题,点了踩,计划稍后回复,但后来没有时间再次检查。如果你感到冒犯了,我很抱歉。总的来说,我不是图标字体的粉丝,因为它们在语义和可访问性方面是一个非常灰色的领域。许多网站过度依赖它们(例如 GitHub 在 2014 年 8 月)。当禁用 Web 字体时,它们会显示无意义的 Unicode 符号,没有文本或任何其他回退来说明它们应该做什么。请参阅 http://technotes.iangreenleaf.com/posts/font-awesome-not-awesome.html - tomasz86
1
我个人很感兴趣是否存在任何(非JS?)解决该问题的方案。根据我在Web字体禁用方面的经验,要么是实际文本旁边的无意义Unicode框(不那么糟糕),要么是文本旁边的乱码(糟糕但仍可用),或者是没有文本的Unicode /乱码(最糟糕的情况)。 - tomasz86
2
与此同时,我找到了这个网站:http://jasonsantamaria.com/articles/symbolset,我可以确认它似乎有效。在他们的主页(https://symbolset.com)中,导航菜单中有一个购物车图标。如果Web字体被禁用/覆盖而不显示乱码或奇怪的Unicode数字,则该图标会更改为单词“Cart”。 - tomasz86
我同意这个答案并没有正确回答标题问题。我不会给它点踩,因为它写得很好,并且明确指出它只涉及NoScript插件问题。然而,我希望@BenM的答案能够被标记为被接受的答案,因为它实际上回答了标题问题。 - jumps4fun
显示剩余2条评论

8

解决该问题的一种方法是为<noscript>用户引入另一个CSS文件,并覆盖图像或精灵的 .fa-*类。

例如:

<noscript>
<link rel="stylesheet" type="text/css" href="safe-icons.css" />
</noscript>

您的safe-icons.css文件可能类似于以下内容:
.fa {
    display: inline-block;
    overflow: hidden;
    color: transparent;
    font-family: sans-serif;
    width: 16px;
    height: 16px;
    background-position: center center;
    background-repeat: no-repeat;
}

.fa-star { background-image: url('star.png'); }

当然,你会遇到来自FontAwesome的图标大小不同的问题,但是这种方法肯定能够平衡一些,并且对于启用了NoScript的用户至少呈现出一些内容。

网络字体在某些设置中整体上变得有问题了。例如,Windows 10与IE11可能会阻止所有网络字体。虽然这个答案需要付出很多努力,但可能是唯一可行的解决方案。 - jumps4fun

4

最近我遇到了一些问题,即使JS已经启用,但用户所在的受保护网络仍然阻止所有Web字体或特定的FontAwesome字体。

为了解决这个问题,我使用了类似这个的方法:

function css(element, property) {
  return window.getComputedStyle(element, null).getPropertyValue(property);
}

window.onload = function () {
  var span = document.createElement('span');

  span.className = 'fa';
  span.style.display = 'none';
  document.body.insertBefore(span, document.body.firstChild);

  if ((css(span, 'font-family')) !== 'FontAwesome') {
    // add a local fallback
  }
  document.body.removeChild(span);
};

基本上,它是一小段jQuery代码,可以在页面上创建一个FA元素并检查字体是否正确加载。如果不正确,您可以实现回退方案。在我的情况下,备用方案是插入一个带有通用占位符图形的<img>标签。

这不是纯CSS,但它(1)允许更强大的回退措施,并且(2)涵盖比<noscript>更多的场景。


2

我知道这是一个古老的问题,但最近我也遇到了类似的问题。

我通过自己托管图标来解决了我的问题。

在按照上面的托管指南后,以下是我自己的html示例。

 <head>
    <link rel="stylesheet" href="assets/css/all.css">
 </head>

 <footer>
    <a href="https://www.instagram.com/"><i class="fab fa-instagram"></i></a>
    <a href="https://www.facebook.com/"><i class="fab fa-facebook-f"></i></a>
 </footer>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接