Safari 17.4 中的 WebKit 功能

与 Safari 15.4 和 Safari 16.4 一样,今年三月发布的 Safari 17.4 对 Web 开发者来说意义重大。我们很荣幸地宣布又增加了 46 项功能和 146 项 Bug 修复。

您可以在 iOS 17.4、iPadOS 17.4、macOS Sonoma 14.4、macOS Ventura、macOS Monterey 和 visionOS 1.1 上体验 Safari 17.4。

架构改进

发布新功能,供您在为用户构建网站和 Web 应用时使用,总是令人兴奋。WebKit 工程师还在实现新 Web 平台功能之外,从事许多重要的项目。最近,大量的精力投入到多个基础设施项目中,以增强 WebKit 的长期发展。

我们完成了我们多年来重写内联布局引擎的最后一期(稍后详细介绍)。我们构建了两个新的 iOS 框架,其中包含数百个新的 API,以支持 Web 浏览器使用的功能,包括多进程、JIT 以及高级键盘和触摸事件访问——我们正在将 WebKit 转向使用这些新框架。我们正在开展其他几个大型项目,以深化安全和隐私。我们一直在努力使 Safari 运行更快。多年来,Safari 一直保持着世界上最快浏览器的桂冠。对我们来说,不断突破速度的界限非常重要,因为您构建的网站会越来越复杂。最近数百项更改使得 Safari 17.4 的性能显着提升。

Web 应用

Safari 17.4 为 Mac 上的 Web 应用带来了两项改进。

首先,Safari 在 macOS Sonoma 上增加了对 shortcuts 清单成员的支持。这为您在 manifest 文件中提供了一种机制,用于定义将出现在文件菜单和 Dock 上下文菜单中的自定义菜单命令。

Web Kittens web app open on macOS, with the File menu showing and four custom shortcuts listed
在 Mac 上,我们的 Web Kittens Web 应用包含四个快捷方式。您可以在“文件”菜单中看到它们:New Kitten、Discover、Messages 和 Notifications。它们各自通过转到相应的 URL 打开一个菜单项。

Web 应用快捷方式由 name(您希望出现在菜单中的文字)和 url 组成。当用户激活命令时,它会在 Web 应用内部打开指定的 URL。

"shortcuts": [
  {
    "name": "New Kitten",
    "url": "/new-kitten"
  },
  {
    "name": "Discover",
    "url": "/discover"
  }
]

用户可以在“系统设置”>“键盘”>“键盘快捷键”>“应用快捷键”中设置应用菜单命令的自定义键盘快捷键。默认情况下,macOS 不为 Web 应用快捷方式分配任何键盘命令。

其次,Safari 17.4 现在在 macOS Sonoma 上支持 categories 清单成员。此 成员 为您提供了一种机制,用于告诉浏览器您的 Web 应用属于哪个 类别。在 Mac 上,当用户创建包含 Web 应用的启动台文件夹时,该文件夹会自动相应地命名。

Launchpad on macOS showing two app icons in a group titled Social Networking

表单元素

开关控件

开关是许多用例中流行的界面,但到目前为止,还没有一种简单的方法可以在网页上放置开关。相反,开发者可能会使用复选框输入字段,通过 appearance: none 删除复选框的视觉外观,并编写自定义样式以创建类似开关的东西。

现在,通过适用于 Safari 17.4 的 WebKit,HTML 支持原生开关。如果您编写 <input type="checkbox" switch>,浏览器将简单地为您创建一个开关,并将其映射到 role=switch 和相关的 ARIA 功能。

在 Safari 17.4 中尝试此演示。目前,在其他浏览器中您会看到三个复选框。

扩展当前的 HTML 复选框提供了多项好处,并遵循了 W3C 的 HTML 设计原则。首先,这种设计优雅降级——这意味着您今天就可以使用 <input type="checkbox" switch>。支持的浏览器将显示开关,而不支持的浏览器将显示复选框。没有任何用户会遇到糟糕的体验,而且您不必等到所有用户都拥有支持此功能的浏览器才能在您的网站或 Web 应用中利用它。这种设计也没有重复造轮子。它与表单控件在 Web 上始终工作的方式相匹配,并且感觉就像您熟悉的的的代码一样。它是 Web 的增量演变。作为一种简单的解决方案,它避免了不必要的复杂性

accent-color 属性可用于更改开关在“打开”状态下的背景颜色。而且,与其它表单控件一样,您可以使用 appearance: none 来删除系统默认样式并应用您自己的样式,也许可以同时利用 :before:after

未来,可能会有多个伪元素,使您更轻松地使用自定义样式来设置开关样式。您今天可以在 Safari 技术预览版中尝试 ::track::thumb,并让我们知道您对此方法的看法。在启用“::thumb 和 ::track 伪元素”功能标志后,请参阅它们在此演示中的工作原理。(这些伪元素将等待,直到 CSS 工作组提出、讨论并解决了关于表单控件样式的更全面计划后才发布。)

垂直书写模式

一开始,Web 就一直是交互式的。即使在没有任何自定义样式方法可用之前,表单控件和输入字段就提供了用户与网站和彼此之间进行通信的手段。Web 最初也是在一个拉丁字母(许多语言,包括英语,都使用)被假定为默认的时代设计的,其书写模式是水平从上到下。

三十年来,表单控件都假定采用水平书写模式。对于中文、日文、韩文和蒙古文等语言的垂直书写模式排版不包括垂直表单控件。现在,这种情况已经改变了。从 Safari 17.4 开始,支持垂直表单控件。这包括仪表、范围、进度和其他表单控件,它们在垂直布局时可以在任何语言中形成出色的 UI。

支持此功能的浏览器中尝试此垂直表单控件演示

选择框中的水平线

您可以在 <select> 元素内使用 <hr> 元素(水平线)来绘制分隔线。WebKit 在 macOS 上的 Safari 17.0 中提供了支持。现在,iOS 17.4、iPadOS 17.4 和 visionOS 1.1 上的 Safari 17.4 也支持此功能。

Safari window floating in front of mountains in Vision Pro, with a a select menu open on a web page, showing lines between list items

尝试演示并阅读关于 hrselect 中如何多年前获得支持,后来消失,现在又恢复的故事。

更多内容

适用于 Safari 17.4 的 WebKit 还增加了对 macOS 上 <input type="date">showPicker() 方法的支持。

CSS

内联布局

过去几年,WebKit 一直在进行的基础设施项目之一是完全重写我们的内联布局引擎。Safari 17.4 标志着该项目的完成和有二十一年历史的旧行布局引擎的退役。

内联布局对于网页内容的显示至关重要。它决定了所有文本和其他内联级别内容的大小和布局——包括换行、对齐、间距和基线对齐。作为开发者,我们通常关注网页上不可见的块框,并编写 CSS 使用流、表格、Flexbox 或 Grid 来布局这些框。这些框内的内容使用复杂的内联布局算法放置,而开发者通常不需要过多考虑。

多年来,我们一直在逐步发布新的内联布局引擎。随着新引擎的完成度越来越高,网页上越来越多的内容由新引擎进行定位。这意味着用户已经从 WebKit 的新内联布局引擎中受益一段时间了。只有在新引擎中尚未实现的功能才会触发旧系统。最后一个主要步骤是Ruby的重新实现——现在它也成为了一个合适的内联布局功能,解决了过去的不足之处。

这类项目可能会带来中断。浏览器团队通常会选择在多年的重写项目进行中不发布任何新功能。WebKit 则选择继续发布新功能,通常会实现两次——一次在旧行布局引擎中,另一次在新内联布局引擎中。现在这项工作已经完成,我们不再需要重复实现任何功能。这项工作也使我们能够处理大量在 bugs.webkit.org 上报告的 Bug,确认它们不再是问题,并将其关闭为已修复。

我们对 WebKit 搭载新引擎的未来感到兴奋。这项投资通过与最新 Web 标准对齐,减少内联布局 Bug,提高性能,改进稳定性,以及能够更轻松地实现新功能,从而提高了互操作性。内联布局的完成也标志着其他格式化上下文(从 Flexbox 开始)的布局引擎重写工作的开始。

内容无处不在

当 Flexbox 发布时,它为 Web 带来了强大的新工具——盒对齐align-content 属性使得在盒子内部垂直居中内容成为可能!您也可以用它将内容对齐到盒子底部,对齐文本基线等等。当 CSS Grid 发布时,盒对齐在第二种布局模式中也成为可能。自 2017 年以来,您已经能够对齐 Flexbox 和 Grid 容器的直接子元素。

现在,我们很自豪成为第一个在另外两个格式化上下文中——块布局和表格布局中,发布 align-content 支持的浏览器。这意味着,如果您只想在块方向上对齐盒子的内容,您不需要涉及 Flexbox 或 Grid。此外,您现在可以将对齐与浮动混合使用,并且可以在表格单元格内部使用它。

div { align-content: center; } /* one-line vertical centering */

此外,我们更新了 Safari 17.4 的 WebKit 中滚动容器上 align-contentjustify-content 的处理方式。现在,例如,您可以使用 CSS 将初始滚动位置设置为内容的末尾而不是开头。

div { overflow: auto; align-content: unsafe end; } /* end-aligned scroller */

务必在不同浏览器中测试滚动容器上的对齐方式,因为许多浏览器仍在更新到指定行为的过程中。尚未更新的浏览器可能会裁剪内容。

CSS 作用域

今天的网站可能很复杂,大型团队在多个项目上协作,依赖模式库或框架来保持一切有条不紊和一致。对于大型团队来说,处理 CSS 的层叠关系可能变得很困难。Cascade Layers 和 :has() 等工具改变了游戏规则,允许开发者更巧妙地应用样式。然而,开发者通常希望有一种方法能够将样式限定在他们正在处理的单个组件内,而无需担心全局或防止意外后果。

CSS Scoping 的创建是为了提供几种更强大的选项来组织和构建 CSS。(请注意,多年来关于样式作用域如何工作存在许多争论。搜索“CSS scoping”通常会得到旧的未实现的完全不同的想法。)

适用于 Safari 17.4 的 WebKit 增加了对 @scope 规则的支持,并扩展了 :scope 伪类的功能。作用域以某些令人惊讶的方式改变了层叠的工作方式,因此在广泛部署之前,请务必阅读其影响。

如果您的项目大量使用组件,这些组件是独立构建并以随机顺序加载的,那么作用域可以通过确保某些样式仅适用于特定元素的内容,而不会应用于页面上的其他任何内容来帮助您。

默认情况下,项目中的所有 CSS 都普遍适用。它的“作用域根”是 <html>。而 :root 伪元素指的是 DOM 中的根元素——html 元素。CSS Scoping 允许您使用 <style> @scope 将作用域根重置为某个元素,即 <style> 元素的父元素。

<article id="my-component">
  <style>
    @scope {
      h1 { font-size: 4rem; }
    }
  </style>
  <h1>This is 4rem text.</h1>
</article>

<h1>This will not be styled by the CSS above.</h1>

在这种情况下,由于 <article><style> @scope 的直接父级,所有在 @scope 内部定义的样式将只影响 articlearticle 内部的内容。article 之外的任何内容都不会受到影响。

但这并非 CSS Scoping 的全部功能。假设我们想将样式应用于侧边栏,但又不希望这些样式应用于侧边栏中的所有内容。我们可以使用 @scope 来创建一种甜甜圈——中间有一个洞,样式不适用。

@scope (aside) to (section) {
  h2 {
    font-size: 3rem;
  }
}
<aside id="my-sidebar">
  <h2>This is 3rem text.</h2>
  <section>
    <h2>This is not styled by the CSS above.</h2>
  </section>
</aside>
您可以在支持此功能的浏览器中尝试此演示

通过定义具有范围开始选择器(aside)的作用域根和具有范围结束选择器(section)的作用域限制,我们可以有效地阻止样式的层叠。

此外,无论何时使用 CSS Scoping,当特异性(specificity)相同时,它都会彻底改变发生的情况。

自 CSS 创建以来,当多个选择器具有相同的特异性时,最后出现在 CSS 层叠中的那个选择器会被应用。例如,如果这是你的 CSS:

.blue h1 { color: blue; }
.yellow h1 { color: yellow; }

那么这就是你的结果。

<section class="blue">
  <section class="yellow">
    <h1>This headline is yellow.</h1>
  </section>
</section>

<section class="yellow">
  <section class="blue">
    <h1>This headline is yellow.</h1>
  </section>
</section>

标题始终是黄色的,因为 .yellow 在 CSS 文件中出现得更晚。HTML 中的顺序无关紧要。

但是有了作用域,当它们的特异性相同时,应用于 DOM 中更接近作用域根的元素的那个选择器将起作用。

我们用 @scope 代替后代选择器。

@scope (.blue) { 
  h1 { color: blue; }
}
@scope (.yellow) {
  h1 { color: yellow; }
}

现在,标题颜色由 HTML 中的 DOM 顺序决定,而不是 CSS 中的层叠顺序。

<section class="blue">
  <section class="yellow">
    <h1>This headline is yellow.</h1>
  </section>
</section>

<section class="yellow">
  <section class="blue">
    <h1>This headline is blue!</h1>
  </section>
</section>

.yellow 是更近的祖先时,标题是黄色的;当 .blue 是更近的祖先时,标题是蓝色的。

这是 CSS 工作方式的一个根本性改变,所以不要措手不及。使用 CSS Scoping 时要多加思考和小心。

请注意,像 .blue h1 { } 这样的选择器比像 @scope (.yellow){ h1 { }} 这样的选择器具有更高的特异性。作用域根选择器的特异性不会添加到 @scope 规则内选择器的特异性中,这与 Nesting 不同。而且 .blue h1 的特异性高于 h1

适用于 Safari 17.4 的 WebKit 也扩展了 :scope 伪类的用途。当在 @scope 块内部使用时,:scope 匹配该块定义的范围根。这提供了一种从 @scope 块本身内部对范围根应用样式的方法。在以下示例中,:scopearticle 元素应用了边框。

<article id="my-component">
  <style>
    @scope {
      :scope { border: 1px solid black; }    
      h1 { font-size: 4rem; }
    }
  </style>
  <h1>This is 4rem text.</h1>
</article>
您可以在支持此功能的浏览器中尝试此演示

空白和文本换行

多年来,CSS 中的 white-space 属性提供了一种机制,可以同时做两件事:1) 定义空白是否以及如何折叠,2) 定义行是否以及如何换行。CSS 工作组此后指出,在一个属性中处理两种不同的质量可能是一个错误。随着 text-wrap 的引入,CSSWG 重新思考了这些属性的长短版本如何组合成一种更合理且给我们所需灵活性的架构。

现在,white-space 属性是 两个 新的 长手属性的缩写:white-space-collapsetext-wrap-mode,两者都已在 Safari 17.4 的 WebKit 中添加。这些长手属性允许您独立更改折叠和换行模式,彼此互不影响。

white-space-collapse 属性控制空白如何折叠。默认情况下,它设置为 collapse,导致多个空格字符串变为单个空格。您可以将值更改为 preserve 以保留所有空格,或使用其他值:preserve-breakspreserve-spacesbreak-spaces。这些值都像多年来与 white-space 属性一起使用时那样表现。

新的 text-wrap-mode 属性提供了一种机制,用于设置文本是否应换行。wrap 值将其打开,nowrap 值将其关闭。

这项工作为 text-wrap 简写及其长手属性 text-wrap-styletext-wrap-mode 奠定了基础,其中一些您目前可以在 Safari 技术预览版中测试。

间距中的百分比

适用于 Safari 17.4 的 WebKit 增加了对 letter-spacingword-spacing 中百分比的支持。这允许您将间距定义为元素 font-size 的百分比——并且即使在后代元素上字体大小增大或缩小时,也能保持跟踪 font-size

样式化语法和拼写错误

适用于 Safari 17.4 的 WebKit 增加了对 ::spelling-error::grammar-error 伪元素的支持。这些使得为浏览器标记为拼写错误或语法错误的文本创建自定义样式成为可能。

生成内容的替代文本

Web 上绝大多数内容通过 HTML 传达,但 CSS 确实具有向页面插入内容的能力。到目前为止,有时这类内容无法访问。现在,在适用于 Safari 17.4 的 WebKit 中,您可以提供带有可访问的 content 回退的替代文本 — content: "foo" / "alt-text";

例如,我们可能希望在某些链接前加上小小的 ⓘ 图标,让用户知道此项目会引导他们获得更详细的信息。该符号可能会被屏幕阅读器读作“带圈拉丁小写字母 I”或“信息源结合封闭圈”,这两者都未能很好地传达预期的目的。也许更好的体验是简单地听到“信息:”。

.info::before {
  content: "ⓘ" / "Info:";
}

以前,-webkit-alt 属性实现了此功能。它已被弃用,取而代之的是新的内容 alt 文本语法。新语法也更具表现力,因为它允许层叠,并允许您将多个字符串和 attr() 作为替代文本链接起来。

过渡

当 CSS Transitions 被创建时,它们允许作者通过插值在旧值和新值之间创建渐进的定时过渡。然而,有时插值是不可能的。例如,float: leftfloat: right 之间没有有意义的中间值,因此,过渡忽略了这些属性。它们只是立即从第一种状态跳到第二种状态,无法定义何时应该发生跳变。

然而,Web 开发者一直希望能够至少定义离散属性何时发生过渡。因此 CSS 工作组找到了一种方法来实现这一点。现在,您可以告诉浏览器您希望元素能够过渡离散属性值,这让您可以使用缓动函数来控制它们的过渡时间。

适用于 Safari 17.4 的 WebKit 增加了对 transition-behavior 属性的支持。transition-behavior: allow-discrete 规则允许您启用离散属性值之间的过渡,以便您可以通过 transition 控制其时间。

li {
  list-style: disc;
  color: blue;
  transition: all 2s, list-style 0.5s step-end;
  transition-behavior: allow-discrete;
}
li:hover {
  list-style: square;
  color: red;
}
支持此功能的浏览器中尝试此演示代码。关闭 transition-behavior 以查看差异。

:has()

:has() 伪类提供了巨大的价值。我们通过在 :has() 中添加对其他伪类的支持,使其变得越来越强大。适用于 Safari 17.4 的 WebKit 增加了对 :has(:any-link):has(:link):has(:-webkit-any-link) 的支持,使得根据元素是否包含链接来选择元素成为可能。

更多内容

适用于 Safari 17.4 的 WebKit 添加了对 CSS 自定义属性::backdrop 伪元素的支持,允许将变量应用于 dialog 元素和其他顶层项后面的背景。

适用于 Safari 17.4 的 WebKit 还增加了对 circle()ellipse()offset-position 支持。

此外,适用于 Safari 17.4 的 WebKit 使 -apple- 前缀的伪元素不再有效。

Web API

此版本的 Safari 增加了一系列小型的 Web API,为您提供了额外的开发者工具。

通过支持 element.checkVisibility() 方法,您可以在各种条件下确定元素的可见性,包括 CSS 属性(如 displayvisibilityopacity)的应用方式。

适用于 Safari 17.4 的 WebKit 还扩展了其 声明式 Shadow DOM 支持。现在可以使用 Element.prototype.setHTMLUnsafe()ShadowRoot.prototype.setHTMLUnsafe()Document.parseHTMLUnsafe() 方法,以及 ShadowRoot 的 clonable 属性。setHTMLUnsafe() 方法的工作方式类似于设置元素的 innerHTML 属性,允许不安全的 DOM 树变异,但额外支持声明式 Shadow DOM。parseHTMLUnsafe() 方法类似地解析不安全的 HTML 并支持声明式 Shadow DOM,并返回一个文档。而 clonable 只读布尔属性允许您检测 Shadow DOM 是否可克隆。

适用于 Safari 17.4 的 WebKit 增加了对 CustomStateSet 接口的支持,用于自定义元素状态管理。该接口包括 add()delete() 或检测元素是否 has() 给定状态等方法。重要的是,添加到自定义元素的这些状态可以通过自定义元素的使用者使用 :state() 伪类进行样式设置。

DOMMatrixReadOnly 接口现在支持 scaleNonUniform() 方法,该方法创建一个在 X、Y 和 Z 轴上进行缩放的新 DOMMatrix。必须指定 X 轴缩放因子,但 Y 和 Z 轴默认为 1。缩放以给定原点为中心,该原点默认为 (0, 0, 0)

最后,适用于 Safari 17.4 的 WebKit 增加了对 AbortSignal.any() 的支持,这为您提供了一种方便的方式来组合中止信号,例如用户输入(例如用户点击取消按钮)和超时,以向异步操作发送中止信号。

JavaScript

Safari 17.4 中的新 JavaScript 功能通过 promise 解析器、改进的国际化格式、ArrayBuffer 所有权管理和数组分组功能增加了新的表达性和便利性。

适用于 Safari 17.4 的 WebKit 增加了对 Promise.withResolvers 静态方法的支持。它允许开发者方便地创建 Promise 并在创建后配置解析和拒绝处理程序。该方法返回 Promise 以及解析和拒绝函数。

const { promise, resolve, reject } = Promise.withResolvers();

现在 Intl.DateTimeFormat 支持 TimeZoneOffset 格式。它允许您根据本地时间是提前还是落后于 UTC 时间,以正或负的小时和分钟指定本地时间与 UTC 时间的差值。

new Intl.DateTimeFormat("en-US", {
    dateStyle: 'long',
    timeStyle: 'long',
    timeZone: '-0800'
}).format(new Date())

此外,Number.prototype.toLocaleStringIntl.NumberFormat 已更新,以使字符串表示与最近的规范更改正确对齐。

还增加了新的表达性 API,用于管理 ArrayBuffers 的所有权概念。ArrayBuffer.prototype.transfer 创建一个新的 ArrayBuffer,其内容和属性与目标 ArrayBuffer 相同(例如可调整大小),并将其与原始 ArrayBuffer 分离。您可以使用 ArrayBuffer.prototype.transferToFixedLength() 来确保一个不可调整大小的 ArrayBuffer,其内容与缓冲区相同。ArrayBuffer.prototype.detached 将告诉您缓冲区是否已传输并分离。

适用于 Safari 17.4 的 WebKit 还增加了数组分组功能,其中包括 Object.groupByMap.groupBy 方法。这些方法为您提供了功能强大且简单的数据集分组工具。

const todos = [
    { task: "Water the flowers", context: "home", estimate: "5 minutes" },
    { task: "Get the TPS report done", context: "work", estimate: "45 minutes" },
    { task: "Find new insurance", context: "home", estimate: "180 minutes" },
    { task: "Fix a website bug", context: "work", estimate: "25 minutes" },
    { task: "Answer emails", context: "anywhere", estimate: "10 minutes" }
];

let contextual_tasks = Object.groupBy(todos, ({ context }) => context);
console.log(contextual_tasks);

let tasks_by_time = Map.groupBy(todos, ({ estimate }) => {
    return parseInt(estimate.split(' ')[0]) < 15 ? "short" : "long";
});
console.log(tasks_by_time);

媒体

额外编码器

适用于 Safari 17.4 的 WebKit 增加了对多种音频和视频编解码器的支持。

首先,适用于 iOS、iPadOS 和 visionOS 的 Safari 17.4 中的 WebKit 增加了对 WebM 的支持。虽然 WebM 容器(同时支持 VP8 和 VP9 视频编解码器)自 Safari 14.1 以来已在 macOS 上完全支持,但在 iOS 和 iPadOS 上,支持仅限于 WebRTC 中的 VP8。现在,WebM 在所有平台上都得到全面支持。

Vorbis 音频编解码器现在也支持 iOS 17.4、iPadOS 17.4 和 visionOS 1.1 的 WebKit 中。

而且,适用于 Safari 17.4 的 WebKit 通过增加对 HEVC 编解码器的支持,扩展了 WebCodecs 的功能。

源优先级

当 HTML5 中引入 <video><source> 元素以支持视频嵌入时,Web 标准规定应选择并播放浏览器识别的第一个文件。这使得开发者有责任确保将最佳文件列在质量较差的文件之前。

<video>
   <source src="movie.webm">
   <source src="movie.av1">
   <source src="movie.mov">
</video>
你确定列出的第一个格式总是比其他格式更好的选择吗?

在更简单的时代,只有少数几种编解码器可用时,这很有道理。现在,有许多不同质量的编解码器。开发者并非总能知道哪个文件对用户来说是最好的流媒体文件。而且,不可能将它们按一种对所有用户都最佳的特定顺序排列。

浏览器可能能够轻松播放所提供的多个文件,但其中一个文件可能使用用户的设备可以使用硬件解码的编解码器进行压缩,而其余文件可能只能通过软件解码。

使用硬件解码无疑能带来更好的用户体验。这样做会显著影响功耗,并延长电池续航时间。因此,现在,在适用于 Safari 17.4 的 WebKit 中,将选择最适合用户的文件,而不是默认选择第一个受支持的文件。在各种 Apple 设备上支持硬件解码的视频编解码器包括 VP9、H.264、HEVC 和 AV1。

WebVTT

适用于 Safari 17.4 的 WebKit 增加了对 HTML 字符实体WebVTT(Web 视频文本轨道格式)的支持,WebVTT 是用于向网页视频文件添加字幕和隐藏式字幕的技术。HTML 实体是一种编写特殊字符的方式,避免浏览器误认为它们是 HTML 代码的一部分。例如,&middot; 表示“·”字符。

MediaStream

适用于 Safari 17.4 的 WebKit 增加了对 MediaStream 的 whiteBalanceMode 支持。在摄影中,调整白平衡是一种补偿技术,用于解决在不同光照条件下“白色”呈现不同颜色的问题。阳光非常偏蓝,而室内灯光则往往偏橙。我们的大脑会自动调整,所以作为人类,我们很少注意到。但相机需要技术来帮助它们调整色温,以便最终的照片或视频具有人们期望的色彩。现在,Web 上 MediaStream Image Capture API 支持白平衡模式。

SVG

适用于 Safari 17.4 的 WebKit 增加了对 SVGFESpecularLightingElementkernelUnitLengthXkernelUnitLengthY 支持。

WebGL

适用于 Safari 17.4 的 WebKit 增加了对四个新的 WebGL 扩展的支持:EXT_clip_controlEXT_depth_clampEXT_polygon_offset_clampWEBGL_polygon_mode

Web Assembly

适用于 Safari 17.4 的 WebKit 启用了扩展常量表达式,以支持更高级的 WebAssembly 链接。

Web Inspector

Safari 17.4 的 Web Inspector 有两个新功能。首先,当页面尝试加载被锁定模式阻止的字体 URL 时,会在控制台中记录一条消息。

其次,Web Inspector 现在将源映射的加载错误进行分组。源映射文件用于将合并或压缩的文件转换回其原始状态。分组加载错误有助于减少调试时的干扰。您可以在 Web Inspector 设置的“实验设置”下禁用此行为。

Safari 的更改

Safari 17.4 本身包含三项 UI 和用户体验的更改。首先,您现在可以将“收藏夹栏”配置为仅显示带有其图标的书签。编辑收藏夹栏中的书签名称,并删除名称。图标将保留。

其次,Safari 17.4 现在支持在 <iframe> 元素内部进行网页翻译。

第三,Safari 17.4 增加了对 Apple Cash 虚拟卡号的支持,并在使用自动填充时显示用户的 Apple Cash 余额。

Safari 扩展

Safari 17.4 包含了对 Web 扩展的更改,允许扩展即使在没有私人浏览权限的情况下也能打开私人浏览窗口。

Web 认证

适用于 Safari 17.4 的 WebKit 增加了对 WebAuthn 的 PublicKeyCredentials.getClientCapabilities() 函数的支持。使用它可以查找支持哪些 WebAuthn 功能。它返回一个包含功能及其值的 record<DOMString, boolean> Promise。

Bug 修复及更多

除了所有新功能外,适用于 Safari 17.4 的 WebKit 还包含了对现有功能的完善工作。

辅助功能

  • 修复了正确公开 <summary> 元素角色。(13661104)
  • 修复了带 ARIA 角色的 iframe 中不可访问的内容。(104611075)
  • 修复了 VoiceOver 在带 combobox 角色的文本输入框中词语回音问题。(112488137)
  • 修复了 innerHTMLinnerText 对标签的更改未更新其对应输入元素的辅助标题的问题。(113872525)
  • 修复了 <details><summary> 元素未包含在 VoiceOver 表单控件菜单或列表中的问题。(117308226)
  • 修复了 comboboxesaria-activedescendant 更改时未通知辅助技术的问题。(117747058)
  • 修复了切换辅助功能偏好设置以正确更新表单控件外观的问题。(117914468)
  • 已修复:移除了标题角色的默认 ARIA-level 标题,与 ARIA 规范的移除相匹配。(119059172)
  • 修复了许多常见 Shadow DOM 场景中辅助功能标签缺失文本的问题。(120223342)

浏览器更改

  • 修复了在后台标签页中加载 ⌘点击片段链接的问题。(119079650)

CSS

  • 修复了深色配色方案的默认链接颜色对比度问题。(61149466)
  • 修复了 getComputedStyle() 对无效伪元素的问题。(98504661)
  • 修复了 querySelector() 不会因 -webkit- 前缀的伪元素而抛出异常的问题。(99299129)
  • 修复了在输入日期时触发 :user-invalid 的问题。(110687369)
  • 已修复:更新了 text-transform: full-size-kana 以与 Unicode 15 对齐。(111508663)
  • 修复了 contain: inline-size 破坏 grid-template-rows: auto 的问题。(113915953)
  • 修复了当 Safari 标签栏不可见时,svhdvh 单位意外相等的问题。(115085360)
  • 修复了 mixed-blend-mode 与根背景正确混合的问题。(115688282)
  • 修复了 backdrop-filter 的多项互操作性改进。(115703346)
  • 修复了 oklaboklch 亮度值钳制的问题。(116195533)
  • 修复了在弹性项目内容更改或样式更改影响其项目首选宽度计算时弹性布局失效的问题。(117181858)
  • 修复了选择间隙以预期 ::selection 伪元素颜色进行绘制的问题。(117796745)
  • 修复了 -webkit- 前缀伪元素的解析和序列化问题。(118081134)
  • 修复了 ::backdrop 允许在 ::slotted() 之后使用的问题。(119015204)
  • 修复了允许 :checked:indeterminate 同时匹配的问题。(119075969)
  • 修复了带大小约束和 min-height 的网格行尺寸不正确的问题。(119736473)
  • 修复了将基本形状 rect()xywh() 的值计算为等效的 inset()。(119739406)
  • 修复了 :has(+ :not(.class)) 伪类选择器性能低下问题。(119819247)
  • 修复了 CSS content 计算值序列化问题。(120061551)
  • 修复了 getComputedStyle()KeyframeEffect.prototype.pseudoElement 中的伪元素解析,要求它们以 ::(或 : 表示 4 个遗留伪元素)开头。(120170550)
  • 修复了 CSS linear() 缓动问题。(120290721)
  • 修复了当容器在 :host 选择器中命名时,跳过命名 at-rule 容器的问题。(120428386)
  • 修复了 :not(:has(:not(foo))) 被错误分类为破坏作用域的问题。(120492012)
  • 修复了容器查询中 ::slotted 伪元素的名称解析到错误范围的问题。(122224135)
  • 已使 -apple- 前缀伪元素不再有效。(120268884)

表单

  • 修复了 iPad 上移除 <option><select> 未刷新下拉菜单的问题。(88292987)
  • 修复了 text-indent 影响文件输入中选定文件标签的问题。(105223868)
  • 修复了 dir=autohiddenpasswordsubmitresetbutton 输入类型起作用,使 dirnamepasswordsubmit 输入类型起作用,并从 number 输入类型中移除了 dirname 支持。(113127508)
  • 修复了带 webauthn 令牌的 autocomplete 序列化问题。(116107937)
  • 修复了 <optgroup> 之外的 <option> 元素被添加到前一个组的问题。(117930480)

全屏

  • 修复了在 iOS、iPadOS 和 visionOS 中进入和退出全屏模式后,视口单位不正确的问题。(120496571)

HTML

  • 修复了 <canvas> 内的 system-ui 字体家族问题。(117231545)
  • 修复了 <progress> 使用页面首选渲染更新间隔的问题。(118976548)
  • 修复了属性值不区分大小写匹配的属性选择器列表中缺失 direction 属性支持的问题。((119432066)

JavaScript

  • 修复了 Function 构造函数的字符串化算法以匹配规范。(102065151)
  • 修复了块级函数声明在全局代码中具有正确作用域的问题,并使可提升的块级遗留函数声明的检测与规范对齐。(113880075)
  • 修复了生成器中检测语义错误的边缘情况。(117497786)
  • 修复了 Temporal API 对意外的原生类型抛出 TypeError 的问题。(117992134)
  • 修复了 Temporal 选项处理以与规范对齐的问题。(118088676)
  • 修复了 Temporal.Now.timeZone() 更新为 timeZoneId() 的问题。(118674314)

加载

  • 修复了 Link-stylesheet 元素对于非 text/css 和非 2XX 响应不触发加载事件的问题。(116112223)
  • 修复了 link-stylesheet 元素对于非 2XX 响应(例如不重定向的 3XX 响应)不触发加载事件的问题。(116331826)

锁定模式

  • 修复了 Lockdown Mode 在具有 COOP 和 COEP HTTP 头的站点上禁用。(119503109)

媒体

  • 修复了 WebVTT 区域根据规范定位的问题。(23091897)
  • 修复了 MediaRecorder 暂停后在每个 timeslice 事件上继续调用 ondataavailable 的问题。(115979604)
  • 修复了转译 annexb 数据时 HEVC 解码器的问题。(116768196)
  • 修复了 WebVTT 将负百分比视为无效值的问题。(117615681)
  • 修复了 <video> 元素上的 object-fit: fill 问题。(118020922)
  • 修复了 WebRTC 通话在使用 Siri 后有时会自动取消静音,导致传入音频丢失的问题。(118461093)
  • 修复了在浅色模式下全屏视频播放时,顶部和底部出现白条的问题。(118530255)
  • 修复了始终为空的 video.buffered 属性问题。(118550061)
  • 修复了 WebVTT 正确解析区域 id 设置的问题。(118551267)
  • 修复了在未给出帧率/比特率的情况下,VideoEncoder 在 latencyMode 为“realtime”时不会产生帧的问题。(118725549)
  • 修复了在“显示媒体统计”中未显示 MP4 中的 AV1 编解码器字符串的问题。(118850797)
  • 修复了 getDisplayMedia frameRate 始终为 30,无论约束条件如何。(118874132)
  • 修复了从画中画返回全屏后,后续触摸输入中断的问题。(119832557)
  • 修复了在存在多个文本轨道时的 HLS 视频字幕问题。(119839950)
  • 修复了当 Safari 窗口处于全屏应用模式时,全屏视频无法缩放到显示尺寸的问题。(119893556)
  • 修复了处理密钥续订请求导致某些 DRM 内容播放错误的问题。(120230860)
  • 修复了由于媒体能力授予和激活顺序导致摄像头和麦克风激活失败的问题。(120510826)
  • 修复了播放过程中即时字幕移动的问题。(120847946)
  • 修复了全屏覆盖控件出现或消失时视频上下移动的问题。(120848395)
  • 修复了在 visionOS 版 Safari 中调整音量时音量滑块闪烁的问题。(120855936)
  • 修复了在 CDM 附加到 SourceBuffer 后,被阻塞的加密样本未入队的问题。(120879185)
  • 修复了 visionOS 版 Safari 中 Twitter.com 视频播放问题。(121391975)
  • 修复了 [Netflix.com 内容在全屏模式下可能被放大和裁剪的问题。(121822831)
  • 修复了伪元素字体大小计算,以修复全屏模式下的字幕大小。(122584350)

渲染

  • 修复了传统蒙古文脚本字符方向不正确的问题。(93426525)
  • 修复了 writing-mode: vertical-rldirection: rtl 时的调整大小行为。(102620110)
  • 修复了根元素背景图像的透明度和渲染问题。(115396444)
  • 修复了阴影颜色以保留其 alpha 通道的问题。(115812347)
  • 修复了如果使用 GraphicsStyles,带有外置的滤镜会重新绘制整个滤镜区域的问题。(115817290)
  • 修复了合成滤镜样式透明层时不裁剪目标上下文的问题。(115901634)
  • 修复了从 getComputedStyle 返回的变换不正确的问题。(117523629)
  • 修复了后端不支持颜色空间的图像的处理,以回退到 sRGB 渲染。(118238178)
  • 修复了复选框和单选按钮避免浮动的问题。(118660695)
  • 修复了在带有 overflow: hidden 的转换父 <div> 内的 <div> 渲染问题。(118901069)
  • 修复了编辑文本时的渲染问题。(119833765)
  • 修复了包裹块的内联框的 offsetHeightoffsetWidth 为 0 的问题。(119955792)
  • 修复了浮动元素导致列表项项目符号在受限行上孤立的问题。(120022893)
  • 修复了垂直书写模式下内联框(拥抱)轮廓绘制不正确的问题。(120217559)
  • 修复了在 vertical-rlvertical-lr 中,当 text-orientation 不为 upright 时,ch 单位值不正确的问题。(120293590)
  • 修复了滚动 Heroku 应用时出现的图形伪影。(120373474)
  • 修复了 overflow: hidden 不阻止 CSS Subgrid 应用的问题。(120848131)
  • 修复了下划线文本装饰的重新绘制区域问题。(121082290)
  • 修复了滚动容器上的 align-contentjustify-content 导致溢出内容无法访问的问题。(121366949)
  • 修复了浮动元素和带 clear 的流外 <br> 元素的渲染问题。(121444267)
  • 修复了在带有 white-space: nowrap 的容器中,两个内联元素之间间隙处的换行问题。(121859917)
  • 修复了报告负向 advance width 的自定义字体首字母裁剪问题。(121891210)
  • 移除了浮动的 margin-trim 行为,以匹配规范更改。(115794102)

Safari 扩展

  • 修复了如果 scripting.executeScript() 发生错误,则将错误返回给调用方的问题。(107996753)
  • 修复了调用 scripting.unregisterContentScripts() 后脚本可能未被移除的问题。(113171510)

滚动

  • 修复了从右到左、vertical-rl 或 Flexbox 反向模式元素不可用的水平滚动条。(104944522)
  • 修复了 scrollTo() 后跟一个动画滚动,最终滚动位置不正确的问题。(117608836)
  • 修复了 Shadow DOM 元素的滚轮溢出行为。(118496293)
  • 修复了键盘滚动超出页面后卡在错误滚动偏移量的问题。(120053910)

存储

  • 修复了网站数据意外被逐出的情况。(119818267)

SVG

  • 修复了仅通过 CSS 应用 rxry 无效的问题。(113500023)
  • 修复了负 SVGTransform 比例值字符串化不正确的问题。(118656892)
  • 修复了 SVG 位于 <iframe> 内部时的布局问题,而不会影响 <iframe> 的大小。(120178866)
  • 移除了对 SVGRenderingIntent 的支持。(102516681)

URL

  • 修复了 CSS 调用的 URL 解析始终使用 UTF-8,与 W3C CSS WG 达成一致。(114889625)

Web 动画

  • 修复了动画的样式失效问题。(118500247)
  • 修复了暂停的动画中,currentTime 更改为 0 后未在取消暂停时重新启动的问题。(118826588)

Web API

  • 修复了 iframe 内部 wheelgesturechange 事件的无效坐标。(105243167)
  • 修复了 HTMLAreaElement 与 HTML 标准对齐的问题。(110028213)
  • 修复了某些范围的 Range.getClientRects()Range.getBoundingRect() 的结果。(112543805)
  • 修复了在动态样式表加载后且用户已滚动的情况下,滚动到文本片段不会滚动的问题。(112608578)
  • 修复了 SharedWorker 引用策略在未提供脚本 http 响应时默认为其上下文引用策略的问题。(114625126)
  • 修复了 Requestreferrer 功能和 Response.redirect() 的 URL 编码问题。它们现在始终使用 UTF-8。(115219660)
  • 修复了 <meta name="color-scheme"> 在其 namecontent 属性更改时重新处理的问题。(115958450)
  • 修复了 FetchResponse.formData() 将头名称解析为不区分大小写的问题。(116742000)
  • 修复了声明式 Shadow Tree 以匹配最新规范的问题。(117655691)
  • 修复了重复调用 scrollIntoView({ block: 'center' }) 导致的抖动问题。(117755250)
  • 修复了全屏警告横幅以防止截断长域名的问题。(118078137)
  • 修复了更新 resizeByresizeTo 使用 int 而非 float 以与规范对齐的问题。(118872048)
  • 修复了当 Cookie Store API 被禁用时 CookieChangeEvent 未暴露的问题。(118902989)
  • 修复了 Element.prototype.setAttributeNode() 不区分属性名称大小写的问题。(119013600)
  • 修复了切换 spellcheck 属性未切换输入元素上的拼写标记的问题。(119269616)
  • 修复了 Custom Highlights API 中移除高亮显示的问题。(119531671)
  • 修复了 getElementsByName() 仅返回 HTML 元素,而不返回 SVG、MathML 或其他类型元素的问题。(120275680)
  • 修复了 pointerup 事件的 button 值与 pointerdown 事件不匹配的问题。(120429508)
  • 修复了在 document.open 后重新插入的元素上触发滚轮事件的问题。(120893136)
  • 修复了滚动到文本片段文本指令在节点数据中查找带有额外未渲染空白的文本的问题。(120913588)
  • 修复了更改 HTMLCanvasElement 宽度或高度导致中间缓冲区分配的问题。(122309325)
  • 修复了 canvas captureStream 在 WebGL 下出现卡顿的问题。(122471664)

Web Inspector

  • 修复了模拟器中的主屏幕 Web 应用在“开发”菜单的设备子菜单中列于“主屏幕 Web 应用”部分下。(117742935)
  • 修复了 tan() 函数不会触发颜色选择器的问题。(118724061)

WebGL

  • 修复了 Canvas WebGL 上下文捕获到 WebCodecsVideoFrame 未捕获所有帧的问题。(108459224)
  • 已修复:改进了 MSAA 渲染性能,包括抗锯齿默认帧缓冲区和修复了 PVRTC1 纹理的 PBO 上传。(117461678)
  • 修复了 WebGL OffscreenCanvas 在请求 WebGL2 时返回之前创建的 WebGL1 上下文的问题。(119028794)
  • 修复了 WebGL 在嵌套 worker 中可用。(120279728)

WebKit

  • 修复了模拟器中未显示 HTML 内容的问题,影响使用 Web 扩展项目模板的项目。(121338366)

WebRTC

  • 修复了使用 {"width":1920,"height":1080,"frameRate":24} 获取的媒体轨道问题。(61747755)
  • 修复了在 WebRTC 维持帧率 degradationPreference 的情况下触发分辨率缩放的问题。(121041723)
  • 修复了一个 Bug,该 Bug 导致 HTML canvas 元素在初始化时并非总是被标记为脏。这可能导致某些视频效果动画出现卡顿。(121257960)

更新到 Safari 17.4

Safari 17.4 可在 iOS 17.4iPadOS 17.4macOS Sonoma 14.4、macOS Ventura、macOS Monterey 和 visionOS 1.1 上使用。

如果您正在运行 macOS Ventura 或 macOS Monterey,您可以单独更新 Safari,而无需更新 macOS。在 macOS Ventura 上,前往 > 系统设置 > 通用 > 软件更新,然后点击“可用更新”下的“更多信息…”。

要在 iPhone、iPad 或 Apple Vision Pro 上获取最新版本的 Safari,请前往“设置”>“通用”>“软件更新”,然后轻点以更新。

反馈

我们很高兴听到您的声音。要分享您对 Safari 17.4 的看法,请在 Mastodon 上找到我们:@jensimmons@front-end.social@jondavis@mastodon.social。或者在 X 上发送回复给 @webkit。您也可以在 LinkedIn 上关注 WebKit。如果您遇到任何问题,我们欢迎您对 Safari UI 提出反馈,或提交关于 Web 技术或 Web Inspector 的 WebKit Bug 报告。提交问题确实有所帮助。

在 macOS 上下载最新的Safari 技术预览版,以保持在 Web 平台的最前沿并使用最新的 Web Inspector 功能。

您还可以在Safari 17.4 发布说明中找到此信息。