多年来,我们设置文本样式的方式并没有太大变化。 为了使布局更加灵活,已经取得了许多进展,但在样式设置方面,我们设计的大多数有限方面,如文本,仍然保持相对不变。 这对于文本样式设置尤其如此。 我们编写代码来明确地为布局的每个部分设置文本样式,然后为了使其具有响应性,我们编写更多代码以使其在每个断点处正常工作。 这意味着,随着文本的不同区域压缩和扩展,结果是紧张 - 明显的,体验性的紧张 - 就在内容断裂之前。 在这些地方,内容由于尺寸或间距不好而受到影响,同时受到过于复杂和脆弱的代码的支持。
内在排版 改变了这一切,从代码本身开始,清除所有这些问题以影响样式。 您无需编写显式文本样式,而是定义这些样式如何相对于文本区域的变化。 这使您能够在更多布局变化中使用更灵活的文本组件。 它简化了您的代码,增加了新的布局可能性。 内在排版使文本能够自适应地调整到渲染它的区域。 文本不是为每个断点处的每个组件设置大小和间距,而是被赋予了响应其放置区域的指令。 结果,内在排版使设计能够更加灵活,适应其放置的区域,并且代码量更少。
clamp()
的排版超能力
超越 使用内在排版的成果远远超出了 clamp()
等工具所能实现的效果。 内在排版样式将元素查询的组件可移植性与 CSS 动画的插值控制相结合,从而实现任何值跨容器宽度无缝变化。 这种技术可以实现其他 CSS 技术无法实现的功能,例如,随着元素区域的变化,可以流畅地调整可变字体设置、颜色和无单位的 line-height
。 您还可以避免 clamp()
的可访问性陷阱和锁,当使用相对单位时,更改浏览器的默认字体大小 会使您的排版与您的断点脱节。
这与响应式排版有什么区别?
响应式排版引用视窗来转换文本。 它通过媒体查询、clamp()
或 CSS 锁定 来实现。 虽然这些技术使您能够跨屏幕尺寸细致地控制排版,但它们缺乏控制不同组件中排版的能力。 这意味着,对于具有多个不同尺寸内容区域的页面,需要为每个区域创建一个新的标题样式,并采用响应式排版方法。
内在排版不需要所有这些。 使用内在排版,可以在所有不同的内容区域中使用单个标题样式。 可以将离散标题样式合并到一个内在标题中。 这类似于元素查询与媒体查询的区别:使用元素查询,可以将所有缩放信息绑定到组件,而媒体查询样式始终引用视窗。
内在样式的解剖结构
如果我们要提取上面内在标题样式中的所有变化,它将看起来像下面这样
在页面较大的区域中,文本被设置为更大、更粗体、更宽。 在页面较小的区域中,文本更小、更轻、更窄。 测量渲染标题的区域,然后从此内在标题样式中获取适当的切片,用于该特定标题。
您可能会注意到此推断标题样式形状的几个特点。 文本从较小变为较大,但形状本身具有曲线。 这种对文本从一个点到另一个点如何缩放的控制特别有用,因为屏幕会变小以确保最佳的可读性。 在下面,您可以看到相同的样式集应用于两列文本,一列具有曲线形状,另一列具有线性形状。 在曲线内在示例中,文本在更多地方的可读性明显更高,与使用线性插值的示例相比,在使用线性插值的示例中,文本变得太快太小了。
通过结合在布局的大小和区域之间插值文本样式以及塑造这些设置如何插值的能力,内在排版为设计人员提供了前所未有的控制权,以控制文本在任何屏幕或组件尺寸下的渲染方式。
内在地排版
Typetura 开发了一个 工具,将内在排版功能添加到 CSS 中(我是创建者)。 此工具使您可以编写必要的排版样式,在以前没有灵活性的地方注入灵活性。 内在样式存储在 CSS keyframes 中,并根据父元素的宽度进行更改。 这使您可以跨元素宽度插值任何 可动画属性。 为了引用我们的元素查询示例,可以想象插值的元素查询。
要设置您的 keyframes,0%
等于容器宽度为 0px
,而 keyframe 100%
是样式将覆盖的容器最大宽度。 默认情况下,此值为 1600px
。 通过将类 typetura
添加到元素来定义容器,根元素作为默认容器。 子元素将根据父上下文宽度进行样式设置,除非定义了新上下文。
@keyframes headline {
0% {
font-size: 1rem;
}
100% {
font-size: 4rem;
}
}
要将这些样式附加到您的元素,请使用自定义属性 --tt-key
。 现在您可以看到您的第一个内在样式。
@keyframes headline {
0% {
font-size: 1rem;
line-height: 1.1;
}
100% {
font-size: 4rem;
line-height: 1;
}
}
.headline {
--tt-key: headline;
}
要塑造这些样式的缩放方式,请使用自定义属性 --tt-ease
。 此属性接受 CSS 缓动 函数和关键字。 这使您可以快速提高基本字体大小或逐渐减少标题缩放和间距。 此外,我们可以使用 --tt-max
来约束这些样式覆盖的范围,以更好地适应布局的约束以及文本的使用目的。
@keyframes headline {
0% {
font-size: 1rem;
line-height: 1.1;
}
100% {
font-size: 4rem;
line-height: 1;
}
}
.headline {
--tt-key: headline;
--tt-max: 600;
--tt-ease: ease-in-out;
}
以下示例展示了当页面上的所有文本都由内在排版样式驱动时,页面可以多么灵活;从文档的根部向上。 文本可以从服务会议室的显示器无缝过渡到手表的大小 - 所有这些都不需要媒体查询。 文本样式也可以在不同的模块中共享;例如,页面顶部的标题和下一单击区域中的标题都由相同的样式驱动。 虽然效率在任何网站尺寸下都会立即显现,但它们会迅速累积:网站越大,这些效率累积得越快。



查看此 Pen。 在里面,我添加了一个内在样式检查器,这样您就可以点击每个标题并查看渲染的大小。 在检查器中,您还可以操作内在样式的形状和上边界。 这使您可以开始了解 Typetura 启用的排版样式可能性。
内在排版是网页样式的未来
将这些设计规则融入你的内容中就是内在设计,而将这些规则融入你的文本中就是内在排版。 内在网页设计 是由 Jen Simmons 提出的一个概念,指的是将常见的网页设计变体融入到网页组件的本质。 与显式声明每个单独内容片段的样式不同,内在布局被赋予了设计约束,并且我们的内容会根据其环境做出反应,而不是显式定义样式。 这种方法既简化了你的代码库,又增强了设计的灵活度,因为组件拥有指令,可以帮助它们对不止视窗做出反应。
Typetura 将这种理念引入文本样式。 由于文本组件是我们最基础的设计素材,这种素材几乎在每个组件中都会被重复使用,因此内在排版比其他方法有明显优势。 设计弹性、可扩展性和代码简化等优势存在于你的项目更深层次,并延长了其寿命。 缩小到手表大小或扩大到电视大小,文本曾经限制了你的布局能达到的范围,而现在它支持你的雄心壮志。
这听起来是一个激动人心的有趣概念。 但是除了实验性的乐趣之外,我发现它对现有实践的改进微乎其微。 你如何管理排版一致性? 一个页面上的许多不同字体大小和粗细肯定会显得杂乱,并由于缺乏一致性而降低可用性。 第一个示例清楚地展示了这个问题,这根本不能算作一个有用的设计。 它还如何与其他布局元素协同工作? 你如何保持比例关系,以使整个页面协调一致? 垂直间距如何? 例如 8 点网格。 我很乐意看到更多实际示例。
感谢你的阅读,Rob!
我还没有遇到你所描述的问题,但可以理解你的担忧。 在大多数情况下,标题和引用是根据自身大小进行样式设置的,而其他元素则是根据父元素或视窗上下文进行样式设置的。 在实际应用中,标题几乎总是根据布局差异进行缩放和样式设置,这种方法可以将所有这些不同的样式封装到一个单独的内在样式中。 在我看到的这些演示中,排版 CSS 代码估计减少了 75%-90%,并且具有几乎相同的排版层次结构,但现在具有流畅的响应能力。 目前,我无法公开任何大型网站的 1:1 对比,因此我能理解你的怀疑态度。
另外,是的,你可以,我确实也会使用这种方法插值间距。 我倾向于避免像 8 点网格这样的系统,因为我发现它们对设计师来说更有用,而不是为读者提供一致体验的东西。 就一致性而言,我专注于比例的一致性,并创建工具来控制比例,而不是控制使用的特定度量的一致性。 我发现这种对比例的关注有助于我为流体媒体设计更好的体验,在流体媒体中,我无法期望浏览器窗口和基于百分比的布局遵循我在设计时使用的固定度量。
这是一种新方法,我也很乐意看到更多实际示例。 希望随着时间的推移,会出现很多示例。
Scott,感谢你抽出时间给出如此详细的回复。 是的,我同意,现在这个概念确实很有意义。 让我们看看可以用它构建什么,并继续努力!
对此没有灵丹妙药,但我对这里需要注意的关于可访问性以及例如文本缩放的内容很感兴趣?
浏览器缩放和用户设置的字体大小偏好会被尊重,因此两种形式的文本缩放都可以按预期工作。 虽然你确实需要使用
%
和em
/rem
来尊重用户设置的字体大小。 这无法神奇地使font-size: 12px
对人来说变得可访问。注意 WCAG 成功标准 1.4.4:调整文本大小 是唯一需要注意的,但这只是一个设计问题,而不是技术问题,因为即使使用媒体查询对文本进行大小调整也可能违反它。 已打开问题,它可能会被修改为更全面地涵盖不同尺寸下的排版设计更改。 另外,我见过不同的解释,只要你能够在 500% 的缩放级别下将文本缩放 200%,那么 SC 1.4.4 就会通过。 只要记住这一点即可。
吹毛求疵,但这不应该被称为内在排版。
在 CSS 意义上,内在行为是根据事物的自然内部特性进行的样式化;布局等,而根据外部环境进行的行为被称为外在行为。
适应可用空间的排版是外在排版。
这里合乎逻辑的类比是 CSS 外在和内在大小。 内在大小是根据内容本身的大小进行的尺寸设置 - 例如
min-content
和max-content
。 而外在大小是由可用空间决定的尺寸设置 - 例如来自 CSS Box Sizing Lv4 的stretch
和contain
。感谢你的阅读,Ron!
虽然是的,你可以对容器元素进行样式设置,但我之所以称之为“内在”,是因为样式可以对元素本身的属性做出反应。 例如,
H1
的font-size
可以根据H1
本身的大小变化而变化。我觉得这符合内在的定义,或者至少符合其精神,因为在样式设置中不需要考虑任何外部因素。
Scott,很棒的文章和概念。
你有没有考虑过如何将它纳入设计流程? 因此,如果设计师正在 Figma 中设计一个新网站,他们如何知道基于内在排版约束,字体在该设置下的尺寸应该多大?
我认为,如果设计师只是在模拟一个单独的视窗,那么可以将样式设置为与设计中使用的字体大小相匹配,但如果他们想模拟多个尺寸(例如,桌面、平板电脑、移动设备),那么他们需要知道每个文本元素在该尺寸下将被缩放到的尺寸。
感谢,Mark,我很高兴你喜欢这篇文章和这个概念!
是的,我有一些想法。
我现在采用的方法是,在 Figma 中设计时,我并不担心实现问题。 就像响应式网页设计一样,我们模拟的是静态实例,它们是对我们最终创建的事物的不完美表示。 我发现,我可以使用这种方法合理准确地实现我在模型中的效果。 我们在模型中定义的大小和间距往往遵循围绕约束条件的比例直观规则,而内在排版则是创建该映射的一种方式。
这仍然无法令人满意地回答你的问题。 与响应式网页设计工具进行类比,我认为我们还没有能够准确地代表我们产品的工具。 对于流体媒体,我们拥有固定画板的想法在我看来有点荒谬。 我们在 Typetura 的第一个产品是 app.typetura.com,该产品探索了视觉排版方法,将动画时间轴的概念与视窗宽度相结合。 在我们当前工具范式中,我快速原型制作了 内在排版在 Adobe XD 中可能是什么样子。 这两者都没有完全成熟,但我认为未来的发展前景令人激动。
对我来说,更深入地与设计工具集成的前景令人兴奋之处在于,它对品牌指南的意义可能超越 UI 模式库。 从调用框中获取一个内在类型组件,将其放到 Photoshop 中设计一个广告牌,然后在营销网站、应用程序和杂志广告中使用同一个组件,有可能真正简化品牌存在于所有媒体上的生产流程。
有一种方法可以进行内在类型化,而无需进行所有这些操作。 transform scale 将处理 80% 的用例,无需进行所有这些胡言乱语。
我们需要的是更少的复杂性,而不是更多的复杂性,这种伪装成 CSS 的代码只会让 CSS 更难处理。
感谢你的阅读和评论,James! 我有点不明白你说的 transform scale 是解决这些问题的解决方案是什么意思。 我很想看看你用它做了些什么示例。
嘿,Scott,我发现这种方法很有吸引力。 我很想知道 JavaScript 在 Typetura 中扮演什么角色? 这篇文章只描述了这种方法的 CSS 部分。 你能谈谈为什么 JavaScript 可能使这种方法更有效吗?
感谢你的阅读,Derek,我很高兴你喜欢这种方法。
理想情况下,我们应该能够在 CSS 中以原生方式插值断点。 我会直接深入介绍“如何”,因为我认为这篇文章总结了为什么这是理想的。 这里有一个 CSS 工作组问题,要求进行断点插值。
动画可以使用 JavaScript 重新映射,而 JavaScript 的作用也仅限于此。 使用 resizeObserver,一个 CSS 自定义属性会被写入到所有具有
typetura
类别的元素中。 自定义属性的格式为--tt-bind: 384
,其中384
是元素宽度,以 CSS 像素为单位。 现在,我们有了 CSS 中可以查询的宽度,我们可以将其传递给应用于所有元素的动画函数(以低特异性进行,以便可以被覆盖)。 动画函数为animation:var(--tt-key) 1s var(--tt-ease) 1 calc(-1s * var(--tt-bind) / var(--tt-max)) both paused
。 也就是说,关键帧--tt-key
从时间轴上对应于元素宽度--tt-bind / --tt-max
的位置开始应用,然后在该位置paused
。使用写入到元素的自定义属性和已就位的 CSS 基础,这篇文章中描述的 CSS 将会正常工作。
为了进一步说明,您可以使用 TensorFlow 查询除元素宽度以外的其他内容,例如滚动位置、光标位置或跟踪查看距离。然后,您可以将输出到
--tt-bind
并根据它设置文本样式。 这里有一个非排版和滚动为基础的示例,它使用了相同的底层 CSS+JS 技术.我一直关注你并从中学到很多东西,所以如果我的问题太简单,请原谅我的愚蠢。我不确定为什么字体大小不会依赖于读者从设备到设备的正常距离的清晰度,并在以大约 14-25 英寸的距离查看各种设备时保持不变,而无需在断点进行调整?
感谢 Lori!这是一个很好的问题。是的,在查看距离的清晰度是选择合适的根级别字体大小的主要因素,建议的最小字体大小为 16px 以确保良好的清晰度。但是,还有一些其他因素导致我们选择不同的字体大小,以及为什么流体排版很有用。
您希望强调文本以首先吸引读者注意,并引导他们进入页面的其他区域。这对标题、引用语或号召性用语很有用。为了最大限度地强调,您可能希望使文本尽可能大。尽可能大可能会根据布局中可用的空间以及该视窗的大小而变化,以及您正在排版的语言中单词的长度。但这解释了为什么您可能希望流体地缩放文本使其更大。
您可能希望使文本变小的原因是,如果单词不再适合布局。文本可能会在奇怪的地方断开,使阅读变得支离破碎,或者更糟的是,一个单词可能会溢出其容器或视窗。Apple Watch 会自动缩小网站以避免这种情况,因为即使是 16px 的文本也会在那个屏幕尺寸上开始变得支离破碎。
我认为 Tim Brown 在他关于熔融行高的文章中触及了您问题的核心。是的,对于段落文本,您不希望大幅度地向上或向下缩放它。我列出的用于缩放文本的两个原因更多地与标题或极端视窗大小有关。但是,对于段落文本,您还需要考虑其他因素。例如,流体地调整行高以帮助人们更舒适地跟踪他们正在阅读的文本行。如果您好奇,是的,这可以通过内在的排版方法实现。我用它在我的项目中实现熔融行高。
再次感谢您的问题。我在文章中没有详细说明它,所以我很高兴您给了我在这里的机会。
非常感谢您的解释和信息丰富的文章!