如何防止在Google的JS无法转换材料图标文本时显示它们?

46

当谷歌的JS无法将材料图标转换为图标时,您如何防止材料图标文本出现?

图标在标记中定义如下:

<span class="material-icons">icon_name</span>

示例: https://archive.fo/CKqKG/scr.png (查看顶部的按钮行)。

Material Icons文档: https://material.io/icons/

这也是Google搜索中存在的问题,Google实际上会读取和保存div的文本而不是忽略它。

示例: https://i.imgur.com/TixS06y.png

我知道一个解决方案是简单地切换到由Google提供的.PNG文件。我想尽可能减少用户系统的网络负载。

谢谢!


这可能会有所帮助 https://dev59.com/H2ct5IYBdhLWcg3wI6N6#12316349 - talkhabi
15个回答

18

您可以使用 font-display: block;,只需将此CSS添加到您的HTML头部:

<style>
   @font-face {
      font-family: 'Material Icons';
      font-display: block;
    }
</style>

了解更多信息,请参阅font-display


3
只有在@font-face指定字体的src,而不是使用@importlink标签在头部中导入字体,才能使此方法生效。不幸的是,使用Google Fonts目前还不能实现这一点:https://css-tricks.com/dont-just-copy-the-font-face-out-of-google-fonts-urls/ - Laurens
2
注意:font-display: block将显示一个不可见的字体,这意味着在字体加载时,将显示一个与回退文本长度相同的不可见文本。这个连字文本通常比实际字体宽,因此您需要设置一些样式,以便即使由于font-display:block而不可见,宽度仍然较小,因此不会闪烁。 - gaurav5430
3
虽然这是一个老问题,但对我来说是一个新问题。现在您可以使用Google字体指定font-display属性,因此https://fonts.googleapis.com/icon?family=Material+Icons&display=block有效。 - sheng
5
我尝试了你的解决方案,它有效,但在网络速度太慢时不起作用。更明确地说,它会显示块(实际上是空的),而不是文本,大约持续两秒钟,所以在我尝试“快3G”模式时很好,它不会向用户显示文本,但对于“慢3G”模式,问题仍然存在,只是有大约两秒的延迟!有没有办法增加这个延迟时间?! - Hamidreza
@Hamidreza 我可以点赞这个,这仍然是一个重大问题。 - MrProgrammer
非常有帮助!+1 - undefined

13

我也遇到了类似的问题:我的问题不是图标永远无法加载,而是在较慢的连接上需要一些时间才能加载,直到它们加载出来之前,页面上会显示丑陋、格式不正确的文本,例如sentiment_very_satisfied,这些文本通常比周围的文本大很多,非常明显。

这里提供的其他解决方案对我都没有用(包括font-display:block,我以为这可能是有希望的),所以我自己使用CSS和jQuery想出了一个解决办法。我相信你可以轻松地将其改为使用vanilla JS。

CSS:

.material-icons{
    opacity:0;
}

jQuery:

$(window).load(function() {
    $('.material-icons').css('opacity','1');
});

这里的技巧是,与更常用的$(document).ready()监听器不同,$(window).load()会等待页面上所有元素下载完毕后再被触发。在这种情况下,这意味着它不会改变图标的不透明度,直到图标字体已经被下载。

缺点是,除非页面上的所有内容都已经下载完毕,否则图标不会显示,但这是我愿意做出的权衡,以避免在图标字体加载之前在我的页面上出现大量可见的文本。

(我还在CSS .material-icons{transition:opacity 0.5s;}中添加了过渡效果,让它们显示得很漂亮和平滑。)


3
我刚刚核实了一下,sentiment_very_satisfied 是一个真正的图标:https://material.io/resources/icons/?icon=sentiment_very_satisfied&style=baseline。是的,这就是我想让我的用户看到的东西。 - Dem Pilafian
1
很不幸,这在React中不起作用。我的项目的index.html中querySelectorAll的结果始终为空。我应该把这段代码放在React项目的哪里? - MrProgrammer

7
在你的“index.html”文件中,应该包含指向Google Material Icons的链接。在该链接中,你需要在末尾加上“&display=block”。我将展示给你它的结果:
  <link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon? 
  family=Material+Icons&display=block"
  crossorigin
  />

如果您现在点击链接,您会看到文档中包含:“font-display: block;”(您已更改“display”)。这就是全部内容。图标的名称将不再可见,并且图标将正确加载!

1
这是唯一对我有效的!它应该是“正确答案”!谢谢! - L777

6
如果您正在使用Typekit的webfont loader,您可以应用条件类来在Web字体加载时隐藏图标或者如果无法加载,例如:
.wf-loading, .wf-materialicons-n4-inactive {
  .material-icons {
    display: none;
  }
}

当然,您可以根据自己的喜好应用其他样式技术以获得最佳效果,例如font-size: 0;,这将取决于您的网站和用例。
要使用Webfont加载器加载材料图标,请使用以下配置:
window.WebFontConfig = {
  google: {
    families: [
      'Material Icons',
    ],
  },
};

你能否详细说明为什么 Material Icon 无法显示,并且以文本形式显示出来?是否有什么解决方法? - Ramesh Pareek
1
材料图标无法显示的原因有很多,例如互联网连接失败或者未能成功请求获取字体文件等。在这种情况下,如果您使用带有连字号的材料图标,当您的代码类似于 <i class="material-icons">face</i> 时,单词“face”将作为纯文本显示在您的页面上。我提供的解决方法可以避免此文本显示。 - Adam Reis

3
正确的解决方案是添加与字体大小相同的最大宽度,并将溢出设置为隐藏。
.material-icons {
    max-width: 16px;
    overflow: hidden;
}

它可以减小文本的大小,但不能隐藏文本。 - Kritarth Sharma

3

我也面临着这个问题。不过,我相信使用像这样的伪选择器可以帮助解决。更多信息请参见此链接

---- 编辑:工作示例

i.material-icons:before{display:none;}


3

我曾经遇到过相同的问题(TOC),直到我发现IcoMoon可以帮助您创建一个CSS文件,其中包含您选择的每个素材图标的类名标识符,并为您创建图标作为符号SVG。

让我们用一个例子来说明。

Google字体方法(FOUC)

<span class="material-icons">
search
</span>

这段代码在图标字体加载时显示搜索单词。但是,通过合理使用缓存、预连接、预加载和显示块,希望没有人会注意到它。


IcoMoon 方式(使用字体)

<span class="icon-search"></span>

在这里,您可以注意到没有FOUC的可能性,因为没有默认文本显示。

.icon-search:before {
  content: "\e900";
}

使用这个额外的类,它会保留一个空位直到资源加载完成。

IcoMoon方式(使用SVG符号)

<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M9.516 14.016q1.875 0 3.188-1.313t1.313-3.188-1.313-3.188-3.188-1.313-3.188 1.313-1.313 3.188 1.313 3.188 3.188 1.313zM15.516 14.016l4.969 4.969-1.5 1.5-4.969-4.969v-0.797l-0.281-0.281q-1.781 1.547-4.219 1.547-2.719 0-4.617-1.875t-1.898-4.594 1.898-4.617 4.617-1.898 4.594 1.898 1.875 4.617q0 0.984-0.469 2.227t-1.078 1.992l0.281 0.281h0.797z"></path>
</symbol>

<svg class="icon icon-search"><use xlink:href="#icon-search"></use></svg>

使用这种技术,您无需等待字体加载。但是,如果您有大量的图标集,则HTML大小将会更大,可能会更难维护。
最后,如果您担心项目加载时间过长,您会很高兴地知道,使用这个工具(IcoMoon),您只需加载您使用的图标(哇,这看起来像一个广告)。无论如何,以下是要遵循的步骤:
1. 前往https://icomoon.io/app/#/select/library,使用+添加按钮选择Material icons。 2. 现在选择您要使用的那些图标。 3. 最后,在底部选择生成字体生成SVG选项。
您将获得一个zip文件,其中包含可以包含在您的项目中的css和字体,或者包含在您的HTML中的SVG路径。
一些额外的参考资料:
- CSS Tricks

1
感谢您分享这个。使用 Material Icons 制作新字体非常方便(在我的情况下可以节省 160kB 的空间)。遗憾的是,Icomoon 无法更改字体的重量和等级。 - Kasper Kamperman
我很高兴听到这个消息。你说的重量和成绩是什么意思?也许我可以帮忙。 - Pizaranha
1
重量和等级是图标字体中的新功能,可更改描边的笔画粗细和强调程度。请参见右侧的参数:https://fonts.google.com/icons - Kasper Kamperman

2

如果您正在使用angularjs,则可能需要进行修复

最初的回答:

<i class="material-icons-outlined" ng-bind-html=" 'icon_text' "></i>

如果您使用jQuery,那么原始回答可以翻译成"最初的回答"。
<i material-icons="icon_text" class="material-icons"></i>

jQuery.onLoad

$('[material-icons]').each(function(){
  var icon_text = $(this).attr('material-icons');
  $(this).html(icon_text)
});

页面加载完成后才会出现图标。


这看起来像是一个有前途的答案。 - PKInd007
它不起作用。在慢速连接上,某些相同的图标文本会出现。 - Ashik

2

1
我发现如果你在链接标签的href末尾插入&display=swap,会有所帮助:

<link
    href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap"
    rel="stylesheet"
  >

这里有一个参考链接。请保留HTML,不要解释。

5
为避免自定义字体加载时显示不可见文本,最简单的方法是暂时显示系统字体(...)“swap” 告诉浏览器,应该立即使用系统字体显示使用该字体的文本。一旦自定义字体准备就绪,它将替换系统字体。"这正好与问题所涉及的相反。 - Andrey Popov

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