柏虎资源网

专注编程学习,Python、Java、C++ 教程、案例及资源

用了这5个 @function,CSS代码量减少三分之二?

家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

随着 Chrome 139 对 if() 函数的支持,开发者可以编写更具条理、更动态的 CSS 了。

自定义属性允许存储通过 var() 访问的动态值,而自定义函数则可以执行逻辑,其接受传递给它的参数,并返回一个新值。开发者可以使用基于指定的函数语法(例如 --my-custom-function())来调用,而不是使用 var() 语法。

取反函数

下面的 CSS 自定义函数对一个值取反并返回负数:

@function --negate(--value) {
  result: calc(-1 * var(--value));
}

接着可以在 CSS 声明中使用 --negate() 函数:

html {
  --gap: 1em;
  padding: --negate(var(--gap));
}

不透明度函数

下面函数可以将任何颜色转换为该颜色的不透明度变体,并接受两个值,即颜色值和不透明度值。

// 返回半透明值,rgb 函数的签名为:rgb(from <color> R G B[ / A])
// 定义相对颜色时始终包含关键字 from,后跟表示原始颜色的 <color> 值,后面的颜色基于原始颜色
@function --opacity(--color, --opacity) {
  result: rgb(from var(--color) r g b / var(--opacity));
}
// 使用示例
div {
  background-color: --opacity(red, 80%);
}
// 使用自定义属性,假设有主题变量
.card {
  border-color: --opacity(var(--color-secondary), var(--mostly-opaque));
}

流畅排版函数

CSS 函数的另一个绝佳用途是用于字体大小调整方法 clip() ,从而确保文本在任何屏幕尺寸下始终清晰易读且显示良好。

clip() 函数会将中间值限制在定义的最小值和最大值之间的某个范围内,该函数接受三个参数:最小值、首选值和允许的最大值。

例如:下面的函数用于创建流畅排版,其可以随视口宽度缩放,但也有最小和最大尺寸限制。同时,还提供了一些选项,可以以不同的速率缩放字体,例如:标题的缩放速度比文本的缩放速度快:

@function --fluid-type(--font-min, --font-max, --type: 'header') {
  --scalar: if(style(--type: 'header'): 4vw;
               style(--type: 'copy'): 0.5vw);
  // 结合 if 判断 type 的值类型,并将其放在 --scalar 上
  result: clamp(var(--font-min), var(--scalar) + var(--font-min), var(--font-max));
}
// 使用 --fluid-type 函数,使用默认 header 类型
h1 {
  --header-min: 24px;
  --header-max: 36px;
  font-size: --fluid-type(var(--header-min), var(--header-max));
}
// 使用 --fluid-type 函数,类型为 copy
p {
  --copy-min: 16px;
  --copy-max: 24px;
  font-size: --fluid-type(var(--copy-min), var(--copy-max), 'copy');
}

有条件地圆角边框

这是一个有意思的 CSS 技巧,即当元素接近视口边缘时,有条件地移除圆角边框,从而避免布局异常,因为其会变成全宽,而且完全不需要任何媒体查询!

下面函数中,当框的边缘到达视口边缘(由 --edge-dist 插入,默认设置为 4px)时,移除 border-radius。否则,将其设置为 --radius。此函数使用默认值,因此可以仅使用一个参数来设置半径大小,或者使用两个参数来覆盖默认的 4px 边缘距离。

// --edge-dist: 20px;  /* 页面边缘距离 */
// --radius: 16px;     /* 最大圆角值 */
// 100vw - var(--edge-dist)     /* 视口宽度减去边缘距离 */
// (100vw - var(--edge-dist)) - 100%  /* 差值部分 */
// ((100vw - var(--edge-dist)) - 100%) * 1e5  /* 放大 100000 倍 */
// 乘以一个很大的数(100000)是为了确保中间值足够大,让 clamp 的中间参数能够达到最大值实现 "开关" 效果
@function --conditional-radius(--radius, --edge-dist: 4px) {
  result: clamp(0px, ((100vw - var(--edge-dist)) - 100%) * 1e5, var(--radius));
}
.box {
  // 1rem 的圆角,--edge-dist 默认 4px
  border-radius: --conditional-radius(1rem);
}
.box-2 {
  // 1rem 边框半径,--edge-dist 位于边缘(0px 距离)
  border-radius: --conditional-radius(1rem, 0px);
}

布局侧边栏函数

开发者还可以将自定义函数与媒体查询结合使用,根据特定条件返回不同的结果。此函数会创建一个响应式侧边栏布局,因此只需调用 --layout-sidebar() 即可。在较小的屏幕上,其将占据整个宽度。但在较大的屏幕上,其会创建一个指定宽度的侧边栏和一个占据剩余空间的主内容区域。

下面的示例依然使用默认值,即 --sidebar-width 默认值为 20ch,如果提供了新值则使用新值。

@function --layout-sidebar(--sidebar-width: 20ch) {
  result: 1fr;
  // fr 是 fraction unit(分数单位),是 CSS Grid 布局中的专用单位
  @media (width> 640px) {
    result: var(--sidebar-width) auto;
  }
}

.layout {
  display: grid;
  // 使用默认值
  grid-template-columns: --layout-sidebar();
}

亮暗主题函数

使用 light-dark() 来根据用户偏好设置主题样式仅适用于颜色值,如果想将其用于其他用途,例如:背景图片或调整边框宽度则无能为力。

下面的自定义函数 --light-dark() 结合使用了 if()、:scope、style() 查询和 @function 函数,使 light-dark() 更具可扩展性。

@function --light-dark(--light, --dark) {
  result: if(
    style(--scheme: dark): var(--dark);
    else: var(--light)
  );
}

首先, --root-scheme 是根据 :root 级别的 prefers-color-scheme 媒体查询设置的,其会捕获操作系统设置:

:root {
  --root-scheme: light;
  --scheme: light;
  @media (prefers-color-scheme: dark) {
    --root-scheme: dark;
    --scheme: dark;
  }
}

然后,使用 @scope 和内联 if() 函数检查 [data-scheme] 属性。如果该属性的值为 system,则将 --root-scheme 的值应用于元素的 --scheme。否则,使用属性中提供的值(例如 “light” 或 “dark”):

@scope ([data-scheme]) {
  :scope {
       // 获取 HTML 中属性的值
       --scheme-from-attr: attr(data-scheme type());
      // 综合设置 --schema 变量的值,考虑了 HTML 属性和 --root-schema 的值
      --scheme: if(
        style(--scheme-from-attr: system): var(--root-scheme);
        else: var(--scheme-from-attr)
      );
    color-scheme: var(--scheme);
    /* To make the native light-dark() work */
  }
}

下面是使用的方式:

[data-scheme] {
  color: light-dark(#333, #e4e4e4);
  background-color: light-dark(aliceblue, #333);
  border: 4px --light-dark(dashed, dotted) currentcolor;
  font-weight: --light-dark(500, 300);
  font-size: --light-dark(16px, 18px);
}
<div class="stylable-thing" data-scheme="light">
	…
</div>

参考资料

https://una.im/5-css-functions/

https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb

https://developer.mozilla.org/en-US/docs/Web/CSS/clamp

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言