给CSS加把锁

特别声明:如果您喜欢小站的内容,可以点击年卡¥199.00元(原价: ¥598元)季卡¥78.00元(原价: ¥168元)月卡¥28.00元(原价: ¥68元)进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)

看到该标题,我想你可能会感到非常的意外和好奇,“CSS怎么能加把锁呢”?其实这里所说的给CSS加把锁是指业内所说的CSS Locks(或者CSS calc Lock)。该概念是@Tim Brown在2012年提出的一个概念,该技术其主要致力于解决文本排版可读性相关的技术难度,特别是在实现一些精准的流式布局中的文本排版。在《Web技术10》中也提到过,@Mike Riethmuller、@Tim Brown和@Geoff Graham都在致力于这方面的研究,而且找到了使用CSS锁技术方案来锁定流式排版。让我们实现一个精准的流式排版不再是难题。在今天这篇文章,我们来一起探讨一下CSS锁的故事。

什么是CSS锁

这里所指的CSS锁并非说给CSS加把锁,让程序无法写入CSS代码,所指的是CSS Locks。那么具体什么是CSS锁呢?如果要搞清这个概念,我们要先回顾一点Web相关的知识。

响应式设计

早在2010年@Ethan Marcotte就提出了Web响应式设计(Responsive Web Design)的概念。“响应式设计”简单地说是可以让你的网站从宽屏显示器到手持移动终端(比如手机)都能良好的显式。

这是一种Web设计和开发的方法,它可以让你基于同一套源码为不同的设备终端提供最佳的展示。

熟悉响应式设计的同学都知道:

响应式设计是通过CSS的媒体查询来实现的

开发者借助CSS的媒体查询特性有条件地使用CSS规则,比如媒体查询根据断点(屏幕分辨率节点):

它们会告诉浏览器应该根据用户的设备忽略或应用某些规则:

最终用户在不同的终端会看到不一样的效果:

事实上,现在社区中实现响应式设计采用的大都是该方案,很多优秀的CSS框架都会有一些预定义的断点。不过基于断点来做媒体查询条件判断,特别是在一些CSS框架中预定一些断点,难免有点武断。这好比有点像猜测和妥协一样。我们越想让它工作得更好,需要设计(处理)的东西就越多。这也造就响应式设计基于媒体查询来实现总是令人感到不太优雅,效率也不高。

另外响应式设计在断点之间的切换时,流畅度是有一定的折扣(会闪那么一下),而且在响应式排版中也有着令开发者感到头痛的事情,尤其是文本的排版以及元素间距间的控制。也正因如此,才会有CSS锁的出现。

CSS锁简介

简单地说,CSS锁是一种响应式的Web设计技术,他主要致力于解决响应式设计的文本排版,它允许你根据当前的视窗大小大两个值之间平稳地转换,而不是直接从一个值跳到另一个值。

CSS锁是@Mike Riethmuller在2015年的《Precise control over responsive typography》中首次展示的,但早在2012年的时候@Tim Brown在《Flexible typography with CSS locks》中就提出了该概念,并称之为CSS Locks

@Tim Brown用了实际生活中的一个示例来描述CSS锁。在运河和河流中都会备有船闸用来控制河中水位,也可以在不同水位的水域之间升降船只

用到CSS锁上来的话,就是CSS锁允许你设置最小和最大的字体大小。最小字体大小将应用于最小视窗宽度以下,最大字体大小将应用于最大视窗宽度之上,在最小宽度和最大宽度之间,字体大小将按比例从最小字体到最大字体间按一定的比例缩放:

如果用CSS来描述的话会像下面这样:

/**
 * 1. minf: 最小font-size
 * 2. maxf: 最大font-size
 * 3. minw: 视窗最小宽度
 * 4. maxw: 视窗最大宽度
*/

font-size: calc([minf]px + ([maxf] - [minf]) * ( (100vw - [minw]px) / ([maxw] - [minw]) ));
@media only screen and (max-width: [minw]px) { font-size: [minf]px; };
@media only screen and (min-width: [maxw]px) { font-size: [maxf]px; };

现在我们大致知道CSS锁是什么?那么接下来,我们再花点时间来了解一下,其设计原理。

CSS锁设计原理

接下来通过一些数学计算来向大家阐述CSS锁的设计过程。

CSS中的数学计算和其他程序语言有所不同,在CSS中需要借助calc()函数来做数学计算,有关于该方面的介绍可以阅读《Keep Math in the CSS》和《CSS3的calc()使用》。

视窗单位

先由视窗单位来说起。可能很多同学会和我一样,在做响应式布局时对于文本的排版,比如font-size会采用视窗单位:

h1 {
    font-size: 4vw;
}

期望的是标题在小屏幕有小的字体,大屏幕有大的字体。如果直接使用视窗单位可能会存在两个缺陷:

  • 文本在小屏幕上非常小,比如在320px屏幕下font-size12.8px;在大屏幕时非常大,比如1500px屏幕下font-size60px
  • 它没办法根据用户的喜好来设置文本字号大小

而CSS锁技术旨在解决第一个问题,当然该技术也在尝试着解决第二个问题:遵循用户的喜好来设置字号大小。

CSS锁的计算

前面的内容告诉我们,“CSS锁是一种特定类型的CSS值计算”。比如font-sizeline-height。比如计算font-size的代码:

font-size: calc([minf]px + ([maxf] - [minf]) * ( (100vw - [minw]px) / ([maxw] - [minw]) ));

上面的calc()计算涵盖了:

  • minf:最小字号
  • maxf:最大字号
  • minw:视窗最小宽度(断点1
  • maxw:视窗最大宽度(断点2
  • 在这两个断点之间的实际值是从最小值到最大值之间变化的,该变化是一个线性的变化

比如,我们在低于320px(minw)使用的font-size20px(minf),而高于960pxmaxw)使用的font-size40px(maxf);在断点320px ~ 960px之间采用的font-size20px ~ 40px(minf~maxf),用水位图来描述的话像下面这样:

如果用图表来描述的话,大致像下面这样:

用CSS可以像下面这样描述:

h1 { 
    font-size: 20px;
}

@media (min-width: 320px) {
    h1 { 
        font-size: /* 从20px到40px之间 */; 
    }
}

@media (min-width: 960px) {
    h1 { font-size: 40px; }
}

我们要接受的第一个挑战是真正的实现这个魔幻的值(自动变化的值)。在这里首先引入一个新的值,该值被称为视窗相对值,并且通过calc()来做值的计算:

h1 {
    font-size: calc(20px + '视窗相对值')
}

视窗相对值可以是一个单一的值,比如4vw,也可以是一个更复杂的计算值(也是基于vw或另一个视窗单位计算得来的值)。有关于视窗单位的更多介绍可以阅读《CSS 的值和单位》一文。

由于计算是基于视窗单位的,所以CSS锁有一定的限制。它们只对数字值有效,可以使用calc(),并且可以接像像素值。为什么是像素值呢?那是因为,浏览器客户端最终计算出来的值都是px值。也就是说,视窗单位vwvhvminvmax总是会解析成px。例如,如果视窗宽度是750px,那么1vw就相当于7.5px

在移动端上的一些适配方案,也就是基于这样的原理来做的。比如《再聊移动端页面的适配》中所介绍的技术方案。

从理论上来说,CSS锁对于所有应用数值的属性都应该是有效的,但事实上,它的有用性还是有限的,其中我们不能有效的查询元素,并且将每个元素的动态绑定到媒体查询上是件复杂的事情。为了让事情变得简单化,接下来我们主要聊的相关技术和特性可以运用于font-sizeline-height(或许有一天可以运用于其他的属性,比如widthheight等)以及它们是如何基于px或基于em的断点来构建CSS锁。

特别声明,下面中用到的数学公式来自于《The math of CSS Locks》一文

基于像素断点的CSS锁

先来看基于像素为单位的断点的CSS锁计算。

对于CSS锁而言,我们期望的font-size(或line-height)值在两个断点之间是按比例增长的。而且这种增长是一种线性增长。用图表来表示的话,像下面这样:

上图中红色线其实就是一个简单的线性函数。如果用公式来表达的话,可以是y = mx + b,其中:

  • y表示是font-size(纵轴)
  • x表示的是视窗宽度,单位为像素(横轴)
  • m是函数的斜率(“视窗宽度每增加1px,对应的font-size应该增加多少像素?”)
  • b是在添加任何基于视窗值之前的font-size大小

其中mby = mx + b中是一个不可变的部分。接下来我们要做的是算

剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/css/css-locks.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部