View in English

  • 打开菜单 关闭菜单
  • Apple Developer
搜索
关闭搜索
  • Apple Developer
  • 新闻
  • 探索
  • 设计
  • 开发
  • 分发
  • 支持
  • 账户
在“”范围内搜索。

快捷链接

5 快捷链接

视频

打开菜单 关闭菜单
  • 专题
  • 相关主题
  • 所有视频
  • 关于

返回 WWDC25

  • 简介
  • 概要
  • 转写文稿
  • 代码
  • Safari 浏览器和 WebKit 的新功能

    了解 Safari 浏览器和 WebKit 中最新的网页技术如何助你打造妙不可言的体验。我们将重点介绍不同的 CSS 功能及其工作原理,包括滚动驱动动画、跨文档视图转换和锚点定位。我们还将探讨针对音频、视频、图像以及图标的新增媒体支持。

    章节

    • 0:00 - 简介
    • 1:46 - 动画
    • 19:01 - 布局
    • 29:05 - 视觉效果
    • 38:22 - 媒体

    资源

    • Can I use
    • Safari Technology Preview
    • Submit feedback
    • Web Speech API - Web APIs | MDN
    • WebKit Open Source Project
    • WebKit.org – Bug tracking for WebKit open source project
      • 高清视频
      • 标清视频

    相关视频

    WWDC25

    • 了解适用于 SwiftUI 的 WebKit
    • 使用 WebGPU 解锁 GPU 计算能力
    • 在网页上验证身份证件
    • 空间网页的新功能
    • 进一步了解声明式网页推送
  • 搜索此视频…

    大家好 我叫 Saron Yitbarek 在 Safari 浏览器和 WebKit 团队 担任网页技术布道师 自去年 WWDC 以来 我们一直致力于 为大家带来新的网页技术 其中既有大家期待的功能 也有令人惊喜的创新 我们始终关注开发者 与网页生态的发展 希望赋能各位网页设计师与开发者 让创意落地 变得更加简单 我们的目标很简单: 帮助你为用户打造 可靠、兼容且以隐私 为先的使用体验 因此今天我想宣布 今年秋季将随 Safari 浏览器 推出的全新网页技术 这个版本中包含 诸多出色功能 我们投入大量时间与精力 来提升互操作性 并填补了最新功能中的空白场景 在本次讲座中 我将介绍 几个我最喜欢的功能 并展示我们在哪些领域 填充了这些技术空白 这些新功能分为四类 在动画方面 我将演示 如何使用滚动驱动型动画 和跨文档视图过渡 布局部分聚焦于 强大的锚点定位功能 视觉效果方面 我们将介绍 background-clip、新的 shape 函数 以及 text-wrap: pretty 在 CSS 相关内容之后 我将 介绍媒体技术 包括 SVG 图标支持 图像处理 以及 对现有媒体格式的改进 让我们先从动画开始 动画能够提升 你打造的在线体验 让页面更具 趣味性与灵动性 我将通过一个例子 来为大家说明 假设我正在为我的在线 教育公司 A-School of Code 重新设计网站 我希望网站兼具 实用性与趣味性 借助最新功能 仅使用 CSS 就能实现这一目标 这是最终网站的效果演示 这是一个网校的网站 承诺教授技术技能 我用精美的网格展示了 我们涵盖的课程主题 大家可以看到聘用过 我们优秀学生的公司名单 阅读往期学员 对课程与体系的好评 最后还提供了 两种课程方案 供用户进一步了解 有几个设计亮点 让这个网站脱颖而出 其中最引人注目的 可能是动画效果 这要归功于 Safari 浏览器 19 新增的滚动驱动型动画功能 自 2007 年 Apple 在 WebKit 中 首次引入 CSS 动画以来 它就成为了网页的一部分 但此前若想将动画与用户行为关联 始终需要借助 JavaScript JavaScript 是强大的网页语言 但只要能避免使用它 用户就能获得更好的 性能与电池续航 滚动驱动型动画 让开发者无需 JavaScript 仅用 CSS 就能将动画 与滚动行为关联 让我们来详细了解它的运作方式 要理解滚动驱动型动画 首先需要掌握 一个关键概念:时间线 网页的默认时间线 是基于时间的 这意味着动画 会随时间推移播放

    随着时间流逝 进度条动画会同步推进 而滚动驱动型动画 引入了两种新的时间线 第一种是滚动时间线 现在我的网站中 使用 scroll() 时间线 在页面底部 创建了进度条 这是一个简化示例 实际上 你可能 不需要这样的进度条 因为页面本身已有滚动条 但这个进度条能直观展示 滚动驱动型动画的运作方式 我们来看看它的实现方式 在开始制作进度条之前 有个重要因素需要考虑 辅助功能 滚动驱动型动画 为网站引入了动态效果 部分用户可能偏好 较少的动态效果 用户可以在辅助功能 设置中减少动态效果 我希望尊重这一选择 避免意外引发运动不适 运动不适很常见 由多种因素引发 包括体验、遗传、疲劳 甚至前庭功能障碍等 症状可能包括恶心、 头晕、头痛等身体不适

    作为开发者 我们为网站和网页 App 添加的动态效果 可能会无意 触发运动不适: 大型对象缩放、镜头推拉、 视差效果等变速运动 三维效果模拟技术 或边缘动态效果 比如在用户的预期 焦点区域之外持续移动 这个列表并未涵盖所有情况 但足以作为思考的起点 你的网站有这些效果吗? 我的动画是一个 简单的进度条 这种动态效果在网页上 常见且安全 影响范围小 因此我认为 这个特定动画 不会引发运动不适 但每当为页面添加动态效果时 我们都应该停下来思考 它会如何影响 不同用户的需求 下面让我们来实现滚动条 我会先从 CSS 代码入手 我打算在页脚中添加 一个伪元素作为滚动条 我会为它添加样式 让它从页面左下角开始 并在滚动时停留在底部

    接下来 我将使用 我们熟悉的 CSS 语法 通过关键帧创建动画 这段代码告诉浏览器缩放 我的进度条 使它在 X 轴上增长 从而创建一个从左向右 增长的进度条效果 到目前为止 我已经为 滚动驱动型动画奠定了基础 但还需要完成最后一步 将动画添加到进度条上 我可以在这里完成 现在到了滚动部分 我希望进度条仅在滚动时 才开始从左向右增长 为此我需要为进度条指定 一个新的动画时间线 我会在 CSS 中添加 animation-timeline:scroll(); 替换默认的时间线 现在请记住 为了使这个生效 animation-timeline 必须 放在 animation 属性之后 就这样 我将动画 与滚动时间线连接起来 只用几行 CSS 代码 就创建了一个进度条 无需 JavaScript 让我们看一个更实际的例子 我希望动画 不仅基于滚动 还基于元素何时 出现在页面上 来看这个例子 我看到方块旋转 形成一个网格 这在我滚动时发生 但还有另一个因素在起作用 动画只在蓝色框内发生 它从底部开始 只有当方块进入视口时 并且方块在屏幕中间 (蓝色框顶部) 停止旋转 考虑视口因素需要 一种不同的时间线 视图时间线 让我们通过代码来 看看它是如何工作的

    我从 html 代码开始 这里 我有一个主题列表 其中包含 一些我将在 CSS 中使用的类 接下来 我将添加一些基本的 CSS 样式 将列表变成黄色框 与我的网站主题相匹配 现在基础已经就绪 我可以开始实现滚动驱动型动画了 第一步是确定我想 将什么动画附加到滚动上 在我的网站上 我有 三个动画同时发生 我需要将这些动画 应用到每个方块上 第一个动画使方块 从左侧飞入 第二个动画使方框 从中心飞入 第三个动画使方块 从右侧飞入

    到目前为止 代码中并没有什么新东西 我仍然在使用经典的 CSS 动画语法

    接下来我要引入 滚动驱动型动画的 滚动驱动部分 但首先 我要暂停一下 思考这个动画的可访问性 回想一下常见的触发因素 旋转就是其中之一 但这更多是指 可能导致定向障碍的 环境效果 因为这只是几个元素 而且动画相对较小 我认为这个动画 不存在无障碍访问风险 所以我可以继续编写代码 接下来 我要将动画代码 添加到我的 CSS 中 将左侧动画 应用到左侧框 将中心动画应用到中间框 并将右侧动画应用到右侧框 因为我希望元素动画前后 保留它们的动画样式 我还将添加 animation-fill-mode: both 现在 我终于要实现 代码的滚动驱动部分了 我需要两行代码 才能实现这一功能 第一行是我的新视图时间线 我将在这里添加它 第二行代码是 所谓的动画范围 动画范围会告诉 浏览器基于时间线 在什么位置 开始和结束动画 我选择了视图时间线 因此范围将反映元素 在视口中的位置 默认值范围为 0% 到 100% 这表示动画 在 0% 时开始 即元素首次进入 视口的时刻 并在 100% 时结束 即元素完全离开 视口的时刻 我们来看看使用这些 默认值时动画的效果 这已经很接近我想要的效果了 但还不完全对 使用滚动驱动型动画时 尤其是在这样一个 展示信息的网站上 用户体验是需要重点考虑的 动画很有趣 能让 我的网站脱颖而出 但信息必须保持可读 动画不应妨碍功能使用 在这种情况下 这意味着 要注意动画持续的时间 我不希望它持续整个 100% 的范围 因为这意味着方块 会一直处于运动状态 导致难以阅读

    相反我想要一个 短暂的动画 能吸引眼球 然后让方块定位到 合适位置 以便用户阅读 尝试将动画在页面中途结束 听起来是个不错的选择 这应该既能 带来趣味性 又能给用户 足够的时间阅读内容 所以我要将范围 更改为 0% 到 50% 这意味着 当元素位于页面中途时 动画将结束 限制了它们运动的时间 如果我向上滚动 动画会反向播放 方框会在 50% 处 开始散开 并在 0% 处完全消失 通过范围还能控制更多内容 比如 0% 的确切位置 若想了解有哪些选项 及它们的运作方式 请查看不同的值 多尝试和探索 这些新时间线功能强大 与动画相结合后 能为用户打造出色的体验 这就是 WebKit 为 Safari 浏览器 提供的滚动驱动型动画 我很想展示的下一个动画 会覆盖整个页面 它们是跨文档视图过渡去年 12 月在 Safari 浏览器 18.2 中推出 它们是视图过渡的扩展 在更早的 Safari 浏览器 18.0 中推出 借助跨文档视图过渡 可以在页面之间 打造平滑过渡 从这样的效果

    变为更加无缝的效果 比如这种淡入淡出 而无需 JavaScript 实现这种效果 只需一行 CSS 当用户点按没有 过渡效果的导航项时 浏览器会重新绘制页面 擦除当前页面并加载新页面 过渡效果的美妙之处在于 由于它会在页面更改前后 拍摄快照 并在它们之间创建过渡 因此能带来流畅的体验 我很喜欢这个效果 下面介绍它的运作方式 在 CSS 文件中 只需添加 @view-transition at-rule 并将 navigation 属性设置为 auto 就这样! 但在发布前 我们还需要做一件事 由于这为页面添加了动态效果 我们需要暂停并思考 是否存在任何 无障碍访问问题 虽然淡入淡出是一种动画 但它们非常微妙 实际上被认为是 对需要减少动态效果的用户 更安全的动画之一 所以我可以放心发布 现在 假设我不想使用默认的 淡入淡出效果 而是想使用滑动效果 当点按导航中的项目时 我希望当前页面滑出 新页面滑入 我将展示一下具体效果 但需要提醒的是 如果你对运动敏感 这可能会让你感到不适 结束时我会告知你

    在这里 我要创建一个滑动效果 我喜欢这个效果 它比淡入淡出效果更进了一步 但首先 让我们暂停一下 想一想它对用户的影响 动画已经结束

    这种滑动效果 是否属于 可能触发运动 不适的动画类型? 就动画而言 它是一个较大的动画 它不仅仅是移动 一个单词或一个元素 而是移动整整两页内容 由于我不确定 这个动画是否安全 并且因为它只是一种增强功能 而并不是用户体验的核心 最好将它放在 减少动态效果的媒体查询中 现在就来实现这一点

    这是我的媒体查询 它告诉浏览器只有在用户 不偏好减少动态效果时 才运行我的滑动过渡效果 现在我需要编写滑动效果的代码 这里我将使用 CSS 动画 来创建关键帧 通过关键帧定义 这两个页面的动画行为 让当前页面滑出 新页面滑入

    接下来 要使用这些动画 需要指定目标元素 默认情况下 navigation: auto 会过渡页面中的所有元素 但我不希望 整个页面都参与过渡 导航栏需要保持固定 仔细想想 页脚也需要保持不动 因此我会给需要 过渡的内容添加 ID 在每个页面上都设置一个 命名为“school-info”

    现在需要声明一个 后续使用的 view-transition-name 实现视图过渡时 还会用到一组伪元素 我将使用其中两个

    view-transition-old 和 view-transition-new view-transition-old 代表 过渡前的页面快照 view-transition-new 代表 过渡后的页面快照 但使用它们时 需要传入参数 这里我将使用“main-body” 作为 view-transition-name 并将它传入两个伪元素 因为这是我希望 过渡的页面部分 然后将 animation-name 设置为关键帧的名称 这样就可以了 让我们看看效果 如果你对运动敏感 建议暂时移开视线

    很棒 点按时 导航栏保持不动 页面其他部分完成过渡

    动画结束 我非常喜欢跨文档 视图过渡的一点是 它们是增强功能 它们并不是必需的 也不会改变网站功能 如果浏览器支持且用户需要 那么这是一个不错的补充 如果不支持或用户不需要 也完全不影响使用 在 App 或网站中实现 跨文档视图过渡时 请记住要注意过渡的页面 需要来自同一来源 例如从 example.com 跳转到 example.com/cohorts 是可行的 但从 example.com 跳转到不同子域则不行 这有助于确保 用户的安全和隐私 避免恶意页面 通过动画操纵你的网站 接下来看看布局方面的 新功能 包括锚点定位、 这是今年秋季将随 Safari 浏览器推出的新功能 锚点定位 尤其是 基于现有 popover API 构建时 是一个 CSS 模块 能让创建工具提示 和精确定位菜单 变得前所未有的简单 并且能对视口变化 做出适当响应 我们来一探究竟 我希望为用户提供 流畅的导航体验 用户登录后 导航栏会显示头像 点按头像时 应该出现一个菜单 这是网页 App 中常见的功能 我将从 html 代码开始构建

    先看导航栏 和头像的 html 结构 以及点按头像后 要显示的菜单 html 添加样式后 先看看初步效果 让我们把页面的 其余部分放在一边 现在 我们已经实现了 一个美观的导航栏和菜单样式 但菜单不能始终显示 而是需要在点按头像时弹出 再次点按时消失 并且弹出位置 不能在左上角 而要锚定在头像下方 为解决这个问题 在使用锚点定位前 需要先使用 popover API 首先在头像菜单元素上 添加 popover 属性 并为 popover 设置 ID 接下来我需要用按钮包裹头像 作为可点按的触发元素 在这个过程中 我需要确保 这个按钮及它的菜单 对使用辅助技术的用户是可访问的 因此我会添加 aria-haspopup 属性来告知屏幕朗读器 点按这个按钮后 将向用户显示菜单 最后我还需要添加 popovertarget 属性 并将它的值设置为 与 popover 元素 ID 相同 太棒了! 现在点按头像时 弹出菜单会出现 点按其他区域时则会消失 但目前菜单显示在 页面的左上角 而我希望它锚定在 头像下方并对齐 这时就需要 引入锚点定位

    锚点定位允许将一个元素 锚定到另一个元素 并基于锚点位置 对元素进行定位 下面介绍它的运作方式 首先确定锚点 并通过 anchor-name 属性为它命名 在本例中锚点 是头像按钮 这意味着需要基于 按钮位置来定位菜单 所以我将锚点 命名为“profile-button” anchor-name 是用户 定义的任意字符串 但必须以两个短横线开头 现在需要转到菜单并 将菜单与刚命名的锚点关联 在锚点定位中 菜单称为目标元素 需要为目标元素 提供一些信息 首先通过设置 position-anchor 属性 将它与锚点 “—profile-button”关联 即在这里写入“—profile-button” 最后 需要告知 菜单的定位方式 这里有两种实现方式 第一种是定位区域 下面我们来探讨一下这是什么

    锚点位于一个 3×3 的网格中央 网格分为 左、中、右三列 以及上、中、下三行 如果想将目标元素 放在锚点右上角 可将 position-area 设为“top right” 这让我能直观地描述 菜单相对于锚点的位置 如果想让菜单 位于头像下方 即网格的底部中央 则设置为 bottom center

    效果如下 虽已接近预期 但仍不完全符合需求 菜单确实位于底部 但由于菜单宽度 大于头像按钮 导致超出网格范围 实际需要的是 将菜单左侧 与头像左侧对齐 因此需要为 position-area 设置不同值 bottom span-right 这会使菜单 从网格中央开始 向右延伸

    如此一来 菜单与头像就完美对齐了 在当前屏幕尺寸下效果很好 但在不同设备或 更窄的视口下会如何呢? 为验证这一点 可在 Safari 浏览器中启用响应式设计模式 通过依次前往 “设置”和“高级” 选中“显示网页 开发者功能”即可启用

    这时会出现“开发”选项 其中包含 开发者期待的功能: 视口预设 现在可以从多种精心挑选的 视口尺寸中进行选择 从而加快测试和开发速度 我喜欢只需切换 即可旋转视口预设 点按一下即可轻松测试 纵向和横向模式 我希望菜单能够 响应视口宽度变化 而无需 JavaScript 当前菜单向左对齐 当宽度变窄时 希望它移至 头像按钮右侧对齐 锚点定位的 神奇之处在于 它专为轻松处理 这类情况而设计 这个属性名为“position try” 功能正如其名 当第一个位置空间不足时 允许设置备选位置 由于我希望菜单 从向右延伸 变为向左延伸 可将 position-try 设为“bottom span-left” 但 position-try 还支持 其他类型的值 除了显式指定菜单位置 还可以设置 相对于 position-area 的值 其中一个值是“flip-inline” flip-inline 的意思是 无论元素原本在什么位置 都沿着内联方向进行翻转 同理 flip-block 用于块级方向翻转 这是一种更直观的描述方式 我们来看看它的实际效果 在 13 英寸 iPad 的 响应式模式下 菜单向左对齐 但切换屏幕方向时 position-try 立即生效 菜单自动向右对齐 这正是我想要的 响应式菜单效果

    值得自豪的是 WebKit 团队提出了 position-area 并与标准机构合作 为锚点定位提供了 直观的解决方案 此外还有另一种锚点定位方式 即 anchor() 函数 这是一个强大的工具 使用 anchor() 函数时 无需将元素置于网格中 而是将元素边缘 与锚点边缘对齐 首先 需要确保 将 position 设为 absolute 然后设置菜单顶部位置 将它与锚点底部对齐 所以我将它设为 anchor(bottom) 接着我将设置 菜单左侧位置 我将这个值设为 anchor(left) 使它与锚点左侧对齐

    这是一个非常简单的例子 但是如果我想像这样将菜单 与头像对齐 该怎么办? 我需要考虑这个内边距 我可以使用 position-area 并添加 margin-left 或者我可以使用 anchor 函数 并添加 calc() 函数 就像这样 在这里 我将 anchor 函数与 calc 函数和 em 单位结合起来 这将使我的菜单滑动过去 在大多数用例中 position-area 是一个很棒的 直观定位方法 当你做更复杂的事情时 比如从一个位置 到另一个位置的动画 或者使用多个锚点 使用 anchor() 函数 不管你选择哪一个 锚点定位使你可以 仅使用 CSS 来轻松地 创建响应式的相对定位 最后 对于 CSS 功能 我们将探索一些打造 出色视觉效果的新方法 第一个是将边框 提升到新的水平 大约 15 年前 Apple 推出了 background-clip: text 这样你就可以获取文本 而不是用颜色填充它 你可以使用渐变 或背景图像填充它 比如我标志中这个 从黄色到橙色的渐变 我的标志非常简单 它只是基本字体的文字 因此我不使用图像 我只打算使用文本 这样我就可以用 CSS 来设计它的样式 我的标志是一个 h1 元素 我将 h1 的样式设为白色 所以我从白色文本开始 为了给我的文本添加这个渐变效果 我首先将背景图像设置为 从黄色到橙色的微秒渐变 一直延伸到右下角 我的文本后面就有了这个渐变 接下来是 background-clip 属性 我要将它设置为 text 这让我… 回到了白色文本 嗯 不是我想要的 我还需要做一件事 我需要覆盖 h1 的样式 使标志的颜色透明 这样它就可以让开 当我这样做时 我的渐变就会显现出来 但不仅仅是渐变可用于文本 你也可以使用图像 就像这张秋叶的背景图片 background-clip: text 为文本 引入了新的视觉功能 而现在 我们要 对边框做同样的事情 我来展示一下它是如何工作的 我的按钮设计有 白色粗边框 但对于主按钮 我想做些不同的设计 我想使用新的 background-clip 值 给它增加一些亮度 并为边框添加渐变效果 我会先添加之前用过的 从黄色到橙色的微秒渐变 作为背景图像 这样 按钮背景就会呈现渐变效果 接下来添加新的 background-clip 并设为 border-area 结果背景变回黑色 边框仍是白色 这和文本遇到的问题一样 边框颜色确实改变了 但被按钮样式的 白色边框遮挡了 我需要将边框颜色设为透明 以便渐变效果显现出来 我会在这里添加它 看看效果怎么样… 很有趣 渐变出现了 但新问题来了 渐变似乎在重复 它占据了按钮宽度 但只延伸到 边框内侧 然后在边缘重新开始渐变 要解决这个问题 需要将背景 延伸到边框最外侧 这可以通过将 background-origin 设为 border-box 来实现 看起来很不错

    你也可以使用 不需要声明 背景图像的简写方式 这就是利用新 background-clip 值 border-area 实现的渐变效果 仅用边框就能 做很多事情 通过选择图像和 令人兴奋的渐变效果 你可以制作进度圆环、 警告标志 甚至带双重边框的 精美照片 这就是 background-clip: border-area 它提供了更多选项 来帮助美化内容 让你的网站和 网页 App 脱颖而出 如需查看这些示例的演示 以及 background-clip 的更多详情 请查看 webkit.org 上的博客文章 视觉效果的改进 不仅限于边框 还包括 CSS 中 用途广泛的形状创建 接下来 我很高兴地 介绍 shape() 函数 它现在已在 Safari 浏览器 18.4 中得到支持 在 App 和网站中 形状有多种使用方式 我在 A School of Code 网站就运用了这个特性 在用户评价部分 我为所有评价 添加了这些曲线箭头 作为背景装饰 这些 CSS 形状通过 clip-path 设置 成为页面的有趣美观元素 在 shape() 函数出现之前 我使用 path 实现这一效果 path 函数功能 强大且灵活 允许通过各种点和曲线 来绘制各种形状 但当视口宽度变化时 形状会发生什么? 为说明这一点 我隔离了这三个箭头 并展示它们的响应情况 调整大小时 箭头尖端 和曲线都被截断了 它们不会随视口调整大小 而我需要更具响应性的效果 但问题在于 我不希望 形状的每条线和曲线 都随视口变化 只希望部分元素变化 我希望曲线保持形状 箭头尖端保持角度 但长度和高度 随视口进行缩放 使用 shape() 函数后 当演示窗口变小时 形状宽度也相应地缩小 而这是我想要的 但你会注意到尖端角度 和曲线形状始终保持不变 即使视口变窄 也维持原有形状 这正是 shape() 函数的优势 它提供了这种 精细的控制能力 允许选择哪些部分保持静态 哪些响应发生变化 我来给你演示 一下代码实现 你会注意到 代码中使用了 容器查询高度 和百分比等不同单位 这是因为 shape() 函数可以 接受所有 CSS 单位类型 我甚至用到了 calc 函数 通过创建响应式值 并使用多种单位 可以有选择地 控制形状的不同部分 实现所需的响应式效果 有了 shape() 函数的支持 我们可以创建灵活、 响应更灵敏的形状 而我们的改进不止于形状 我们在文本方面 也有重大改进 全新排版功能 例如 Safari 浏览器 19 中支持的 text-wrap: pretty

    细看这段文本 虽然还可以但有几个地方 让它有点难读 看起来也不太舒服 第一是那些短行 段落末尾只有一个词 这在视觉上 会分散注意力 让段落之间的空间 看起来比实际更大

    第二是连字符 连字符本身 没有什么问题 但我们希望谨慎地使用它 我们不希望连续 三个句子都有连字符 第三是我们所说的 rag 也就是段落各行 所形成的整体形状 好的 rag 由长度 大致相同的行组成 像这样的坏 rag 是参差不齐的 在视觉上很突出

    text-wrap: pretty 的效果是微妙的 但也是有意为之的

    在这里 它消除了单字词行 连字符和

    坏的 rag

    下面介绍它的运作方式 未使用 text-wrap: pretty 时 浏览器的行为是 尽可能占满 每一行的全部空间 但是当你添加 text-wrap: pretty 时 你是在告诉浏览器 以不同的区域为目标 靠近那条绿线 那是我们的目标 我们理想的行长度 但我们有一些回旋余地 由我的紫线和 红线之间的区域表示 那里的任何东西都是公平的 它还会在单词周围移动 以确保 最后一行不会特别短 并尽量不使用连字符 而是选择将单词 移到下一行 代码很简单 将 text-wrap pretty 应用到 你想要的任何元素上: 段落、标题等等 尤其是当你看到 一些短的最后一行 大量的连字符或一些坏的 rag 看看它对你的文本有什么影响 text-wrap pretty 的优势在于 它也是一种增强功能 将它添加到文本中 如果浏览器支持它 它会让你的文本更令人愉悦 如果用户的浏览器 不支持它 或者它决定 只调整最后几行而 不调整其他行 用户仍然有良好的体验 没有伤害 没有犯规

    我们讨论了相当多的 CSS 功能 主要是关于样式的 现在 让我们看看媒体方面 我要与你分享的 第一个媒体很小 但功能很强大 我们已经听到了你的反馈 我们很高兴为你带来 今年秋季将在 Safari 浏览器中推出的 SVG 图标 SVG 图标不仅仅是 作为收藏图标 它们可以在书签、Safari 浏览器 起始页的任何地方、 当用户添加到 程序坞时等等地方看到 对于现代浏览器 使用 SVG 作为 收藏图标可让 Safari 浏览器生成 最适合这个图标上下文的图标 文件大小通常也小于 收藏图标中常用的 png 还有另一种我很高兴 要宣布的静态媒体类型 今天登陆 WebKit 和 Safari 浏览器的是 HDR 图像 高动态范围 (HDR) 使 你的媒体比我们在网页上 习惯看到的典型 SDR 照片 和视频更丰富、更生动 自从 Safari 浏览器 14.0 以来 我们已经支持 HDR 视频五年了 现在我们增加了 对图像的支持 为了说明 HDR 和 SDR 之间的区别 让我来展示一下两者的模拟 我左边的图像是 标准动态范围 (SDR) 图像 它可以有许多 不同的文件格式 我无法通过这个视频 向你展示 HDR 的样子 所以我在右边创建了 这张图像来模拟一些差异 你会注意到模拟的 HDR 有更深的色调、更广的范围和 更明亮的颜色 在真正的 HDR 图像上 看到这些差异令人惊叹 造成这些差异 有几个技术原因 其中之一是每张图像 所包含的数据量 SDR 是 8 位 而 HDR 是 10 到 16 位 这些额外的位给了 HDR 更多的图像数据来显示 SDR 通常也存在于 sRGB 色彩空间中 而 HDR 使用更广泛和 更丰富的色彩空间 比如 P3 文件格式也不同 SDR 可用于包括 JPEG 在内的多种格式 而 HDR 除了这些格式 还支持 HEIC 和 AVIF 但在现实中显示 HDR 需要一些思考和意图 毕竟 在未来一段时间内 网上的大多数媒体可能不会是 HDR 所以我们需要考虑如何 并排显示 HDR 和 SDR 图像 以及那会是什么样子 由于动态范围的原因 HDR 图像往往比对应的 SDR 图像 看起来亮得多 你看那只蓝鸟是如何突出的? 在搜索结果图像 或图库的背景下 这可能会让用户分心 并造成糟糕的体验 作为开发者 我们希望你能更好地控制 如何管理这种差异 为此我们推出了一个 CSS 属性 称为 dynamic-range-limit dynamic-range-limit 的 默认值为 no-limit 它能让 HDR 图像 和视频保持原样 即使它们比其他图像 亮得多也是如此 或者你可以使用 CSS dynamic-range-limit: standard 告诉浏览器将任何 HDR 图像或视频 渲染成 SDR 的样子 第三个选项是 dynamic-range-limit: constrained 它要求浏览器使用 HDR 图像的额外动态范围 使它看起来很棒 但这样做的方式 是不让它突出 这使得 SDR 和 HDR 内容 混合在一起看起来更舒适 Safari 浏览器 19 的第一个 Beta 版尚不支持 constrained 值 但请继续关注 如果你使用 HDR 图像 而浏览器不支持它 没关系 浏览器会简单地 将 HDR 内容映射到 SDR 范围 因此不需要回退 你可以使用可用的最佳图像 浏览器会处理其余的工作 这意味着现在你可以 将更多动态的照片和视频 带入你的网站和网页 App 为你的用户打造更丰富、 更美丽的视觉效果 其他类型的媒体 比如音频和视频 有助于使你的网站 和网页 App 变得生动 我们在支持更多 媒体格式方面也取得了进展 在过去的几年里 我们已经填补了很多空白 以更全面地支持 广泛的编解码器和容器 我们率先在网页上支持 JPEG XL 和 HEIC 在 Safari 浏览器 19 中 我们在支持的媒体列表中 添加了 Ogg Opus 和 Ogg Vorbis 通过支持 15 种格式 我们为你在网站或 网页 App 中可以放置的 内容提供了更多选择 我们的部分工作是确保 各种编解码器与容器的 复杂组合可在网页 API 上工作 在 Safari 浏览器 18.4 中 我们通过提供 对 MediaRecorder API 中 WebM 的支持来缩小差距 这个用于录制媒体的 API 允许你将实时播客 和视频录制等功能 集成到你的网页 App 中 现在这样的 App 可以 在 Safari 浏览器和 WKWebView 中 使用 Opus 音频编解码器和 VP8 或 VP9 视频编解码器创建 WebM 文件 我们还致力于为空间网页 带来更多的媒体支持 我们增加了以立体方式 渲染 3D 模型的支持 与其他网页内容内联 同时允许人们 与模型交互 你还可以在网页中 包含沉浸式视频 Safari 浏览器能够理解 并正确渲染 无需任何额外的工具 要进一步了解 请观看 我们关于空间网页的讲座 我们将介绍嵌入 3D 模型、 向用户展示空间媒体 并预览一个新功能 这项功能将允许你 为你的网站 添加三维环境 这些是我们在过去一年中 所做的媒体支持工作的亮点 在本次讲座中 我们重点介绍了 CSS 和媒体 但还有更多讲座深入探讨了 我们推出的其他功能 我们有一个关于 WebGPU 的讲座 介绍了 WebGPU 的概念 概述了 Wig Sil 着色语言 并讨论了如何 获得最佳设备性能 我们还有一个关于 声明式网页推送的讲座 这将介绍如何在不需要 Service Worker 的情况下使用它 它如何更高效和更透明 以及你如何保持与 原始网页推送的向后兼容性 还有更多讲座待你探索 自去年秋季以来 Safari 浏览器的多个版本中 已经推出了许多新功能 其中包括一些 开发者最期待的功能… 帮助你完善排版并支持 世界上所有语言的 CSS… 以及帮助保护 用户隐私的功能 请查看 webkit.org 上的发布说明 你也可以通过 关于 Safari 浏览器新功能的 文章来及时了解最新的网页技术 你可以在 bugs.webkit.org (WebKit 的问题跟踪器) 上 提交关于网页技术的 错误报告和功能请求

    对于关于 Safari 浏览器界面或关于 iOS、iPadOS 和 macOS 的任何问题 请在 feedbackassistant.apple.com 上提交报告 确保你了解 Safari 浏览器 所支持功能的最新信息 Caniuse.com 是这方面 一个很好的资源 下载 Safari 浏览器技术预览版 以跟上未来发展的步伐 它大约每两周更新一次 因此它具有 WebKit 的最新新增功能 我们一直在努力 为你带来一系列功能 帮助你在网页上 打造非凡的体验 我们希望这些版本能让构建 变得比以往更容易、更令人兴奋 当你使用这些功能时 请告诉我们你的想法 祝大家编码愉快

    • 6:18 - Progress bar code scroll() example

      footer::after {
        content: "";
        height: 1em;
        width: 100%;
        background: var(--yellow);
        left: 0;
        bottom: 0;
        position: fixed;
        transform-origin: top left;
        animation: progress-scale linear;
        animation-timeline: scroll();
      }
      
      @keyframes progress-scale {
        from { transform: scaleX(0); }
        to { transform: scaleX(1); }
      }
    • 8:36 - html an css of text blocks showcasing different code topics

      <section class="topics">
        <h3>What you can learn:</h3>
        <ul class="topics">
           <li class="topic-item">Web Development</li>
           <li class="topic-item">Computer Science</li>
           <li class="topic-item">Data Science</li>
           <!-- additional HTML... -->
        </ul>
      </section>
      
      .topic-item {
        background: var(--yellow);  
        border: 1px solid var(--gray);
        /* additional CSS... */  
      }
    • 9:12 - text blocks twisting from the left - animation

      @keyframes in-from-left {
        from {
          opacity: 0;
          transform: scale(.8) rotate(-90deg)   
                     translateY(15vh);
        }
      }
    • 9:18 - text blocks twisting from the middle - animation

      @keyframes in-from-middle {
        from {
          opacity: 0;
          transform: scale(.8)   
                     translateY(15vh);
        }
    • 9:24 - text blocks twisting from the right - animation

      @keyframes in-from-right {
        from {
          opacity: 0;
          transform: scale(.8) rotate(90deg)   
                     translateY(15vh);
        }
      }
    • 10:07 - view() timeline example with timeline and range

      .topic-item {
        animation-fill-mode: both;
        animation-timeline: view();
        animation-range:
        &:nth-child(3n + 1) { animation-name: in-from-left; }
        &:nth-child(3n + 2) { animation-name: in-from-middle; }
        &:nth-child(3n + 3) { animation-name: in-from-right; }
      }
    • 12:20 - animation range 50%

      .topic-item {
        animation-fill-mode: both;
        animation-timeline: view();
        animation-range: 0% 50%;
        &:nth-child(3n + 1) { animation-name: in-from-left; }
        &:nth-child(3n + 2) { animation-name: in-from-middle; }
        &:nth-child(3n + 3) { animation-name: in-from-right; }
      }
    • 14:20 - simple cross document view transition code

      @view-transition {
          navigation: auto;
      }
    • 16:00 - adding media query for reduced motion

      @view-transition { navigation: auto; }
      
      @media not (prefers-reduced-motion) {
        @keyframes slide-in {
          from { translate: 100vw 0; }
        }
        @keyframes slide-out {
          to { translate: -100vw 0; }
        }
      }
    • 16:22 - adding ids to html for cross document view transition

      <body>
        <nav>
          <!-- additional HTML... -->
        </nav>
      
          <section class="hero">
            <div class="hero-image">
            <!-- additional HTML... -->
        </main>
        <footer>
          <!-- additional HTML... -->
        </footer>
      <body>
    • 16:58 - slide effect for cross document view transition

      @view-transition { navigation: auto; }
      
      @media not (prefers-reduced-motion) {
        #school-info {
          view-transition-name: main-body;
        }
        ::view-transition-old(main-body) {
      
        }
        ::view-transition-new(main-body) {
      
        }
        @keyframes slide-in {
          from { translate:e100vw 0; }
      	}
      }
    • 19:48 - nav bar and profile menu

      <nav>
        <h1 class="logo">A-School of Code</h1>
        <ul>
          <li>Courses</li>
          <li>Cohorts</li>
          <li class="profile">
            <img src="https://example.com/saron.jpeg" alt="woman speaking"/>
          </li>
        </ul>
      </nav>
      
      <ul class="profile-menu">
        <li>Account</li>
        <li>Settings</li>
        <li>Profile</li>
        <li>Billing</li>
      </ul>
    • 20:37 - adding popover attributes

      <ul class="profile-menu" id="profile-menu" popover>
        <li>Account</li>
        <li>Settings</li>
        <li>Profile</li>
        <li>Billing</li>
      </ul>
    • 20:51 - adding aria to popover target

      <nav>
        <div class="wrapper">
          <h1 class="logo">A-School of Code</h1>
          <ul>
            <li>Courses</li>
            <li>Cohorts</li>
            <li class="profile">
              <button class="profile-button" aria-haspopup="true" popovertarget="profile-menu">                                                 >
                <img src="https://example.com/saron.jpg" alt="woman speaking"/>
              </button>
            </li>
          </ul>
        </div>
      </nav>
    • 21:58 - establishing the anchor

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
      }
    • 23:25 - setting the target to top right

      .profile-menu {
        position-anchor: --profile-button;
        position-area: top right;
      }
    • 23:39 - setting the target to bottom center

      .profile-menu {
        position-anchor: --profile-button;
        position-area: bottom center;
      }
    • 24:16 - setting the target to span right

      .profile-menu {
        position-anchor: --profile-button;
        position-area: span-right;
      }
    • 24:17 - setting the target to span left

      .profile-menu {
        position-anchor: --profile-button;
        position-area: span-left;
      }
    • 27:30 - intro to the anchor() function

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
        position: absolute;
        top: anchor(bottom);
        left: anchor(left);
      }
    • 28:26 - using calc and units in anchor() function

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
        position: absolute;
        top: anchor(bottom);
        left: calc(anchor(left) + 1.5em);
      }
    • 29:43 - adding a text gradient

      .logo {
        background-image: linear-gradient(to 
                          bottom right in hsl, 
                          yellow, orange);
        background-clip: text;
        color: transparent;
      }
    • 31:05 - adding a gradient to border

      .primary-btn {
        background-image: linear-gradient(to 
                          bottom right in hsl, 
                          yellow, orange);
        background-clip: border-area;
        border-color: transparent;
        background-origin: border-box;
      }
    • 32:15 - shorthand for adding gradient to border

      .primary-btn {
        background: border-area linear-gradient(to bottom right in hsl, yellow, orange);
        border-color: transparent;
      }
    • 33:33 - arrow shape using path

      .review-shape {
        clip-path: path("M0 0 L 500 0 L 600 
                         100 L 500 200 L 0 
                         200 Q 100 100 0 0 z");
      }
    • 35:01 - arrow shape using shape()

      .review-shape {
        clip-path: shape(from top left,
          line to calc(100% - 50cqh) 0%,
          line to 100% 50cqh,
          line to calc(100% - 50cqh) 100%,
          line to bottom left,
          curve to top left with 50cqh 50cqh,
          close);
      }
    • 41:42 - dynamic range limit: no limit

      img {
        dynamic-range-limit: no-limit;
      }
    • 41:57 - dynamic range limit: standard

      img {
        dynamic-range-limit: standard;
      }
    • 0:00 - 简介
    • 自去年 WWDC 以来,Safari 浏览器和 WebKit 团队一直在不懈努力,持续改进网页技术,以提升互操作性与用户体验。动画、布局、视觉效果和媒体方面的新功能 (包括滚动驱动型动画、锚点定位、SVG 图标支持以及改进的媒体格式) 将于今年秋季在 Safari 浏览器中正式推出。

    • 1:46 - 动画
    • 动画是一种强大的工具,能够提升在线体验,让网站更具吸引力和趣味性。 使用 CSS 中的最新功能,特别是 Safari 浏览器 19 中现在支持的滚动驱动型动画,你无需借助 JavaScript 也可优化网站。这项功能意义重大,因为它可以提高用户体验并延长电池续航时间。 滚动驱动型动画引入了两个新的时间线:滚动时间线和视图时间线。滚动时间线支持将动画与用户的滚动行为关联起来,从而打造互动性更强的体验。例如,页面底部的进度条可以随着用户滚动下移而延伸,直观展示浏览进度。 在实现动画效果时,考虑辅助功能非常重要。有些用户可能偏好较少的动态效果,因为他们可能会因动态效果而感到不适,例如当大型对象缩放、镜头推拉或物体以不同的速度移动时,都可能引发这种反应。通过关注这些潜在的触发因素,你可以创造出更具包容性、适合所有用户的动画效果。

    • 19:01 - 布局
    • 今年秋季,Safari 浏览器将推出一个名为“锚点定位”的新 CSS 模块,它将彻底革新 Web 开发者创建工具提示和位置菜单的方式。 锚点定位让你可以轻松地将一个元素固定在另一个元素上,例如将菜单固定在个人头像旁边。该功能可实现菜单相对于锚点的精确定位。 Safari 浏览器还在响应式设计模式下重新引入了视口预设,让你能够更轻松地在各种设备和不同尺寸的屏幕上测试网站。

    • 29:05 - 视觉效果
    • 我们推出了多项全新的 CSS 功能,可增强网站和网页版 App 的视觉效果。 其中一项重要的功能是对“background-clip”属性进行了扩展。该属性最初用于通过渐变效果或图像填充文字,现在你也可以将其应用于边框。不过,为了实现预期效果,还需要进行一些额外调整,例如将边框颜色设为透明,并扩展 background-origin。你可以使用此项技术让各种元素 (如按钮和进度圆环) 看起来更美观。 另一项激动人心的进展是对“shape()”函数的支持,该函数使设计师能够比以往更轻松地创建响应灵敏的形状。它让你能够精细控制形状中哪些部分随视口缩放,哪些部分保持静态效果,确保形状在不同尺寸的屏幕上亦能保持其外观和比例。这对于创建装饰性元素 (如箭头或背景) 尤其有用。 此外,CSS 还引入了新的排版功能,例如“text-wrap:pretty”,在 Safari 浏览器 19 中可用。这项功能旨在通过解决短行、过多断字和行长不均匀等问题来提高文本的可读性。它会调整单词间距和换行符,以创建更美观且更协调的段落布局。这是一项细微但对整体用户体验有显著提升的改进,并且在不支持该功能的浏览器中也会优雅降级。

    • 38:22 - 媒体
    • 今年秋季,Safari 浏览器将推出多项重要的媒体增强功能。其中包括 SVG 图标的实现,这将改善各种 Safari 浏览器功能 (如收藏图标、书签和起始页) 的用户体验。与传统的 PNG 相比,SVG 图标提供更出色的可扩展性和较小的文件尺寸。 此外,Safari 浏览器现在还为 WebKit 和 Safari 浏览器引入对高动态范围 (HDR) 图像的支持。HDR 图像通过显示更深的色调、更广的范围和更明亮的颜色,使网页内容更加生动和更具吸引力。 Safari 浏览器还扩展了对各种媒体格式的支持,包括音频格式 Ogg Opus 和 Ogg Vorbis,并在确保不同 API 之间编解码器与容器格式的复杂组合能够正常协同工作方面取得了进展。这些升级让你能够将实时播客和视频录制功能集成到网页版 App 中。 此外,Safari 浏览器正在增强对空间网页的支持,让你能够在网页中以立体方式渲染 3D 模型并嵌入沉浸式视频。这些改进旨在提升网页的互动性和沉浸感,为所有用户提供更丰富且更具吸引力的浏览体验。

Developer Footer

  • 视频
  • WWDC25
  • Safari 浏览器和 WebKit 的新功能
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载 (英文)
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    获取 Apple Developer App。
    版权所有 © 2025 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则