我不确定确切的用例是什么,但 Sam Stephenson 最近问我
@chriscoyier 在 CSS 中引用 OS X 系统字体的最佳方法是什么(为了获得 Lucida Grande 或 Helvetica,视情况而定)?
— Sam Stephenson (@sstephenson) 2014 年 11 月 20 日
我立即想到的是使用旧技巧,您可以在根元素上放置一个包含用户代理的 data-attribute,您可以从中选择该属性。
var doc = document.documentElement;
doc.setAttribute('data-useragent', navigator.userAgent);
然后根据需要设置字体。在本例中,为 OS X 设置 Lucida Grande,但为最新版本设置 Helvetica Neue。
html {
font-family: sans-serif;
}
html[data-useragent*='Mac OS X'] {
font-family: "Lucida Grande","Lucida Sans Unicode", Tahoma, sans-serif;
}
html[data-useragent*='Mac OS X 10_10'] {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
}
这 基本上有效。它是 UA 嗅探,这 不好,但我们在这里不做任何特别重要的任务,因此不会让我们的网站或网络面临风险。
Sam 尝试了另一条路径,并 变得很花哨。在这里,他创建了一个 iframe
(因此没有干扰样式),插入一个 button
元素(默认情况下应该具有系统字体),并测试其样式。
(function() {
window.addEventListener("DOMContentLoaded", function() {
getSystemFontFamily(function(systemFontFamily) {
var cssText = ".system-font { font-family: " + systemFontFamily + " }";
var element = createStyleElement(cssText);
document.head.insertBefore(element, document.head.firstChild);
});
});
function getSystemFontFamily(callback) {
withHiddenFrame(function(document) {
var button = document.createElement("button");
document.body.appendChild(button);
callback(window.getComputedStyle(button).fontFamily);
});
}
function withHiddenFrame(callback) {
var frame = document.createElement("iframe");
frame.style.cssText = "width: 0; height: 0; visibility: hidden";
frame.onload = function() {
callback(frame.contentDocument);
document.body.removeChild(frame);
}
document.body.appendChild(frame);
}
function createStyleElement(cssText) {
var element = document.createElement("style");
element.type = "text/css";
if (element.styleSheet) {
element.styleSheet.cssText = cssText;
} else {
element.appendChild(document.createTextNode(cssText));
}
return element;
}
})();
在 Yosemite(10.10.1)上,您将获得
.system-font {
font-family: '.HelveticaNeueDeskInterface-Regular';
}
奇怪的名字,但它有效。
在 10.9 中,您将获得
.system-font {
font-family: '.LucidaGrandeUI';
}
同样,奇怪的名字,但有效。
Tab Atkins 建议 CSS 应该能够使用 font-family: sans-serif;
来实现这一点,但不幸的是,它并不像那样工作。您将在 10.9 中获得 Helvetica,而不是 Lucida Grande。
Tab 还建议 尝试 @font-face。通过为 src
属性设置多个 local()
值,它可以工作!
@font-face {
font-family: "MacSystem";
src:
local(".HelveticaNeueDeskInterface-Regular"),
local(".LucidaGrandeUI");
}
body {
font-family: "MacSystem", sans-serif;
}
这里的技巧是首先选择“最稀有”的一个。当我在这台 Yosemite 10.10.1 上键入时,font-family: ".LucidaGrandeUI";
可以正常工作,因此它必须在列表中排在第二位才能使此方法生效。
我确信,您可以将此想法扩展到 Linux 和 Windows 等其他系统,并创建一个大型的 @font-face
声明来涵盖所有方面。如果有人愿意,请随时发布,我会在这里链接它。
2016 年 9 月更新
很多网站开始使用一个本地字体栈,该栈试图使用任何“系统字体”。该字体栈看起来像
由 GitHub 使用
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
由 WordPress 管理员和 Medium 界面使用
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}
iframe/button 会返回默认系统字体还是用户在其系统上定义为默认的字体?实际上我从未查看过浏览器是否尊重该设置。如果目标是获取该用户定义的字体,则 @font-face 可能无法正常工作。
这难道不是通用的“sans-serif”设置的用途吗?
是的,我在上面提到过 Tab Atkins 也是这样说的。问题是它在 OS X 10.9 及更低版本中的用例中不起作用。那里的系统字体是 Lucida Grande,而您在 Mac 浏览器上获得的是 Helvetica。
我在这里错过了什么?难道所有这些都不能通过一个复杂的 font 标签来实现吗?
问题是您可能在 OS X 10.9 机器上拥有“HelveticaNeue-Light”,然后您将获得它,而不是真正的系统字体。正如我在开头所说,我不确定确切的用例是什么,并且我确信它并不常见,但那是目标,并且目标已经实现。如果您愿意,可以称之为 CSS Tricks。
很棒的技巧……顺便说一句,我喜欢新主题
我不确定浏览器/操作系统对它的支持程度,但根据:http://www.sitepoint.com/css-system-styles/
您可以使用
不错,Kemie。
这似乎在快速尝试了开发者工具后在 MacOSX 上有效,其他人愿意尝试一下吗?
不错!与用户代理相比,这看起来更适合这种场合,尽管那也是一个巧妙的方法。
使用这种方法来利用操作系统系统字体似乎也在 CSS-Tricks 上得到了介绍
我现在对哪个信息来源更适合这个主题感到困惑,哈哈。
我以为从标题来看您会讨论如何获得多个系统的操作系统特定字体……但显然您所说的“操作系统特定字体”指的是“Mac 特定字体”……。
正如我在底部所说,这里用来找出所有这些内容的概念可以扩展到任何系统或任何系统组合。用例不是我自己的,所以我没有深入研究,但如果你想这样做,请随时尝试。
全世界 90% 的人口遇到了一个更严重的问题,即我们不仅使用基本的 ISO 字符,还使用 UTF 字符,例如,如果我想用“ěščřžýáíé”字符写一些东西,它可能在一台计算机上看起来不可读,而在另一台计算机上看起来还可以,因为一个字体名称可能在一台计算机上支持这些字符,但在另一台计算机上不支持。
因此,它需要对用户浏览器中定义字体上的 caron 或尖音符之上的定义字符进行一些检测,或者对我来说,始终定义一个自定义网络字体会更容易且确定。
如果浏览器需要的字形不在指定的字体中,它将使用一个回退字体(即使该字体未在 CSS 字体栈中指定)。
我猜大多数现代操作系统都带有覆盖广泛字符范围的字体,因此您最有可能遇到的情况是一些字符以与周围文本不同的字体呈现(我在写关于马耳他地点的博客时遇到了这个问题)。
这种技术在以下情况下可能特别有用:提供网络字体,但该字体在某个操作系统下呈现效果很差。
例如,想象一下这样一种情况:客户的既定品牌需要使用某些非网络优化的 Georgia 克隆,名为“Foobar”。也许在 Windows 下,“Foobar”看起来很好,但在 OS X 下,它的粗细程度非常小,无法辨认。使用这种技术,我们可以改为为 OS X 用户提供 Georgia。
我敢肯定这只有 webkit 支持(我还没有在其他地方测试过),但将
font-family
的值设置为system-font
实际上会为您提供任何系统字体。我实际上是在查看 Safari 的“您未连接到互联网”页面上的源代码时发现这一点的。
我只是使用 font anti-aliased 和 font-family: sans-serif,以减少问题。