-
Notifications
You must be signed in to change notification settings - Fork 59
Description
🚧 本文还在书写中,如有不足请多指教。
2010 年 @wintercn 老师在 W3C 中文 IG 里发出了《我理想中的 HTML 和 CSS》这封邮件,如今看来很多想法依然很有前瞻性。时间的齿轮滴答滴答的转动,十五年后网上「前端已死」的声音此起彼伏,那么就让我们来看看 Web 技术发展的到底如何了。
Style 可以控制所有交互
随着声明式组件浪潮的兴起,HTML 逐渐抢了很多 JS 的饭碗🍚,许多交互功能变成了通过 HTML 属性来控制和触发。
比如已经讨论了三四年的 Invoker Commands 功能,最近即将在 Chrome 中发布。
command: 执行组件的某个方法。commandfor:找到需要执行组件的 id。
这个示例可以通过纯 HTML 点击按钮,打开一个对话框:
<button command="show-modal" commandfor="my-dialog">This opens a dialog</button>
<dialog id="my-dialog">This is the dialog</dialog>那么同样的,<input type=color> 中的颜色选择器、<select>、<video>、 popover 等都可以通过声明式的属性来控制行为。
如你所见,主要的活都被 HTML 抢去了,CSS 或许心有不甘,心想留点汤汤水水给我喝一喝也行啊。
虽然 CSSWG 对于在 CSS 加入控制交互的行为非常克制,但终究耐不住 Web 用户的需求高涨,还是加入了内卷的行列。比如最近 Chrome 推动的 interest-target-delay 属性,用来控制 popover 的延时显示和消失的时间。所以,「你还记得大明湖畔的夏雨荷么」?CSS 已不再是那个只负责展现层的 CSS 了。
不同的 CSS 单位直接可以互相运算
是的,CSS 现在可以通过 calc 混合运算单位,这是数学函数的基本操作:
.foo {
width: calc(300px - 1cm + 10%);
}稍有遗憾的是,目前带有单位的数值作为除数只有 Safari 支持,例如:calc( 200px / 10% * 1px)。
Chrome 正在实现(2025 年 5月)https://issues.chromium.org/issues/40768696
使用 SVG 控制标签的形状
无论是在 CSS 中还是底层的计算机图形渲染,非矩形的绘制都是不容易的。目前已经初见成效:
border-shape 提案
苹果 WebKit 的人在积极推动的 border-shape提案,可以通过 SVG path 彻底自定义 border 样式的提案。目前已经添加到规范中:https://drafts.csswg.org/css-borders-4/#border-shape-func
corner-shape 提案
此前,我们只能对边框做圆角,通过这个提案,边框可以是斜切,内凹。
甚至未来支持苹果独有的曲率连续的圆角。这完成了工业设计特性在 Web 设计中的落地。也感谢苹果开放相关的算法和专利。
这是当前 CSS 圆角绘制曲率梳,可以看到与直线相接的地方,是不连续的。
这是苹果圆角的曲率梳,过渡更加平滑
对标 SVG path shape() 函数,但具有响应式
在此之前 SVG 中的 path 已经通过 shape()函数完成了语义化的迁移。
比如页面常见的气泡样式,之前我们只能通过 clip-path 来实现:
.bubble {
clip-path: path("m 5 0 H 95 Q 100 0 100 5 V 92 Q 100 97 95 97 H 70 l -2 3 l -2 -3 H 5 Q 0 97 0 92 V 5 Q 0 0 5 0");
}现在可以直接转换为等效的 shape() 函数:
.bubble { clip-path: shape( from 5% 0%,
hline to 95%,
curve to 100% 5% with 100% 0%,
vline to 92%,
curve to 95% 97% with 100% 97%,
hline to 70%,
line by -2% 3%,
line by -2% -3%,
hline to 5%,
curve to 0% 92% with 0% 97%,
vline to 5%,
curve to 5% 0% with 0% 0%);}那么在 CSS 里重新实现 path 的意义是什么呢?我们知道 SVG 里的 path 是无法响应 CSS 单位的,而 shape 正是为此而生的。
在上述例子中,我们通常希望三角形部分始终为固定大小,圆角部分也是保持固定值,而矩形部分则可以根据容器或文本内容来自适应的。shape() 可以这样做:
.bubble { clip-path: shape(from 5px 0,
hline to calc(100% - 5px),
curve to right 5px with right top,
vline to calc(100% - 8px),
curve to calc(100% - 5px) calc(100% - 3px) with right calc(100% - 3px),
hline to 70%,
line by -2px 3px,
line by -2px -3px,
hline to 5px,
curve to left calc(100% - 8px) with left calc(100% - 3px),
vline to 5px,
curve to 5px top with left top); }更强大的是,它还可以和 CSS 变量一起使用,让你可以灵活配置细节参数。
pg.mp4
:root {
--radius: 5px;
--arrow-length: 3px;
--arrow-half-width: 2px;
--arrow-position: 70%;
--arrow-bottom-offset: calc(100% - var(--radius) - var(--arrow-length));
}
.bubble {
clip-path: shape(from var(--radius) top,
hline to calc(100% - var(--radius)),
curve to right var(--radius) with right top,
vline to var(--arrow-bottom-offset),
curve to calc(100% - var(--radius)) calc(100% - var(--arrow-length))
with right calc(100% - var(--arrow-length)),
hline to var(--arrow-position),
line by var(--arrow-half-width) var(--arrow-length),
line by var(--arrow-half-width) calc(-1 * var(--arrow-length)),
hline to var(--radius),
curve to left var(--arrow-bottom-offset) with left calc(100% - var(--arrow-length)),
vline to var(--radius),
curve to var(--radius) top with left top); }我正在写一个工具,可以直接把 SVG path 转换为 CSS shape()