开发高级 Web 内容
Develop advanced web content
2021年6月11日
一句话判断
WebGL 2、WebM/VP9、CSS Grid 子网格——Safari 15 一次性补齐了多年来被前端开发者吐槽的几个大坑,Web 兼容性终于不那么让人头疼了。
这场 Session 讲了什么
Safari 15 在 Web 标准支持上做了一次大规模的追赶。Session 用一系列 demo 展示了新支持的 Web 技术,覆盖了图形、音视频、CSS 布局和 JavaScript API 四个方向。
图形方面,WebGL 2 终于被 Safari 支持。这意味着基于 WebGL 的 3D 应用(Three.js、Babylon.js)可以使用更多现代 GPU 特性,比如多采样抗锯齿(MSAA)、3D 纹理和 instanced rendering。配合 Web GPU 的实验性预览,Safari 在图形能力上正在向 Chrome 看齐。
音视频方面,WebM 容器和 VP9 编解码器得到了支持。这对 YouTube 等视频网站来说是重要的一步——之前 Safari 只支持 H.264,导致 4K HDR 内容在 Mac 上需要用 HEVC 编码,兼容性一直是个问题。
CSS 方面新增了 subgrid、:has() 伪类选择器等现代特性。JavaScript 方面支持了 structuredClone()、Worker 中的 ES Modules 等开发者期待已久的 API。
值得深挖的点
:has() 选择器为什么是「CSS 的父选择器」
:has() 被称为 CSS 中最被期待的选择器,因为它实现了从子元素向上选择父元素的能力。比如 div:has(> img) 可以选择「包含直接子元素 img 的 div」。在它出现之前,这种选择只能通过 JavaScript 实现。
Safari 15 是第一个支持 :has() 的浏览器。这对表单验证场景特别有用::has(:invalid) 可以直接给包含无效输入的表单容器添加样式。但要注意,:has() 的性能取决于 DOM 的复杂度——在深层嵌套的 DOM 上使用复杂的 :has() 选择器可能导致布局性能下降。
WebGL 2 到 WebGPU 的迁移路径
WebGL 2 是当前标准,WebGPU 是下一代。Safari 15 同时支持两者,WebGPU 通过实验性 flag 开启。Session 建议新项目优先使用 WebGPU API(如果目标平台支持),因为它的计算着色器(Compute Shader)能力是 WebGL 2 没有的。但如果需要最大兼容性,WebGL 2 仍然是更安全的选择。
代码片段
/* 使用 :has() 实现表单验证样式 */
/* 当表单中包含无效输入时,给整个表单添加红色边框 */
form:has(:invalid) {
border: 2px solid #ff3b30;
}
/* 只选中包含选中复选框的标签 */
label:has(+ input:checked) {
font-weight: bold;
color: #007AFF;
}
/* 根据图片数量调整网格布局 */
.gallery:has(img:nth-child(3)) {
grid-template-columns: repeat(3, 1fr);
}
/* CSS subgrid 实现对齐 */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.card {
display: grid;
/* 子元素继承父网格的列定义 */
grid-template-rows: subgrid;
grid-row: span 3; /* 占据标题、内容、按钮三行 */
}
.card-title {
/* 自动与同列其他卡片的标题对齐 */
}
// structuredClone 深拷贝对象
const original = {
date: new Date(),
buffer: new ArrayBuffer(8),
nested: { value: 42 }
};
// Safari 15 原生支持,不再需要 JSON.parse(JSON.stringify())
const clone = structuredClone(original);
// 可以拷贝 JSON 不支持的类型
console.log(clone.date instanceof Date); // true
console.log(clone.buffer instanceof ArrayBuffer); // true
最佳实践
开始在你的 CSS 中使用 :has() 选择器,但要准备好 fallback。目前只有 Safari 15+ 支持,Chrome 和 Firefox 还在实现中。可以用 @supports selector(:has(*)) 来做特性检测。
如果你的网站使用了 WebGL,现在是时候从 WebGL 1 迁移到 WebGL 2 了。WebGL 2 的 API 更现代,而且所有主流浏览器现在都支持。迁移过程中最大的变化是着色器语言从 GLSL 100 升级到 GLSL 300 es。
还有什么值得关注
MediaRecorderAPI 现在在 Safari 中可用,可以在浏览器端录制音视频流。ImageCaptureAPI 支持从摄像头捕获高分辨率照片,对 Web 应用类产品有用。mediastream的getDisplayMedia在 Safari 15 中支持了preferCurrentTab选项,用于屏幕共享场景。