所在的位置: js >> js市场 >> 第期编写更好的CSS代码P

第期编写更好的CSS代码P

前言

本系列最后两部分。今日前端早读课文章由公号:KooFE前端团队授权分享。

正文从这开始~~

使用clamp媒体查询

在下面的示例中,为了调整element的字体大小,给element设置了两段字体样式代码:

.element{font-size:1rem;}

mediascreenand(min-width:px){.element{font-size:1.25rem;}}

如果不使用媒体查询,这些样式上的变化是无法实现的。但对于间距、字体大小等数字属性值,实际上可能需要的是在两个点之间进行线性缩放,而不是让它从一个离散值变为另一个离散值。如果允许使用CSS的新特性,可以利用clamp函数来实现属性值在最小值和最大值之间变化。

clamp函数

clamp是一个CSS函数,它接收三个用逗号分隔的表达式作为参数,按最小值、首选值、最大值的顺序排列:

.element{property:clamp(min,preferred,max);}

当首选值比最小值要小时,则使用最小值;当首选值介于最小值和最大值之间时,则使用首选值;当首选值比最大值要大时,则使用最大值。因此,首选值被限制在一个上限和下限之间。这相当于,将min和max函数关联到了一起,clamp(MIN,VAL,MAX)与max(MIN,min(VAL,MAX))是等价的。

乍一看,clamp似乎用途不大,特别是像下面这样的例子:

.element{font-size:clamp(12px,16px,20px);}

在这个例子中,clamp的计算结果是16px,因为这是个静态值。当首选值是动态的时候,clamp才会大放异彩。其中的一个场景是,使用视口单位vw,其中1vw是当前视口宽度的1%。如果视口的宽度是px那么1vw等价于4px。只要视口宽度发生变化,浏览器都需要重新计算该值并将其解析为CSS像素。这就是我们用线性插值来代替媒体查询的关键因素。

下面的图可以让我们更好地了解clamp的工作原理:

最左边的水平线表示clamp返回的最小值;最右边的水平线对应最大值。在这两个端点之间是首选值,该值呈线性向上延伸。

因此,如果我们以vw单位设置首选值,clamp将保证它不会超出最小值和最大值的界限,而视口单位的性质将允许该值在这两个值之间线性增大。下面是一个例子:

.element{font-size:clamp(1rem,0.45vw+0.89rem,1.25rem);}

也就是说,element的字体至少是1rem,但也不会超过1.25rem,它的首选值是0.45vw+0.89rem。

上面代码的首选值看起来似乎比较随意,但事实上,我们要通过一些数学知识来计算出正确的值。给定了最小/最大字体,要借助一些工具可以帮助我们生成clamp声明。

虽然这里的示例是关于字体大小的,但是clamp可以应用于任何数字属性,包括填充、边距、边框等。我推荐大家在项目中尝试一下clamp,看看它是否适合你们的设计。

尽管这种线性变化看起来很棒,但是如果设计师没有对页面设计这种样式行为,那么在这种场景下使用它可能并不合适。有时,我们确实只是希望属性值在两个离散状态之间变化,而不是让它做连续的线性变化。在这种情况下,媒体查询依然是我们唯一的选择。总而言之,尽管clamp非常有用,并且在许多流式布局中有所应用,但它并不能替代媒体查询。

使用gap简化布局

在CSSgrid出现之前,能够在Web页面上实现动态布局的唯一可行方案就是Flexbox。但是它在使用过程中,存在一个较大的限制:缺少对间隙的支持。尽管一些设计工具支持间隙的概念,但是CSS却不支持间隙,在绝大多数样式中都要用外边距来分隔flex子元素。因此,我们经常不得不对最后一个flex子元素做一些特殊处理:

.flex-item:not(:last-of-type){margin-right:8px;margin-bottom:8px;}

如果要flex布局中的最后一行元素取消底部的外边距,这个功能看似简单,真正实现起来还是挺困难的。除非我们在布局上使用负外边距来抵消这些子元素的外边距。因此,我们不得不写更多的CSS来实现这个任务。

现在,有另外一种解决方案了,那就是在flex布局中支持使用间隙,也就是gap属性。如果不考虑一些老版本浏览器的兼容问题,我们可以写出更简单一些的CSS,如下所示:

.flex-layout{display:flex;flex-wrap:wrap;gap:8px;}

除此之外,我们也可以使用grid实现布局,它不仅支持gap,而且支持自动适配网格容器中每列的尺寸。

.grid-layout{display:grid;grid-template-columns:repeat(auto-fit,minmax(some-min,1fr));gap:8px;}

无论使用上面提到的哪种方式,都不必再担心布局的边缘间距,浏览器会自动为我们处理好,只有相邻的子元素之间存在对应的间隙。如果布局不需要换行,那么它的外边缘就不会有任何不必要的间距。此外,由于flex和grid布局会适配RTL(右对齐),这使得它们非常适合创建RTL安全布局,因为我们不必担心文本的方向性。

使用aspect-ratio设置宽高比

假如,你想做一个3x3的正方形九宫格:

在CSS还没有aspect-ratio属性之前,我们通常是使用内边距百分比技巧来实现响应式的正方形:

.square{height:0;padding-bottom:%;}

或者,使用自定义属性来保持元素的宽度和高度同步。这种方法的主要缺点是,由于要设置显式尺寸,因此无法使用响应式尺寸:

.square{--size:2rem;width:var(--size);height:var(--size);}

但现在,所有主流浏览器都支持aspect-ratio,可以用它更直观地表达元素的宽度和高度之间的关系:

.square{aspect-ratio:1;}

也许,你决定给正方形一个明确的宽度,让它的高度匹配:

.square{aspect-ratio:1;width:2rem;}

或者,使用grid布局,并通过网格的格式上下文来设置其宽度:

.square-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;}.square{aspect-ratio:1;}

不管是哪种方式,都能实现一个正方形,并能够自动地缩放。

关于aspect-ratio,我最喜欢的将它和其他一些属性组合起来使用,比如下面这个圆形:

.circle{aspect-ratio:1;border-radius:50%;}

还有很多使用aspect-ratio的场景值得去探索。一个例子是,根据需要调整嵌入媒体的大小,比如YouTube视频;另一个例子是,增强用户体验,当我们使用HTML属性来设置图片的宽高,使用aspect-ratio可以防止布局发生变化。

如果说每分钟前端都会诞生很多新框架和类库,那么CSS的变化可能要按年来计算。每年CSS会出现一些新特性,包括leading-trim,containerqueries,relativecolors等一系列让人兴奋的功能。只要对CSS知识掌握得越多,就能写出更好的代码。

关于本文译者:

koofe译文:


转载请注明:http://www.aierlanlan.com/rzdk/606.html