CSS 对手机表情符号字体的引用?

Posted

技术标签:

【中文标题】CSS 对手机表情符号字体的引用?【英文标题】:CSS reference to phone's Emoji font? 【发布时间】:2015-02-25 14:10:42 【问题描述】:

我想在我的网页中使用这个特定的表情符号🔍 - ????

android 上,浏览器将 Unicode 字形识别为表情符号并显示。

在桌面上它呈现为 Unicode 后备字符 - 一个带有数字的小方块。

所以,使用 Symbola、Quivira 或任何其他带有正确符号的字体,我可以解决这个问题。

@font-face 
    font-family: 'quiviraregular';
    src: url('fonts/quivira.woff2') format('woff2');


body
 font-family:sans-serif,quiviraregular;

不过,现在 Android 会显示字体中的符号,不是表情符号。

有没有办法设置 font-family 声明,以便 Android(和 iPhone)使用其内置颜色表情符号,而所有其他浏览器将使用提供的符号字体?

【问题讨论】:

【参考方案1】:

我接受了@ckuijjer 的回答并跟着跑了。我发现位置 16,16 在 IE11 中不可靠。位置 14,16 在 FireFox 中有问题。但到目前为止,位置 12,16 在我尝试过的所有地方都有效(IE11、Edge、FF42+、Chrome;Windows7、Windows10、OSX10.11)。

export default class EmojiUtils 
  static checkEmoji(char) 
    var node = document.createElement('canvas');
    var ctx = node.getContext('2d');
    ctx.fillStyle = '#f00';
    ctx.textBaseline = 'top';
    ctx.font = '32px Arial';
    ctx.fillText(char, 0, 0);
    return ctx.getImageData(12, 16, 1, 1).data[0] !== 0;
  

  static checkColor() 
    var node = document.createElement('canvas');
    var ctx = node.getContext('2d');
    ctx.fillStyle = '#000';
    ctx.textBaseline = 'top';
    ctx.font = '32px Arial';
    ctx.fillText('\uD83D\uDD34', 0, 0);
    var data = ctx.getImageData(16, 16, 1, 1).data;
    return data[0] > data[1];
  

  static polyfillEmoji() 
    if (!EmojiUtils.checkColor()) 
      require('emojione/font.css');
     else 
      if (!EmojiUtils.checkEmoji('\uD83D\uDD7A'))  //Dancing man Unicode 9.0
        require('emojione/font-versioned.css');
      
    
  

然后我只需要在页面加载时调用EmojiUtils.polyfillEmoji()

我添加到我的身体font-family: "EmojiOneColor", "EmojiOneColor-9", sans-serif;

字体.css:

@font-face 
  font-family: 'EmojiOneColor';
  font-style: normal;
  font-weight: 400;
  src: local('EmojiOneColor'), local('EmojiOne Color'), url(emojione-svg.woff);
  unicode-range: U+0020, U+0023, U+002A, U+0030-0039, U+00A9, U+00AE, U+200D, U+203C, U+2049, U+20E3, U+2122, U+2139, U+2194-2199, U+21A9-21AA, U+231A-231B, U+2328, U+23CF, U+23E9-23F3, U+23F8-23FA, U+24C2, U+25AA-25AB, U+25B6, U+25C0, U+25FB-25FE, U+2600-2604, U+260E, U+2611, U+2614-2615, U+2618, U+261D, U+2620, U+2622-2623, U+2626, U+262A, U+262E-262F, U+2638-263A, U+2648-2653, U+2660, U+2663, U+2665-2666, U+2668, U+267B, U+267F, U+2692-2694, U+2696-2697, U+2699, U+269B-269C, U+26A0-26A1, U+26AA-26AB, U+26B0-26B1, U+26BD-26BE, U+26C4-26C5, U+26C8, U+26CE-26CF, U+26D1, U+26D3-26D4, U+26E9-26EA, U+26F0-26F5, U+26F7-26FA, U+26FD, U+2702, U+2705, U+2708-270D, U+270F, U+2712, U+2714, U+2716, U+271D, U+2721, U+2728, U+2733-2734, U+2744, U+2747, U+274C, U+274E, U+2753-2755, U+2757, U+2763-2764, U+2795-2797, U+27A1, U+27B0, U+27BF, U+2934-2935, U+2B05-2B07, U+2B1B-2B1C, U+2B50, U+2B55, U+3030, U+303D, U+3297, U+3299, U+FE0F, U+1F004, U+1F0CF, U+1F170-1F171, U+1F17E-1F17F, U+1F18E, U+1F191-1F19A, U+1F1E6-1F1FF, U+1F201-1F202, U+1F21A, U+1F22F, U+1F232-1F23A, U+1F250-1F251, U+1F300-1F321, U+1F324-1F393, U+1F396-1F397, U+1F399-1F39B, U+1F39E-1F3F0, U+1F3F3-1F3F5, U+1F3F7-1F4FD, U+1F4FF-1F53D, U+1F549-1F54E, U+1F550-1F567, U+1F56F-1F570, U+1F573-1F57A, U+1F587, U+1F58A-1F58D, U+1F590, U+1F595-1F596, U+1F5A4-1F5A5, U+1F5A8, U+1F5B1-1F5B2, U+1F5BC, U+1F5C2-1F5C4, U+1F5D1-1F5D3, U+1F5DC-1F5DE, U+1F5E1, U+1F5E3, U+1F5E8, U+1F5EF, U+1F5F3, U+1F5FA-1F64F, U+1F680-1F6C5, U+1F6CB-1F6D2, U+1F6E0-1F6E5, U+1F6E9, U+1F6EB-1F6EC, U+1F6F0, U+1F6F3-1F6F6, U+1F910-1F91E, U+1F920-1F927, U+1F930, U+1F933-1F93A, U+1F93C-1F93E, U+1F940-1F945, U+1F947-1F94B, U+1F950-1F95E, U+1F980-1F991, U+1F9C0;

font-versioned.css:

@font-face 
  font-family: 'EmojiOneColor-9';
  font-style: normal;
  font-weight: 400;
  src: local('EmojiOneColor'), local('EmojiOne Color'), url(emojione-svg.woff);
  unicode-range: U+1F57A, U+1F5A4, U+1F6D1-1F6D2, U+1F6F4-1F6F6, U+1F919-1F91E, U+1F920-1F927, U+1F930, U+1F933-1F93A, U+1F93C-1F93E, U+1F940-1F945, U+1F947-1F94B, U+1F950-1F95E, U+1F985-1F991, U+1F57A, U+1F5A4, U+1F6D1-1F6D2, U+1F6F4-1F6F6, U+1F919-1F91E, U+1F920-1F927, U+1F930, U+1F933-1F93A, U+1F93C-1F93E, U+1F940-1F945, U+1F947-1F94B, U+1F950-1F95E, U+1F985-1F991, U+1F57A, U+1F919-1F91C, U+1F91E, U+1F926, U+1F930, U+1F933-1F939, U+1F93D-1F93E;

这样做的好处是,如果 chrome 原生有彩色表情符号,它只会加载 Unicode 9 字符。由于铬的限制,加载的将是黑白的。在其他带有黑白原生表情符号的系统上,它会加载整个表情符号字体。该版本的unicode-range 仍然确保仅在页面上存在表情符号时才加载字体(第一次加载时可能会出现简短的豆腐)。

【讨论】:

【参考方案2】:

Modernizr 有一个(非核心)特征检测来支持表情符号。如果您创建自己的build of Modernizr with cssclasses and emoji,则可以使用添加到html 标记的.no-emoji 类来获得不同的font-family

body 
    font-family: sans-serif;


.no-emoji body 
    font-family: sans-serif, emojisymbols;

我创建了一个 jsFiddle,如果你支持 emoji,则显示绿色背景,如果没有支持,则显示红色背景和 Kenichi Kaneko's EmojiSymbols 字体表情符号支持。不幸的是,我只能在 Windows 7 + Firefox 上看到 EmojiSymbols 字体,但这可能会给你一个开始。

根据评论更新

要查看是否支持检测特定字符,让我们看看 Modernizr 的特征检测source code for emoji support:

define(['Modernizr', 'createElement', 'test/canvastext'], function( Modernizr, createElement ) 
  Modernizr.addTest('emoji', function() 
    if (!Modernizr.canvastext) return false;
    var node = createElement('canvas'),
    ctx = node.getContext('2d');
    ctx.fillStyle = '#f00';
    ctx.textBaseline = 'top';
    ctx.font = '32px Arial';
    ctx.fillText('\ud83d\udc28', 0, 0); // U+1F428 KOALA
    return ctx.getImageData(16, 16, 1, 1).data[0] !== 0;
  );
);

它的工作原理是创建一个canvas 元素,渲染? koala 表情符号并检查特定像素的红色通道值,我假设这个表情符号的每个再现中都存在。

您可以扩展此功能以检查是否支持参数列表中的所有表情符号,如果不支持则使用表情符号字体回退。我认为最好的解决方案是在同一个画布中渲染每个表情符号,并检查每个表情符号的边界框内是否至少有一个像素着色。我不确定不受支持的表情符号是如何呈现的,可能需要检测它。

PS 因为我假设在后备表情符号字体之前指定表情符号的默认字体应该足以解决这个问题,我假设这些表情符号不存在于默认字体?

【讨论】:

真的接近。唯一的问题是,如果默认字体中不存在表情符号,则它根本不会显示。例如ℹ (ℹ) 在 Android 4 上不存在,但在 Android 5 上存在。我想知道是否有办法检测 特定 字符支持? @TerenceEden 我已经用一个可能的、未经测试的、用于检测特定表情符号的解决方案更新了答案。 重新你的 PS。似乎它们确实以默认字体存在。但我只能使用font-family:'Noto Color Emoji',quiviraregular; 让它在 FireFox 移动设备中工作。一切都非常令人沮丧-但感谢以上内容:-) 不客气!这个问题听起来是个不错的挑战,我学到了很多东西!【参考方案3】:

一种方法是使用media-queriestarget devices 而不使用本机支持(例如台式电脑),并应用自定义font-family,例如(从广义上讲,您需要完善以下内容)

// target devices with 'larger than mobile' screen size...and apply the emoji 'polyfill'
@media only screen and (min-device-width: 768px)
   body
      font-family:quiviraregular;
   

【讨论】:

独创性 :-) 尽管随着大屏幕平板电脑和非 Android/ios 小屏幕设备的普及,它并不是一个完全可靠的解决方案。 @TerenceEden - 是的,你最好使用功能,而不是设备检测,ckuijjer 的回答会这样做

以上是关于CSS 对手机表情符号字体的引用?的主要内容,如果未能解决你的问题,请参考以下文章

安卓qq上怎么发iphone表情符号

如何在网站上使用表情符号字体?

emoji纸飞机表情符号怎么输入

如何使用css无限期翻转两个表情符号

为啥我手机在空间里发了emoji表情 却显示符号 该怎么弄

什么叫表情符号,emoji怎么弄?