至少不是普通的字体。 每个字符都是一个 HTML 元素,使用 CSS 构建而成。 真正的网络字体!
让我详细解释一下。 这是一种无需使用任何字体即可呈现文本的方法。 随机文本使用 PHP 拆分为单词和字母,然后作为带有类的 HTML 元素呈现。 每个元素都使用 CSS 进行样式设置以创建字符。 这“仅仅”是使用 CSS 控制的 HTML,但它仍然是软件,并且能够传递信息。 它具有传统字体的所有属性,因此我们将它称为字体。 一种没有格式的字体。
免责声明: 我不是 HTML、CSS 或 PHP 方面的专家。 我敢肯定,这里存在实现我所做事情的捷径或更简单的解决方案,但由于我对结果感到满意,因此我将介绍该过程和我的经验。 本介绍不是教程; 它基于我有限技能的实验,应以这种方式对待。
想法
这个项目原本不打算持续五个月,但事实证明确实花了这么久! 一切都始于玩一个 CSS 图标,使用伪元素来制作 形状。 第一个 S 字母完成后,其余字母就相对容易了。 我查看了是否有其他类似的项目,但没有发现太多,因此我更有动力去看看我能做到什么程度。
最初,一个使用 CSS 控制的 SVG 字体似乎是一个好主意。 它会使这项任务变得容易得多(SVG 专门用于绘图),并且可以专注于特定于设计的效果,但它没有原始 HTML 元素的灵活性。 SVG 无法根据上下文进行修改,并且该过程会回退到传统的字体设计,其中每个字符都有一个固定的形状和代码。
工作原理
这是一种网络和字体设计的混合体。 每个字符都像任何网络元素一样构建,并内联使用以像字体一样工作。 度量、权重、OpenType 功能以及所有其他字体属性都是通过 CSS 文件独家控制的。
字体设计基于元素的边框宽度,这使得它非常通用。 除脚本字体外,只需使用相同的形状,通过边框的变化即可产生多种样式和权重。 在更复杂的字符上,使用裁剪路径和背景来创建剪切效果。
当 ::before
和 ::after
伪元素不足以形成字符时,会生成嵌套元素。 使用 em 值作为宽度、高度和边框宽度将有助于以后控制字体大小。 这是黄金法则之一。
字符(左侧)像任何 CSS 图标(右侧)一样构建。 它们之间没有重大差异。 有时一个字母很容易构建,就像一个简笔画人一样,基于圆形和线条。 但这就是您真正能够欣赏 border-radius
属性作用的地方。 我个人从来不喜欢圆角边框,但这段经历改变了我的想法。 基本上,半径可以做到的没有限制。
以下是本文中 CSS 字体的两个“真实”示例,其余示例图已转换为 SVG,以便在博客文章中更容易显示。
2. 红色 - 伪元素
3. 蓝色 - 额外元素
衬线预览呈现了一种更复杂的情况,但通常,无衬线字体将具有更少的元素要处理,从而使文件更小,加载速度更快。 这其实不是什么问题,而且这是合乎逻辑的——CSS 在使用 @font-face
规则嵌入字体之前读取。
挑战
最难的部分是克服像素比,或者将伪元素与基本形状对齐。 当字符调整大小时,复杂的数学公式会失败。 浏览器会将每个元素单独处理,并将其移到最接近的整数。
一种解决方案是尽可能多地创建伪元素(甚至包括额外的元素),并使用一个参考来引用一对 ::before
和 ::after
,与主形状无关。 在这种情况下,浏览器将或多或少地将元素渲染到相同的位置。
下面用 S 字母说明了一个没有参考点的字符。 字母的顶部和底部部分是两个伪元素,没有基本形状可以依赖(例如,上面衬线中的灰色区域或这里数字二中的灰色区域)。
在创建了几百个字符后,您会意识到一个字符不能支持内联变换(即 skew()
、rotate()
等),因为它不会与兄弟元素对齐。 在文本选择中,这在视觉上更加明显。 因此,伪元素非常有意义。 我会说它至关重要:第二条黄金法则。
clip-path
。clip-path
在所需距离处进行裁剪。CSS 自定义属性
在 CSS 中创建样式似乎比在字体软件中更容易。 您可以选择同时控制多个字符的形状和大小。 在 CSS 中,更多字符在同一个规则集中分组。
CSS 自定义属性在这种情况下非常方便,尤其是在控制边框、宽度和位置方面。 不同的权重是变量更改的结果,之后进行了调整。 微调是不可避免的,因为字符形状和大小会考虑边框宽度,并且可能不会随着不同边框按比例显示,尤其是在非对称形状上。
剪切效果是通过将相同的背景色添加到覆盖元素,然后使用 mix-blend-mode
结合颜色和效果来创建的。
CSS 中需要一个全局颜色变量来创建嵌套元素的剪切效果,否则这些元素会遵循父级颜色(覆盖元素与背景匹配)。
background-image
属性不适用于仅使用边框构建的字符,如果元素具有大小或位置变换(缩放、旋转或其他),背景将发生更改。
在无法使用背景的情况下,解决方案是 mix-blend-mode: lighten;
在深色背景上和 mix-blend-mode: darken;
在浅色背景上。
副作用
缺点是,某些效果可能会对具有可变属性的元素产生意外甚至相反的结果。 通常,filter
会将元素读取为完整对象。 为了防止任何冲突,边框和变换效果保留用于字体设计。
字体到文本
字体不会生成文本。 最初的想法是创建一个文本,该文本将与 CSS 一起加载,没有任何依赖项。 为此,最佳选择是 PHP(我的菜鸟观点)。 除了使用内联函数呈现 HTML 外,它几乎可以完成任何可以想象的任务。 没有 PHP,这个项目就不可能实现。
当然,PHP 的第一个任务是拆分随机文本,删除多余的空格,并为每个单词和字母创建匹配组,每个组都有自己的类。 到目前为止一切顺利。 我不会强调顺利完成的部分,这是一个基本函数,使用 split、explode 以及所有其他从视频游戏中借用的词语。
尽管如此,由于我以前从未做过这个,因此我不得不从错误中学习。 没有人告诉我 PHP 将“0”(零)视为 null,因此一天就这样过去了。 我不明白为什么我的零没有显示出来。
对于遇到此问题的任何人来说,也许它会有所帮助。 我没有使用 empty()
函数,而是使用了下面的函数
function is_blank( $value ) {
return empty( $value ) && !is_numeric( $value );
}
另一个主要问题是字符范围。 似乎 HTML、.htaccess
文件以及服务器本身中存在太多设置,仅用于识别特殊字符。 该解决方案是在几天后从 PHP 文档 中找到的,由 qeremy [atta] gmail [dotta] com 发布,显然是住在重音符号密集区域的人。
function str_split_unicode( $str, $length = 1 ) {
$tmp = preg_split( '~~u', $str, -1, PREG_SPLIT_NO_EMPTY );
if ( $length > 1 ) {
$chunks = array_chunk( $tmp, $length );
foreach ( $chunks as $i => $chunk ) {
$chunks[$i] = join( '', ( array ) $chunk );
}
$tmp = $chunks;
}
return $tmp;
}
恕我直言,有很多代码块,但这确实像个魔法,解决了所有问题。该函数基本上会忽略语言设置,读取任何字符,即使是非标准字符。如果 PHP 函数包含该字符,则 Unicode 表格中深层的字符也将被识别。
此函数仅提供生成每个输入字符的可能性,无需使用 HTML 实体。此选项不会限制在 HTML 格式中使用文本,但应避免使用内联代码或使用其他方法替换它们。例如,可以使用 `<nobr>` 标签将元素包装起来,而不是使用不换行空格 ( ` ` )。
左侧是默认系统字体,右侧是未经任何修改的 CSS 文本呈现。
结构
解决了这个问题之后,下一步是为每个字符创建特定的结构。HTML 元素的类和嵌套元素的位置取决于与一个或多个类相对应的长字符列表。一些最基本的字符也不包含在此列表中(例如,小写字母“a”需要一个收笔,这意味着需要一个额外的元素/类)。
为了便于理解,基本结构如下所示...
'Ć' => 'Cacute C acute'
...它将呈现三个元素:父级 Cacute、字母 C 和锐音符。结果如下所示,其中红色正方形代表父级元素,包含另外两个预设元素。
该技术非常类似于字形软件中基于配对构建变音符号(有时是连字)的方式。当一个组件元素发生改变时,其他所有元素都会进行调整。
由于任何元素都可以有多种应用,因此避免使用 ID,只使用类。
OpenType 特性
PHP 函数被设置为根据上下文表现出不同的行为。字符识别被设置为替换配对并在呈现 CSS 文本时创建连字。
CSS 文本中的上下文连字不是独立字符,没有特定的类。与传统的 OpenType 特性不同,字符的样式被重新设计,而不是被替换。通过对第二个元素进行样式设置来控制交互,以合并或形成一个新字符。
这些特性通过向父容器添加一个特定的类来激活。无论字符是否注册,在任何情况下都会呈现替代项,在任何浏览器中,无论是否有字体特性支持。
具有类似于 OpenType 功能的类以 Microsoft/Adobe 的 注册特性 命名。
HTML 语法
任何 HTML 元素都可以包含 CSS 字体,只要它在字体权重旁边具有 ` .css ` 类。要选择权重,请使用 ` .thin `、` .light `、` .regular ` 或 ` .bold ` 类,例如 ` <pre class="regular css"> `(` <pre> ` 标签仅仅是一个安全措施,以避免任何样式干扰)。
文本可以具有 HTML 格式。纯文本不是必需的。
如果括号 ( ` < ` ) 具有相应的结束符号,则 PHP 会忽略它,这意味着文本中的每个 HTML 标签都将保持活动状态,只有文本内容被呈现为 CSS 字体。浏览器以相同的方式编码标签中找到的 URL、文件路径或其他附加信息。如果在 CSS 中设置了这些标签,则它们可以为字母组或整个句子设置样式。
此外,根据布局首选项,特定的标签(例如 ` <a> `、` <u> `、` <ins> ` 和 ` <del> `)可以被视为对象,以模拟和自定义其原生外观和行为。
设置
CSS 文本是一组带有边框的对象,可以进行大小和颜色处理。将颜色视为 ` border-color `,反之亦然。使用 ` :first-child ` 而不是 ` :first-letter `。
在 CSS 文件中设置 ` font-size `,与其他字体相同,使用视窗、百分比、像素、em 或 rem 单位。以像素为单位的值可以使用小数。
` text-align ` 和 ` text-indent ` 属性默认情况下可用。即使没有文本内容,文本也会对齐到任何设置。
放置在文本内的块级元素(例如 ` <div> `、` <p> `、` <ol> `)会导致换行,就像通常情况下那样。` <br> ` 标签按预期工作。
除了文本格式化元素(例如 ` <h1> `–` <h6> `、` <strong> `、` <em> `、` <small> `、` <sup> `、` <sub> ` 等),它们需要新的规则才能对文本产生正确的影响,大多数语义元素(例如 ` <form> `、` <ol> `、` <li> `)使用其自定义设置。
字体
为了在动态内容中测试字体,PHP 函数的一部分在 JavaScript 中被复制,包括粘贴、鼠标事件、光标位置和文本选择。现在,只需按一下键就可以实现所有这些功能。
CSS 字体和补充图标。这正是整个事情的开始!
评论!优点 (+) vs. 缺点 (-)
即时加载
在没有实际文本的情况下,浏览器不会等待字体和脚本呈现页面。CSS 文件以及 HTML 元素会被缓存,这意味着更快的加载速度。
通用性
每个浏览器和服务器都识别 CSS。减少对找到在每个浏览器中都具有相同效果的正确格式的担忧。服务器不会检查特定格式以允许访问。
无依赖性
CSS 字体不需要备用字体或系统字体来显示文本。与页面样式相同的 CSS 可以包含字体。浏览器不会显示默认字体,无论是在页面加载之前还是之后。字体不依赖于第三方和脚本,设计在禁用脚本的浏览器中也不会不同。
无嵌入
CSS 字体完全集成到网页中,并在加载时适应布局,而不会替换其他元素。每个页面属性都自动适用于文本,并将按预期显示,没有任何后遗症或功能问题。
选择性使用
字体可以减少到有限数量的字符。例如,如果布局只有一个单词或一个符号,则不需要完整版本。
完全安全
实际文本不存在于页面上,这意味着可以轻松显示敏感信息,而无需担心垃圾邮件或网络钓鱼。
SEO 友好
可以使用标签属性包含重要信息,就像 alt 属性对图像的作用一样。
可定制
为了构建复杂的字符或功能,字体对任何 HTML 元素开放。无需脚本即可获取特定详细信息,因为每个单词和字母都有自己的实体,可以单独设置样式。
上下文
字体设计不限于预定义的字符,因此样式可以根据上下文更改,而无需创建新字符。
一致
为了弥补字体软件中缺乏自动化,在 CSS 中,设计可以同时控制多个元素。此论点是有效的,因为字体软件使用现有内容,而 CSS 使用属性,为所有现有或未来元素创建模板。
公开
任何人都可以创建自己的字体。简短的文本可以手动渲染,PHP 函数不是必需的。
基础
可以使用任何文本编辑器或开发人员工具访问设计。使用边框宽度、边框半径、形状和尺寸的基本技能足以重新设计任何字符。
实时
每个调整结果都是即时的。转换、导出、上传或其他激活字体的步骤已从流程中消除。
适度使用
如果为扩展文本生成 CSS 字体,页面速度可能会受到影响。因此,此技术仅推荐用于标题、标题、摘录和简短段落。
常见
CSS 字体不会受益于特殊处理,因为对于浏览器来说,这只是一个普通的 HTML 元素。因此,没有优化或字距调整支持。像素难以共享细线,并且在小尺寸下,字体可能会显示不正常。
硬编码
默认情况下,您通常的字体设置不可用,并且样式标签(例如<strong>
、<em>
等)无效。必须在 CSS 文件中设置函数,并且需要不同的方法,使用 HTML 元素而不是字体。
独家
这是一个网络字体,因此它仅限于使用 CSS 控制的数字媒体。除了某些位图效果,字体只能通过将文档打印为 PDF 进行离线转换,这将把 CSS 转换为矢量格式。
抽象
如果没有独立文件,字体很难识别、测试或传输。它就像 HTML 颜色:在生成之前是不可见的。
不可选
如果没有额外的脚本,文本就无法在输入框和文本区域中被选中或使用。对于动态内容,该函数需要在 PHP 中找到的完整字符识别。
非交互式
最常见的显示功能,例如sort
或filter
,必须与类一起使用,而不是与文本内容一起使用。
不可打印
在线打印仅支持基本 CSS 规则,有时会忽略图形,而选择文本。打印质量将严格依赖于浏览器的功能。
无辅助功能
CSS 字体会根据页面缩放进行调整,但字体大小和语言无法通过浏览器更改。
自定义浏览器功能(例如查找、阅读器)无法访问文本内容,因为没有文本内容。
设计有限
没有多种样式可供选择,设计仅限于 CSS 的功能。CSS 规则对不同的浏览器可能具有不同的含义,导致不一致。CSS 字体是书写的,而不是绘制的,因此完全消除了“手工制作”的概念。
多任务
您需要了解 CSS 才能对字体进行调整,反之亦然。设计过程不是自动化的,一些原本由机器生成的属性必须手动设置。
无保护
设计代码对任何人都可见,与任何在线元素一样。设计无法真正防止未经授权的复制和使用。
感谢您的阅读!这是字体的首页。
不可选择 - 这是对我们来说致命的
你可以创建一个函数和流程,也许可以用 js 允许这样做?这很有趣。
喜欢这个项目,非常酷
这是一个很棒的想法,但我认为它不会流行起来,因为屏幕阅读器甚至无法识别它为文本。
我能看到有人使用它与 css 过渡来创建运动图形。另一个应用可能是一个新奇网站,用户可以在其中输入一些文本,调整一些设置,点击一个按钮,它会为他们提供 html 和 css,然后他们可以用它做任何事情
嗯。但为什么?
我不明白这有什么真正的好处,除了字体可以立即与 CSS 文件一起使用。
你知道你可以对你的字体进行 base64 编码,并将它内联到 CSS 文件中,对吧?
有趣,相信我,我已经做了很多实验,只是为了看看它们是否可以完成,所以我喜欢阅读这篇文章,并为这个实验鼓掌,但你在“优点”中列出的东西有很多问题。
当我读到这篇文章的标题时,可访问性是我想到的第一件事。
我严重怀疑搜索引擎是否会真正索引你提到的属性——你说它们类似于 img alt 标签,但这并不意味着它们会被读取。
虽然它确实“可缓存”,但它不能独立于页面内容进行缓存。至少对于字体来说,你可以缓存字体文件,然后在第二次及之后的页面浏览中重复使用它。这必须为每个页面浏览下载所有完整数据,对吧?
此外,如果我没有弄错,生成的代码实际上比它要替换的字体数据更大。用于表示标记中单个字符的数据量远大于普通字符,并且必须在页面中每个字符的实例中重复。然后你还有所有相关的 CSS。
再说一次,从技术上讲很有趣,感谢分享,但我认为这可能需要在顶部添加“不适合生产使用”的免责声明。
“无辅助功能”应该在该项目缺点列表中排在更靠前的位置。这是一个非常重要的考虑因素,通常被视为“锦上添花”。从技术实验的角度来看,这是一个非常酷的项目;我对创造性地应用样式以使字符不仅清晰易读,而且作为一种字体真正具有吸引力和一致性感到惊讶。但让我们明确一点:出于任何原因,任何人都永远不应该在生产环境中使用基于 CSS 的字体。
这有点让我想起了 sIFR,对于那些年龄不大的朋友来说,它是一种用 Adobe Flash 对象替换文本的方法,因为在过去我们没有 Google Fonts 和 Font Squirrel 以及所有其他很棒的网络字体资源。
sIFR 将重要的页面内容(例如标题)变成了不再可选择、可搜索、可复制等的东西。它从页面中获取内容(和上下文),使其对用户不太友好。它将信息性的东西变成了装饰性的东西。
… 作为概念验证,这很棒。作为 CSS 灵活性的示例,这太棒了!但是作为部署在实际网站上的东西?我有点犹豫,因为它感觉像是用户体验和可访问性方面的一步倒退。
我还想指出,一些优点在几年前可能不像现在那么重要。
@font-face
已经得到了广泛的支持,近年来,对网络友好的字体资源的数量激增。随着网络开发世界中许多知名人士不断重申性能的重要性,字体创建者也开始专注于为我们提供他们所能生成的性能最高的字体。读起来很不错。
像这样的古怪项目通常(至少一开始)很有趣,而且你最终会学到很多东西。
这过于简单化了。通常情况下,PHP 不会将 0 视为 null。你使用的特定函数
empty()
用于测试假值,其中包括零。你可能是对的。我猜你只是想将一个(多字节/utf-xx/unicode)字符串拆分为单个字符的数组,这样你就可以用类似的东西完成工作
(它基本上是 qeremys 代码,没有分组多个字符的选项)
感谢大家的评论。
我特别感谢这一点,因为我可以从中学习一些东西。
否则,这个项目的确是为了娱乐,而不是为了发起一项新事业 =)
非常有趣的练习,也许它可以用作文字艺术生成器或徽标生成器?正如你提到的,它不适合大块文本,但用在标题上很有趣
之前制作的其他 CSS 字体。
– 2004 http://www.cssplay.co.uk/menu/cssfont
– 2010 https://web.archive.org/web/20100414205534/https://desandro.com/resources/curtis-css-typeface
– 2015 https://yusugomori.com/projects/css-sans/fonts
谢谢!很高兴知道我可以与其他人分享批评意见。2015 年制作的那款与我的方法类似。很棒!