
-
SafariとWebKitの新機能
SafariとWebKitに搭載されている最新のWebテクノロジーを活用して、驚くような体験を生み出しましょう。CSSのさまざまな機能を取り上げ、それらがどのように役立つかを解説し、スクロール主導のアニメーション、ドキュメント間のビューの移行、アンカー配置などについて説明します。また、オーディオ、ビデオ、画像、アイコンなどにわたる新しいメディアのサポートについても説明します。
関連する章
リソース
- 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
-
このビデオを検索
こんにちは サロン イトバレクです Safari & WebKitチームの Web Technologies Evangelistです 去年のWWDCから 新しいWebテクノロジーをお届けすべく 取り組んできました ユーザーから要望があったものや ユーザーのためになるものです AppleはユーザーとWebを真剣に思い Webデザイナーやデベロッパを 支援したいと思っています アイデアを簡単に 実現できるようにするためです Appleの目標はシンプルです デベロッパのアプリを 信頼でき 互換性があり プライバシー最優先とすることです だからこそ 本日 今秋Safariに登場する 新しいWebテクノロジーを発表します このリリースには 多くの優れた機能があります Appleでは 相互運用性の向上と 最新機能の間にある ギャップを埋めることに膨大な時間と 注意を払っています 本セッションでは 私のお気に入りの 機能をいくつか紹介します そして機能間のギャップを埋めた 領域をいくつか紹介します ここで取り上げる機能は 4つのカテゴリに分類されます アニメーションでは スクロール主導の アニメーション ドキュメント間のビューの移行を説明します レイアウトは アンカー配置において 非常に重要です 視覚エフェクトに関しては シェイプ関数 background-clipと text-wrap: prettyを紹介します メディアで使用されるCSSを取り上げ SVGアイコンのサポート 画像 そして既存のメディア形式への改善 について説明します まずはアニメーションから説明します アニメーションは 作成する オンライン体験を向上させ ページを楽しく 斬新なものにします 今話した内容をお見せするために 1つ例を紹介します オンライン学習の 「A-School of Code」のサイトを 刷新しているとします もう少し楽しくて 実用的なサイトにしたいと思います 最新の機能を活用すれば CSSだけで正確に作成できます 最終的なサイトがどのようなものになるか お見せましょう ここに オンラインスクールの サイトがあります 技術的なスキルを 教えるためのサイトです この素敵なグリッドで トピックのリストが表示されています 素晴らしい学生を採用した 企業の名前を見ることができ コースやカリキュラムを気に入った 学生のレビューを読んだり 最後に もっと学びたいと思う プログラムを選択する 2つのオプションが表示されます このサイトを進化させるために いくつか実行できます 1つめは 目を引く アニメーションです Safari 19で登場したスクロール主導の アニメーションです CSSアニメーションは 2007年にAppleが WebKitに導入してから Webの一部となっています ですが 操作と連動させるには JavaScriptが必要でした JavaScriptはWebで 多くを行う強力な言語ですが 使わずに済むのであれば 使わずにおくと パフォーマンスが向上し バッテリー駆動時間が長くなります スクロール主導のアニメーションなら CSSだけを使って アニメーションをスクロールにリンクできます どのように機能するかを見ていきましょう スクロール主導を理解するには 最初に知っておくべき重要な概念 「タイムライン」があります Webのデフォルトのタイムラインは 時間ベースです つまり時間が経つにつれて アニメーションが再生されます
経過秒数が増えるごとに 進行状況バーが連動します スクロール主導の場合 2つの新しいタイムラインがあります 1つめはscroll()タイムラインです 私のWebサイトでは scroll()タイムラインで 進行状況バーを作成しました ページの下部にあります これはわざとらしい例かもしれません 現実には このような進行状況バー は必要ないでしょう すでにスクロールバーがあるからです ですがこれはスクロール主導の 動作を表示する簡単な方法です どうやって構築したかを説明しましょう バーの作業を始める前に 重要なことを考える必要があります アクセシビリティです スクロール主導のアニメーション はサイトに動きを与えますが 動きが少ないことを好むユーザーもいます ユーザーはこれをアクセシビリティ設定で 示すことができます 不快感を与えないよう ユーザーの選択を尊重したいのです 動きによって不快感を感じることは 複数の要因によります 経験 遺伝 疲労 場合によっては前庭障害などです 症状は 吐き気 めまい 頭痛 その他の身体的な不快感です
デベロッパは さまざまな種類の動きを選べ サイトやWebアプリに追加できますが 意図せずに動きによる 不快感を引き起こす可能性があります 大きなオブジェクトを拡大縮小させたり 視差エフェクトのように 異なる速度で移動するオブジェクトや 3次元エフェクトをシミュレートする 技術 または周囲を動かしたり ユーザーの焦点領域外で 一定の動きをみせるといったことです これらがすべてではありませんが しかし最初に考慮すべき ポイントです このようなエフェクトを使っていますか? 私の場合 アニメーションは実に シンプルな進行状況バーです かなり安全で小さく Webで一般的な動きの一種です なので このアニメーションが 動きによる不快感を引き起こす 心配はないと思います ですが動きを加えるときは常に 配慮を検討する機会でもあります ユーザーのさまざまなニーズへの 影響を考慮します ではスクロールバーに取り掛かりましょう まずCSSから取り掛かります スクロールバーを フッターの疑似要素として追加します いくつかスタイルを施し バーは左下隅から始まって スクロールしても下隅に留まるようにします
次にお馴染みのCSSを使って keyframesで アニメーションを作成します ブラウザに進行状況バーが X軸方向に大きくなるように指示し 左から右に伸びる進行状況バーの エフェクトを作成します スクロール主導のアニメーションの 基礎を築いたので この基礎を完成させるために もう1つやることがあります アニメーションを進行状況バーに追加します ここで行うことができます 次にスクロールです バーが左から右に伸びるのは スクロールするときだけです それには進行状況バーに 新しいタイムラインを加えます animation-timeline: scroll();をCSSに追加して デフォルトのタイムラインを置き換えます これを機能させるためには animationプロパティの後に animation-timelineを置きます アニメーションを スクロールタイムラインとリンクし 数行のCSSだけで 進行状況バーを作成しました JavaScriptは必要ありません より実用的な例を見てみましょう スクロールだけでなく ページに要素が表示されたタイミングで アニメーションが 動くようにします この例を見てください ブロックが回転して グリッドを作成しているのが見えます これはスクロールすると発生しますが 別の要因もあります アニメーションは この青いボックス内でのみ発生します ブロックがビューポートに入ったときのみ 一番下から始まり 画面半分を通過したら ボックス上部で回転を停止します ビューポートを考慮する際は 別の種類のタイムラインが必要です view()タイムラインです いくつかのコードを確認して どう機能するかを見てみましょう
まずhtmlから取り掛かります CSSで使用する クラスを含むトピックのリストがあります 基本のCSSスタイルを追加して リストを黄色のボックスにします これはWebサイトのテーマと一致します 基礎が完成したので 次はスクロール主導の アニメーションです まずスクロールにどのアニメーションを 割り当てるかを考えます このサイトでは 一度に3つの アニメーションが機能しています これらのアニメーションを各ブロックに 適用する必要があります 1つめは ボックスを上に上げて 左から組み立てる動きです 2つめは ボックスを上に上げて 中央で組み立てる動きです そして3つめは ブロック 右から上へと上がる動きです
これまでのところ 新しいコードは 使っていません 従来のCSSアニメーションを使用しています
ここでスクロール主導のアニメーションの スクロール主導の部分を 採り入れたいと思います ですがその前に アクセシビリティについて考えます スピニングも 不快感を引き起こす よくある要因の1つです ですがこれはむしろ 見当識障害を引き起こす可能性がある 環境的なエフェクトです ここでは 少しの要素で 比較的小さなアニメーションなので アクセシビリティに影響を及ぼす リスクはないと思うので コードに戻りましょう 次に アニメーションコードを CSSに追加して 左のアニメーションを左のボックスに 中央のアニメーションを 中央のボックスに 右のアニメーションを 右のボックスに適用します 要素のアニメーションスタイルを 動きの前と後で保持したいので animation-fill-mode: bothも追加します これでコードの スクロール主導の部分にたどり着きました これを機能させるには 2行のコードが必要です 1つは 新しいview()タイムラインです ここに追加します 2つめは animation-rangeです animation-rangeはブラウザに タイムラインに基づき アニメーションをいつ始め いつ終了するかを指示します view()タイムラインを選択したので 範囲には要素が ビューポートのどこにあるかが反映されます デフォルト値は0〜100%です これにより アニメーションは 0%で開始され つまり要素がビューポートに 入る瞬間に開始され 100%で終了します つまり要素が完全に ビューポートを出るときです デフォルト値では アニメーションがどう見えるか見てみましょう 希望の動きにかなり近いですが まだ完全ではありません スクロール主導のアニメーションの場合 特に情報を表示する このようなWebサイトの場合 ユーザー体験を 考慮することが重要です アニメーションは楽しく サイトを目立たせますが 情報は 読みやすくなければなりません アニメーションが機能性を 損なってはなりません この場合アニメーションが続く長さに 配慮するということです 100%も持続させたくありません そうするとブロックがずっと 動いていることになり 読みにくくなります
代わりに目を引く短いアニメーション にしようと思います ユーザーがブロックを読むことができる 場所を見つけます ページの半ばで止まるようにすると よいように思います 動きにより楽しさが生まれ 同時に ユーザーが読むのに十分な 時間を確保できます そこで範囲を 0〜50%に変更します つまりアニメーションは 要素がページの 半分まできたら止まり 動いている時間が制限されます 上にスクロールして戻ると アニメーションが逆に動き ボックスが50%の場所でバラバラになり始め 0%で完全に バラバラになります 0%は正確にはどこかなど 範囲を細かく制御できます どんなオプションが どう機能するかを確認するには さまざまな値を確認して 探ってください 新しいタイムラインはパワフルで アニメーションと 組み合わせれば ユーザーに素晴らしい体験を提供できます これがWebKitの スクロール主導のアニメーションです 次にお見せするアニメーションは ページ全体で機能します Safari 18.2で登場の ドキュメント間のビューの移行です Safari 18.0で導入された ビューの移行の機能強化です ドキュメント間のビューの移行により ページ間のスムーズな 移行を こんな感じから
このクロスフェードのような よりシームレスなものへと JavaScriptなしで実行できます このエフェクトに必要なのは 1行のCSSだけです 移行なしでこの ナビゲーション項目をクリックすると ブラウザはページを消去し 新しいページを読み込みます 移行が素晴らしいのは ページが変わる前後で スナップショットを撮り それらの間で移行を作成し このようにスムーズに表示することです この見た目が気に入っています 仕組みは次のようになっています CSSで@view-transition を追加するだけです そしてnavigationプロパティをautoにします これで完了です もう1つ やらなければならないことがあります ページに動きが加わるので 立ち止まって アクセシビリティの懸念があるか 考慮する必要があります クロスフェードはアニメーションですが かなりわずかな動きで 動きを抑える必要があるユーザーにとって より安全な アニメーションの1つです なのでこれで完成です ここで クロスフェードではなく スライドを使いたいとします ナビゲーションで項目をクリックすると ページが横に押し出て 新しいページが滑り込みます 実際にお見せしましょう ただし もしあなたが 動きに敏感なら いくらかの不快感を与えるかもしれません なので実演が終わったらお知らせします
ここではお気に入りの スライドエフェクトを作成しています クロスフェードから一段階上の動きです その前に一旦立ち止まり ユーザーへの影響を考えてみましょう アニメーションが終わりました
このスライドエフェクトは 動きによる不快感を引き起こす 可能性がある アニメーションでしょうか? アニメーションとしては これはかなり大きなものです 単に単語や要素が 動くのではなく 2ページ全体が動きます このアニメーションが安全かどうか 確信が持てないので また単なる機能強化で ユーザー体験にとって重要ではないので 動きを抑えるmediaクエリ に入れるのが最善です 早速やってみましょう
これがそのmediaクエリです ブラウザに スライド移行は 動きを抑えるように 選択されていない場合に限るよう指示します ではスライドエフェクトをコーディングします CSSアニメーションを使用して keyframesを作成し 2つのページの 動きについて指示します 1つのページを横に押し出し もう1つを滑り込ませます
次にこのアニメーションを使用する ターゲットを設定します デフォルトのnavigation: autoにより ページのすべてが移行しました ですが実際にはページ上のすべてを 移行させたくありません ナビゲーションバーはそのままにしたいです そしてフッターもそのままに しておきたいと思います なのでページごとに 移行させたいものを 1つのidでラップします これを「school-info」とします
後で使用するview-transition-nameを 宣言します ビュー移行を実装すると 疑似要素もたくさん使えます そのうちの2つを使います
view-transition-old とview-transition-newです view-transition-oldは 移行が起こる直前の サイトのスナップショットを表します view-transition-newは 後のスナップショットを表します これらを使用するには 引数を渡す必要があります ここで「main-body」 view-transition-nameを使用します 「main-body」を両方に渡します これは移行したいページの部分を 包含しているからです 次にkeyframesの名前に animation-nameを設定します これだけです どうなるか見てみましょう 動きに敏感な方は 少し目をそらした方がいいかもしれません
いいですね ナビゲーション以外の 残りの部分がクリックで移行します
アニメーションが終わりました ドキュメント間のビューの移行で 気に入っているのは これが1つの機能強化であるという点です 必須ではなく Webサイトの機能を 変更したりしません ブラウザが対応し ユーザーが望む場合には優れた追加ですが そうでなくても全く問題ありません アプリやサイトに ドキュメント間のビューの移行を実装する場合 移行するすべてのページが 同じところに ある必要があります example.comから example.com/cohortsはうまくいきます 別のサブドメインへの移行は うまくいきません これによりユーザーの安全や プライバシーが確保されます 悪意のある可能性のあるページが あなたのサイトを標的にして アニメーションを 悪用させたくないでしょう 次にレイアウトの新機能を見てみましょう アンカーの配置です Safariの新機能として今秋登場します 特に既存の Popover APIから構築する場合 アンカー配置は ツールチップの作成や メニューの正確な配置 ビューポートで変更に 適切に反応することを これまで以上に簡単にする CSSモジュールです 早速見てみましょう スムーズなナビゲーション体験で ユーザーがサインインしたら ナビゲーションバーで プロフィール写真を表示させたいです 写真をクリックすると メニューが表示されます Webアプリでよく見られる機能です まずhtmlから取り掛かります
これがプロフィール写真付き ナビゲーションバーのhtmlです これが写真をクリックしたときに 表示したいメニューです スタイルを追加して どうに見えるか見てみましょう ページの残りの部分が 邪魔にならないようにしましょう いいですね 素敵なナビゲーションバーと メニューがあります ですがメニューが常に 表示されるようにはしたくありません プロフィールアイコンをクリックすると メニューがポップアップし 再度クリックすると消えるようにしたいです アイコンをクリックしたら アイコンは表示したくありません なのでプロフィール写真に アンカーさせようと思います これを解決するには アンカー配置を始める前に Popover APIを使用します ポップオーバーする要素に popover属性を追加します この場合 私のプロフィールメニューです 次にポップオーバーにIDを渡します 次にクリックできるものが必要なので 私の画像をボタンで ラップします その際 支援技術を必要とする人が ボタンとそのメニューに アクセスできることを確認します aria-haspopup属性を追加し 画面読み上げ機能に ボタンがクリックされたら メニューを表示するよう指示します 最後に popovertarget属性を追加します ポップオーバー要素のIDと 同じ値に設定します できました これでプロフィール写真をクリックすると ポップオーバーが表示され クリックすると消えます ですが 左隅に表示されています プロフィール写真にアンカーし 直下に表示されるようにします ここでアンカー配置を 導入します
アンカー配置により ある要素を 別の要素に固定できます そしてアンカーの場所に基づいて その要素を配置できます 仕組みは次のようになっています まずアンカーを決めることから始めます anchor-nameプロパティで 名前を指定します この場合アンカーは 私のプロフィールボタン つまりボタンの場所に基づいて メニューを配置します そこでアンカー名を 「profile-button」にします anchor-name は任意のユーザー定義文字列です なので2つのダッシュで始めます 次にメニューに移動し 名前を付けたアンカーに接続します アンカー配置のコンテキストでは メニューはターゲットです ターゲットに 情報を提供する必要があります position-anchorプロパティを アンカー名である 「profile-button」に設定し アンカーに接続します 「—profile-button」と入力します 最後にメニューをどこに配置するか 指示する必要があります これには2つの方法があります 1つめはposition-areaです これが何かを説明しましょう
アンカーは9つの正方形の グリッドの中央にあります 左 中央 右と 3つの列があります そして上 中央 下の 3つの行があります ターゲットをアンカーの 右上隅に配置したい場合 position-areaを top rightに設定します アンカーに対してメニューをどこに 配置するかを説明する 直感的な方法です プロフィール写真の下に メニューを表示したい場合は 下部中央のグリッドにあるので 「bottom center」と入力します
このようになります かなりいいですが 望んでいるものではありません 指定した通り一番下にありますが メニューが プロフィールボタンよりも広いので グリッドに収まりません プロフィール写真の左側に メニューの左側が 揃うようにしたいのです そのため 別の値を使用します position-area: bottom span-rightです これでメニューが中央のグリッドが 始まるところから表示され 右側にはみ出るようになります
これでメニューと プロフィール写真がいい感じに並んでいます ただこの画面サイズでは問題ないですが ビューポートが より狭い別のデバイスではどうでしょうか? Safariを レスポンシブデザインモードにしましょう それには 「設定」> 「詳細」に移動し 「Webデベロッパ用の機能を表示」 にチェックを入れます
これで「開発」オプションが表示され モードに入ることができます これはデベロッパ要望の機能 ビューポートプリセットです テストと開発をスピードアップするために 慎重に選ばれた ビューポートサイズから選択できます トグルでビューポート プリセットを回転できるのがいいです 縦向きと横向きモードを ワンクリックで簡単にテストできます JavaScriptを必要とせずに メニューがビューポート幅の 変更に適合するようにします 今のメニューは左揃えです 幅が狭くなったら プロフィールボタンの 右側に揃うように メニューを動かしたいです アンカー配置の利点は このような状況に 正確に対処できるように 設計されている点です position tryプロパティを使用します その名の通りのことをしてくれます 指定した位置にスペースがない場合に 試す位置を設定できます スペースがなければメニューを右揃えで 表示したいので position-tryを 「bottom span-left」に 設定します position tryでは 別の値も使用できます メニューをどこに置きたいか 明示的に指定する代わりに position-areaを基準にした値を 設定できます 値の1つは「flip-inline」です flip-inlineは要素が元々あった位置 がどこであれ インライン方向に移動させます flip-blockでブロック方向に 移動させることもできます 望んでいることをより直感的に 説明できる方法です 実際の動作を見てみましょう レスポンシブモードに戻ると 13インチのiPad用の画面で メニューは左揃えになっています ですが向きを変えると position-tryが機能し メニューが右揃えになり 望んだとおりにレスポンシブな メニューになりました
WebKitチームの同僚が position-areaを提案し 標準化機関と協力して アンカー配置を使用する直感的な方法を 実現したことを誇りに思います そしてアンカー配置を使用する 別のアプローチをお見せします anchor()関数と呼ばれる 非常に強力なツールです anchor()関数では要素を グリッド配置にする代わりに 要素の側面を アンカーの側面に揃えます まず 位置をabsoluteに 設定する必要があります 次に メニューの上部側面を 確認します アンカーの下部に揃えるため anchor(bottom)に設定します 次に メニューの左側を 確認します 値をanchor(left)に 設定して アンカーの 左側に揃うようにします
これは非常に単純な例ですが メニューを写真の位置に 揃えたい場合はどうでしょうか? パディングを考慮する必要があります position-areaを使用して margin-leftを追加するか アンカー関数で calc()関数を追加することもできます ここではanchor()関数に calc()関数とem単位を 組み合わせメニューをスライドさせます 多数のユースケースでは position-areaは優れた 直感的なアプローチですが ある場所から別の場所へ アニメーションを加える場合や 複数のアンカーを使用するなど もっと複雑なことをしたい場合は anchor()関数を 使用します どちらを選んでも anchor positioningにより CSSだけでよりレスポンシブで 相対的な配置を簡単に作成できます そして最後に CSS機能を活用して 優れた視覚エフェクトを作成する 新しい方法をご紹介します 1つは 境界線を 次のレベルに引き上げます 約15年前 Appleは background-clip: textを公表しました これにより テキストを 色で塗りつぶす代わりに グラデーションや背景画像で 塗りつぶすことができます 私のロゴの黄色から オレンジへのグラデーションのようにです 私のロゴはとてもシンプルです 基本的なフォントの単語だけなので 画像を使うのではなく ただテキストを使うつもりです そうすればCSSでスタイルを設定できます 私のロゴはh1要素でh1sを白の スタイルにしました なので白いテキストから始めます グラデーションエフェクトを追加するため まずbackground-imageを 右下方向に黄色からオレンジへと変わる 微妙なグラデーションに設定しました テキストの背後にグラデーションがあります 次にbackground-clipプロパティを textに設定します すると白いテキストに戻りました 私が望むものではありません もう1つやることがあります h1スタイルを上書きし ロゴを透明にします そうすると邪魔するものがなくなり グラデーションが輝きます テキストにはグラデーションだけでなく 画像も使用できます この紅葉の背景 画像のようにです Background-clip: textにより テキストに新しい視覚機能が追加され そしてAppleは今 境界線に対しても 同じことをしています その仕組みをご紹介しましょう 私のボタンは 太い白い境界線で スタイルされています ですがメインのボタンについては 何か違うことをしたいのです 新しいbackground-clip値を使用して 明るくしたいと思います そして境界線にグラデーションを与えます まず微妙な黄色からオレンジへの グラデーションを background-imageとして追加し ボタンの背景にグラデーションを加えます 次に新しいbackground-clip をborder-areaの値と共に追加します 黒い背景と 白い境界線に戻ってしまいました テキストで経験したのと 同じ問題に遭遇してしまいました 境界線の色は変わったものの ボタンのスタイルである 白い境界線の後ろに隠れています 境界線の色を透明にして グラデーションが輝くようにします ここに追加して どうなるかみてみましょう 面白いですね グラデーションはできたものの 新しい問題があります グラデーションが繰り返されているようです ボタンの幅には合っているものの グラデーションは境界線の 内側にのみ広がり 縁でグラデーションが再開します これを修正するには 背景を 境界線のかなり外側まで 拡張する必要が あります それには background-originを指定し border-boxに設定します いいですね
もっと簡単に行うこともできます background-imageを 宣言する必要はありません background-clipとborder-area値を使用した グラデーションです 境界線だけでも できることはたくさんあります 画像を選択したり 楽しいグラデーションを選択する中で プログレスサークルや 警告サイン このような美しい二重の 境界線を持つ写真など さまざまなものを作ることができます background-clip: border-areaには コンテンツを美しく見せたり WebサイトやWebアプリを 目立たせるのに役立つ オプションがあります これらの例のデモや background-clipの詳細は webkit.orgのブログ記事をご覧ください 視覚エフェクトの改善は 境界線だけにとどまらず CSSで作成できる用途の広い 図形も改善されています 次は Safari 18.4から導入の shape()関数について お話しします Appleのアプリや 「A School of Code」の サイトでも 図形は さまざまな方法で使用されています 推薦セクションでは すべてのレビューを曲線的な矢印を 背景として表示しています これらは美的要素として clip-pathに設定されたCSSシェイプです shape()関数の前で pathを使用して実現します path関数は強力なツールであり 用途が広く 幅広い図形を描画するために すべての種類の点と曲線を 使用できます ビューポートの幅を変えると 図形はどうなるのでしょうか? わかりやすいように 3本の矢を分離して それらがどのように反応するかを示します サイズを変更すると 矢印の先端と 曲線が表示されません ビューポートに応じてサイズ変更されません もっとリスポンシブルにしようと思います ですがビューポートの変更に応じて すべての線と曲線が サイズ変更されるようにはしたくありません いくつかの部分だけを変更したいのです 曲線や 矢印の先端の角度は変えず ビューポートに基づいて 長さと高さを拡大/縮小したいのです shape()関数を使用すると デモのウィンドウが 小さくなるにつれて 図形の幅も小さくなります こうしたいですね ですが先端の角度と 曲線部分はそのままで シェイプが狭くなっても 変更されないことに 気づくでしょう これこそshape()関数で 気に入っているところです このような きめ細かな制御ができ 変更に対し何を リスポンシブルにするかを選択できます ではコードがどのようなものか 見てみましょう コードでは異なる単位を 使用していることに気付くでしょう コンテナクエリの高さや パーセンテージなどです これはshape()では すべてのCSS単位を使用できるためです calc関数も使っています レスポンシブな値を作成し 幅広い単位を使用できるので 図形のさまざまな部分を 選択的に制御し 必要とする正確な 応答性を実現できます shape()関数を使用できることで 柔軟で応答性の高い 図形を作成できます Appleが扱いやすくしているのは 図形だけではありません テキストにも 素晴らしい改善があります Safari 19で利用可能になった text-wrap: prettyのような 新しいタイポグラフィ機能があります
この本文自体には なんら問題ありませんが 読むのが少し難しく あまり美しくありません 1つめは 段落の最後に 1つの単語のみの短い行があります 視覚的に気が散り 段落の間に余白が生まれ その余白が 実際よりも大きく見えます
2つめはハイフンです ハイフンを付けること自体は 何も悪いことではありません ですが控えめにしたいと思います ハイフンでつながれた文を 3行も続けたくありません 3つめは「ラグ」と呼んでるもので 段落の行末が作る 全体的な形状を指します よいラグは 各行は同じ長さで構成されています このようなひどいラグは ギザギザしていて視覚的に目立ちます
text-wrap: prettyには さりげない意図的な効果があります
1語だけの行 ハイフンでつながった行 そしてひどいラグが
なくなりました
仕組みは次のようになっています text-wrap: prettyを使用しないと ブラウザは 文章をできるだけ長くし 最後まですべてのスペースを使おうとします ですがtext-wrap: prettyを使用すると ブラウザは別の点に着目し 希望とする 緑のラインに合わせて 文章の長さを 調整するようになります 紫と赤の線で示した間にあるスペースには 絶妙に調整された スペースがあります 見事に調整されています また 文章が極端に短くならず ハイフンを使わずに済むように 単語が次の行に 移動されています コードは単純です text-wrap: prettyを 段落 見出しなどの 任意の要素に適用します 特に 短い行や たくさんのハイフンつながりの文末や ひどいラグがある文章であれば その効果は一目瞭然です text-wrap: prettyの よいところは 機能強化でもあることです テキストに追加し ブラウザがサポートしている場合は テキストがより美しく表示されます ユーザーのブラウザで サポートされていない場合やブラウズが 短い最後の行だけを 調整することにしたとしても ユーザーにとって優れた体験となります 害も失敗もありません
多くのCSS機能を学びましたが ほぼスタイルに関するものです ここからはメディアを取り上げます 最初に説明するメディアは 小さいながらも強力です 皆様からフィードバックを いただいておりました SVGアイコンが今秋Safariに登場です SVGアイコンはファビコンとして 機能するだけではありません ユーザーがDockなどに追加すると Safariスタートページの ブックマークレットで表示されます SVGをファビコンとして使用すると コンテキストに 最適なアイコンをSafariが生成します サイズもファビコンで よくあるpngよりも小さくなります もう1つ静的なメディアがあります 発表できて嬉しいです WebKitとSafariに 登場するのは HDR画像です HDRは Webで見慣れた SDRの写真やビデオよりも メディアをよりリッチで 鮮やかなものにします Safari 14.0以降 AppleはHDRビデオに 対応してきましたが これからは画像にも対応します HDRとSDRの違いを 説明するために この2つのシミュレーションをお見せします 左の画像はSDR 標準ダイナミックレンジ画像です さまざまなファイル形式で 作成できます このビデオではHDRがどう見えるかを お見せできませんが いくつかの違いをシミュレートした 右側の画像を作成しました HDRでは色相が深くなり 色域が広くなり 明るいことがわかります 実際のHDR画像で これらの違いを見ると驚きます これらの違いにはいくつかの 技術的な理由があります その1つは 各画像が保持する データの量です SDRは8ビットで HDRは10〜16ビットです より大きなビットにより 表示できる画像データが増えます SDRは通常 sRGB色空間ですが HDRはP3のようなより広く より豊かな色空間です また ファイル形式も 異なります SDRは JPEGを含む ファイル形式ですが HDRは 同じファイル形式に加えて HEICとAVIFも含みます ですがHDRを現実世界で使うには 考慮すべき点があります オンラインの大多数のメディアは 即HDRにはなりません HDRとSDRを並べて表示する方法と それらをどう表現するのか 検討する必要があります ダイナミックレンジのため HDR画像はSDRよりも はるかに明るく見える傾向があります 青い鳥が際立ってみえますよね 検索結果画像や ギャラリーでは ユーザーの気を散らし エクスペリエンスの低下につながる 可能性があります そこで デベロッパの皆様が この格差をより詳細に 制御できるようにしたいと考えています そこでdynamic-range-limitという CSSプロパティがあります dynamic-range-limitの デフォルト値は「no-limit」です HDR画像やビデオを そのまま表示します 他の画像よりもはるかに明るく 目立つ場合でもです またはCSS dynamic-range-limit: standardで HDR画像やビデオをSDRのように レンダリングするよう ブラウザに指示できます 3つめは dynamic-range-limit: constrainedです HDR画像のエクストラダイナミックレンジを 使用するように ブラウザに要求し 美しくみせつつ 目立たないように することができます これによりSDRとHDRを 混在させて快適に表示できます constrained値は Safari 19の最初のベータ版では 未対応ですが ご期待ください HDR画像を使用しても ブラウザが未対応の場合でも 問題ありません ブラウザはHDRをSDR範囲に マッピングするので フォールバックは不要です 最高の画像を使用すれば 残りはブラウザが処理します つまり よりダイナミックな写真やビデオを Webサイトや Webアプリで使用し よりリッチで美しい ビジュアルを届けることができます 音声やビデオなど その他の種類のメディアも WebサイトやWebアプリを 生き生きとしたものにできます また さらに多くの メディア形式への対応も進んでいます ここ数年 Appleは 幅広いコーデックやコンテナを 完全にサポートするように 取り組んできました WebでJPEG XLと HEICに初めて対応し Safari 19ではOgg Opusと Ogg Vorbisも対応しました 15種類の形式に対応し WebサイトやWebアプリで使用できる さらに多くのオプションを 提供しています AppleはAPIやWebでコーデックと コンテナの複雑な組み合わせが 機能するようにしてきました Safari 18.4では MediaRecorder APIで WebMに対応してギャップを埋めました この収録用APIにより Webアプリにリアルタイムの ポッドキャストや ビデオ録画といった機能を統合できます Opus音声コーデックを使用して WebMファイルを作成でき SafariとWKWebViewではビデオに VP8かVP9を使用できます また空間Webでも多くの メディアに対応するよう務めています ユーザーが3Dモデルを操作できるようにし 3Dモデルを 立体的に他のWebコンテンツの インラインでレンダリングに できるようしました WebページにSafariが理解し 正しくレンダリングできる 没入感あふれるビデオを 含めることもできます 追加のツールは必要ありません 詳しくは 空間Webに関する セッションをご確認ください 3Dモデルの埋め込み ユーザーへの空間メディアの表示 Webサイトに3D環境を 追加できるようにする 新機能のプレビューについて 網羅されています これらは昨年Appleが実現した メディア対応のハイライトです 本セッションでは CSSとメディアに着目しました 他の機能について 詳しく説明しているセッションもあります WebGPUの概念を紹介する WebGPUのセッションや WGSLシェーダ言語の 概要セッション 最適なデバイスパフォーマンスを得る方法 のセッションがあります また宣言型Webプッシュ に関するセッションもあります サービスワーカーを必要とせずに これこれを使用する方法や これがいかに効率的で透明性の高いものか 元のWebプッシュとの下位互換性 についてカバーします それだけではありません 昨年秋以降 複数のバージョンのSafariで 多くの新機能が リリースされました 最も要望の多かった機能も 含まれています CSSはタイポグラフィを美しくし 世界中の全言語に対応します ユーザーのプライバシー保護に 役立つ機能もあります webkit.orgのリリースノート をご確認ください またSafariの最新機能に関する 記事を読んで 最新のWebテクノロジーを把握できます WebKitのイシュートラッカー bugs.webkit.orgで Web技術のバグレポートや 機能リクエストを提出できます
SafariのUIや iOS iPadOS macOSに関することなら feedbackassistant.apple.comで 報告できます Safariの機能について ぜひ最新情報をご確認ください Caniuse.comは優れたリソースです Safari Technology Previewを ダウンロードして 登場予定の 新機能についてご確認ください 約2週間ごとに更新されるので WebKitに追加された最新機能について 確認できます AppleはWebエクスペリエンスを 素晴らしいものにする さまざまな機能をお届けするために 懸命に取り組んできました これらのリリースにより ビルドが簡単で楽しくなれば幸いです これらの機能を使ってみて ご意見をお聞かせください どうぞコーディングをお楽しみください
-
-
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; }
-