タグアーカイブ HTML

WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPress のブロックエディターでカスタム HTML ブロックを保存後に編集画面を開き直すと、ブロックの中身がまるごと消えて空欄に見える現象は、Gutenberg の React 側パーサーが HTML 構造を正しく解析できずに描画を放棄しているのが主な原因だ。script タグや閉じタグのない要素、複雑なインラインスタイルなどが引き金になる。

なぜカスタムHTMLブロックが編集画面で空になるのか

なぜカスタムHTMLブロックが編集画面で空になるのか

フロントエンドでは正しく表示されるのに、管理画面のブロックエディターだけで中身が空になるのは、データそのものはデータベースに保存されている証拠だ。コードエディターモードに切り替えれば、貼り付けた HTML が消えずに残っているのが確認できる。この現象が起こるのは、ブロックエディターがビジュアルモードでブロック内容を再表示するときに、DOM パーサーが特定の HTML を「壊れた構造」と判断してレンダリングを飛ばしてしまうからだ。

具体的には、Gutenberg が内部的に使用している React の DOM レンダリング機構が、管理画面の安全な枠組みの中で処理できないタグや構文に遭遇すると、そのブロック全体を安全のためにスキップする。結果として視覚的には空のブロックに見えるが、データベースの post_content には元のコードがそのまま格納されている。

カスタムHTMLブロックの中身が消える原因を特定する手順

カスタムHTMLブロックの中身が消える原因を特定する手順

まず、どの部分が問題を引き起こしているのかを切り分ける。以下の手順で原因箇所を絞り込む。

ブロックエディターのコードエディターモードで現状を確認する

編集画面右上の「︙」メニューから「コードエディター」を選択すると、ビジュアル表示ではなく生の HTML 構造が表示される。カスタムHTMLブロック内のコードがここで確認できれば、データは失われていない。このとき、Markdown 記法でブロック境界を示す <!-- wp:html --><!-- /wp:html --> のコメント行の内側にコードが残っているかを確かめる。

HTMLを最小単位に分解して原因のタグを特定する

ブロックに貼り付けた HTML を、1つのタグ単位で分割してカスタムHTMLブロックに1つずつ入れ直す。たとえば script タグ、style タグ、空要素(<div></div> など)、インラインイベントハンドラ(onclick など)をそれぞれ別のブロックに分けて保存し、再読み込み時に消えるかどうかをテストする。問題を起こすタグが特定できれば、その部分だけ別の実装方法に切り替えられる。

プラグイン競合の可能性を調べる

特定のプラグインがブロックエディターの動作に干渉して、カスタムHTMLブロックの描画を阻害しているケースもある。特にエディター拡張系のプラグインや、セキュリティ目的でスクリプトをフィルタリングするプラグインが入っている場合は、すべてのプラグインを一度無効化して標準テーマに切り替え、問題が再現するか確認する。プラグインが原因であれば、1つずつ再有効化して犯人を特定する。

カスタムHTMLブロックを正常に表示させる具体的な修正手順

カスタムHTMLブロックを正常に表示させる具体的な修正手順

原因が特定できたら、次は実際にブロックを正常に表示させる。script タグや複雑な HTML 構造が原因だった場合、以下のアプローチで回避できる。

STEP 1 原因となっているタグを特定する(script タグなど)
STEP 2 script タグはカスタムHTMLブロックの外に出す
STEP 3 複雑なHTMLはACFのフィールドやウィジェットで管理する
STEP 4 コードエディターモードで編集する運用に切り替える

script タグや iframe はカスタムHTMLブロックではなく適切な場所に配置する

Gutenberg のカスタムHTMLブロックは、セキュリティ上の理由から script タグの実行を制限している。また、ビジュアルエディターでの再レンダリング時に script タグを含むブロックを空として扱う挙動が確認されている。JavaScript を埋め込みたい場合は、カスタムHTMLブロックではなく、functions.php に wp_enqueue_script で登録するか、専用のコード埋め込みプラグインを使う。iframe も同様に、エディターのプレビューで空白になることがあるため、フロントエンドのみで描画される仕組みを検討する。

閉じタグのない空要素を見直す

カスタムHTMLブロックに <div></div> のような中身のない空タグや、閉じタグを省略した要素が含まれていると、Gutenberg のブロックパーサーが構造を正しく解釈できずにブロック全体をスキップすることがある。空の div や span は削除するか、&nbsp; を入れて実体を持たせる。とくに WordPress の自動整形機能(wpautop)が余分な p タグや br タグを挿入することで、意図しない空要素が生まれることもある。

複雑なHTML構造はカスタムフィールドやショートコードに置き換える

テーブルやフォーム、装飾を多用したマークアップは、カスタムHTMLブロック1つにまとめるよりも、ACF(Advanced Custom Fields)のテキストエリアフィールドや、ショートコード化して出力する方が安定する。とくにクライアントが自分で編集する前提のサイトでは、カスタムHTMLブロックを直接触らせると今回のようなトラブルが再発しやすい。テーマ側でテンプレートパーツとして管理し、投稿画面では入力欄だけを提供する設計が安全だ。

今後同様のトラブルを防ぐための運用ポイント

今後同様のトラブルを防ぐための運用ポイント

カスタムHTMLブロックに貼り付ける前にコード検証を行う

外部の HTML スニペットをそのまま貼り付ける前に、W3C のバリデーターや VSCode の構文チェック機能でタグの閉じ忘れや文法エラーがないかを確認する。コピー元の Web ページから取得したコードには、不要な属性や非推奨のタグが混じっていることが多い。貼り付け前に一度テキストエディターにペーストし、明らかな問題を取り除いてからブロックに入力する習慣をつける。

WordPress と Gutenberg を最新バージョンに保つ

Gutenberg プラグインを単体でインストールしている場合は、定期的に更新することでブロックパーサーの改善や既知の不具合修正が適用される。コア組み込みのブロックエディターであっても、WordPress 本体のアップデートによってパースエンジンの挙動が改良されることがある。編集画面でカスタムHTMLブロックが空になる現象の一部は、過去のバージョンで修正されたバグに起因している可能性もあるため、まずは最新の状態であることを確認する。

どうしても必要な場合はコードエディターモードを常用する

ビジュアルエディターで空になってしまう HTML をどうしてもページに残したいときは、編集時にコードエディターモードに切り替えて作業する方法が最終的な回避策になる。データベースにコードが正しく保存されているなら、コードエディター表示では常に中身が確認できる。手間は増えるが、複雑なマークアップや埋め込みコードを扱うページでは、あらかじめこの運用を前提にしておくとトラブルが起きても編集が止まらない。

よくある質問

カスタムHTMLブロックの中身は完全に消えたのか

ビジュアルエディターでは空に見えても、コードエディターモードに切り替えると HTML が残っていることがほとんどだ。データベースの post_content にも保存されているため、失われたわけではない。

プラグインをすべて無効化しても直らない場合はどうすればいいか

テーマの functions.php や使用中の子テーマがエディターの動作に干渉している可能性がある。標準テーマ(Twenty Twenty-Five など)に一時的に切り替えて再現するか確認し、テーマ側のフィルターやアクションを調査する。

script タグをカスタムHTMLブロックで使う正しい方法はあるか

原則としてカスタムHTMLブロック内の script タグは推奨されない。管理画面でのレンダリング問題に加え、セキュリティプラグインやサーバー側のフィルターで除去されるリスクもある。どうしても必要な場合はショートコード化するか、wp_enqueue_script でテーマに登録するのが安全だ。

ビジュアルエディターで空白になる特定の HTML タグの一覧はあるか

公式の一覧は存在しないが、script タグ、style タグ、iframe、object、embed、空の div や span、コメントアウト行、複雑に入れ子になったインラインスタイル付き要素などが報告されている。問題が起きたら該当タグを一つずつ検証するのが確実だ。

ビジュアルエディターで空になる現象は Gutenberg のバグなのか

仕様とバグの両面がある。script タグの実行制限はセキュリティ上の意図的な制限であり、空要素のパース失敗はブロックエディターの改善が期待される領域だ。WordPress コアのバージョンアップによって挙動が変わることもあるため、最新バージョンへの更新が有効な場合が多い。

この記事のポイント

  • カスタムHTMLブロックが空に見えてもデータはデータベースに残っている
  • script タグや空要素、閉じタグ省略がパース失敗の主原因
  • コードエディターモードで中身を確認し原因タグを特定する
  • 複雑な HTML はカスタムフィールドやショートコードで管理する
  • WordPress と Gutenberg の最新化で改善するケースがある
2026年5月ウェブ標準 CSS疑似クラスや遅延読み込み新機能まとめ

2026年5月ウェブ標準 CSS疑似クラスや遅延読み込み新機能まとめ

2026年5月、Chrome 148、Firefox 151、Safari 26.5が安定版としてリリースされた。CSSの疑似クラスやコンテナクエリ、メディア要素の遅延読み込みといった使い勝手を大きく左右する機能群がBaselineへと加わっている。

具体的な変化点は4つだ。開閉状態にスタイルを当てる :open 疑似クラス、名前だけで親を参照できるコンテナクエリ、カスタムプロパティを条件とするスタイルクエリ、そして <video> および <audio> のネイティブ遅延読み込み。これらはすべて、主要ブラウザの最新版で動作するBaseline Newly availableとなった。

この記事では、それぞれの機能が何を解決し、実際のコードでどう使うのか、概観を交えながら見ていく。リリースノートを追いきれていないフロントエンドエンジニアやWeb制作担当者は、この機会にキャッチアップしてほしい。

:open 疑似クラスが Baseline 入り

:open 疑似クラスが Baseline 入り

長らくFirefoxとChromeが対応していた :open 疑似クラスが、Safari 26.5のサポートによりBaseline Newly availableとなった。開閉状態を持つHTML要素を、開いているときだけまとめてスタイリングできる疑似クラスだ。

具体的には <details><dialog><select> といった要素に加え、カラーピッカーや日付ピッカーなどの <input> も対象になる。これまでは details[open] のように属性セレクタで個別に書く必要があったが、より読みやすく一貫性のあるコードにまとめられる。

:open 疑似クラスが解決するもの

従来の手法では、開閉のインタラクションを表現するために要素ごとに異なるセレクタを書く必要があった。たとえば <details> には details[open]<dialog> には dialog[open] を使う。しかし :open 疑似クラスなら、これらをひとつのセレクタで扱える。

この変化は、コードのメンテナンス性を大きく改善する。とくにデザインシステムを構築するチームでは、コンポーネントの状態管理がシンプルになる利点が大きい。

従来の書き方(Before)
details[open] {
  background: #f0f0f0;
}

dialog[open] {
  background: #f0f0f0;
}
※要素ごとにセレクタを個別に書く必要があった
改善後の書き方(After)
:open {
  background: #f0f0f0;
}
※ひとつのセレクタで開状態を横断的に扱える

このデモで示したように、:open 疑似クラスを使うと開状態の記述が一箇所に集約される。複数箇所に散らばっていたスタイルを一元管理でき、意図しないスタイル崩れも防ぎやすくなる。

活用シーンと注意点

実務では、FAQのアコーディオンやモーダルダイアログのスタイル定義で即座に役立つ。フォーム部品のピッカーUIにも適用されるため、一貫したブランド表現が可能だ。

ただし、すべての開閉要素が対象になるわけではない。<summary> をクリックして開く <details> のように、ブラウザが開閉状態をネイティブに管理する要素に限定される。JavaScriptで独自に開閉を管理するUI部品には反応しない点に注意が必要だ。

名前のみのコンテナクエリ

名前のみのコンテナクエリ

Chrome 148のリリースにより、名前のみのコンテナクエリ(name-only container queries)がBaseline Newly availableになった。コンテナクエリを書く際に、サイズやスタイルの条件を省略してコンテナの「存在」だけを条件にできる。

これまでは container-type プロパティでコンテナの種別を宣言し、かつ @container ルール内でサイズ条件を指定する必要があった。今回の変更で、単に名前でコンテナを参照するだけのクエリが書けるようになり、コードの冗長さが大きく減る。

名前だけでコンテナを参照する仕組み

具体的なコードを見てほしい。従来は「サイドバーという名前のコンテナが、ある幅を超えたら」というクエリが中心だった。新しい構文では「サイドバーという名前のコンテナがあるなら」という条件だけでスタイルを切り替えられる。

/* コンテナの名前を付与 */
#container {
  container-name: --sidebar;
}

/* サイズ条件なしで名前だけで参照 */
@container --sidebar {
  .content {
    padding: 2rem;
  }
}
従来のコンテナクエリ(Before)
container-type: inline-size;
container-name: –sidebar;

@container –sidebar (min-width: 300px) { … }
※container-type とサイズ条件が必須だった
名前のみのコンテナクエリ(After)
container-name: –sidebar;

@container –sidebar { … }
※サイズ条件なしでコンテナの存在を参照できる

この構文によって、container-type の宣言が不要になるケースが増える。名前の指定だけでコンテナを参照したい場面では、CSSの記述量が減り、可読性も上がる。

実務での活用ポイント

大規模なサイトでは、レイアウトのコンポーネント化が進んでいる。コンテナクエリは「親コンポーネントの状態で子のスタイルを決める」設計と相性が良く、名前のみの参照はこの流れを加速する。

たとえば「サイドバーがDOM上に存在するならカードのパディングを変える」といった、レイアウトの有無に応じた条件分岐が簡潔に書ける。メディアクエリでは制御しきれなかったコンポーネント単位のレスポンシブが、より直感的に扱えるようになる。

コンテナスタイルクエリとカスタムプロパティ

コンテナスタイルクエリとカスタムプロパティ

Firefox 151で style() クエリのサポートが加わり、カスタムプロパティを条件とするコンテナスタイルクエリがBaseline Newly availableとなった。これにより、サイズ以外の親コンテナのCSSプロパティを条件にスタイルを切り替えられる。

とりわけ大きな意味を持つのは、カスタムプロパティ(CSS変数)を条件に含められる点だ。たとえば --theme という変数が dark のときに子要素の背景色を変える、といったテーマ切り替えをCSSだけで完結できる。

カスタムプロパティを条件にしたクエリの実例

以下は、親コンテナで定義された --theme: dark というカスタムプロパティを検知し、子の .card にダークモード用のスタイルを適用するコードだ。

@container style(--theme: dark) {
  .card {
    background-color: #1a1a1a;
    color: #fff;
  }
}
親コンテナ: –theme: light
カードタイトル
ライトテーマのカードコンテンツ
親コンテナ: –theme: dark(検知)
カードタイトル
ダークテーマのカードコンテンツ
–theme: light(検知対象外)  –theme: dark(styleクエリが発火)

この仕組みを使えば、JavaScriptに依存せずにテーマの切り替えが可能だ。CSS変数を用いた設計基盤が整っているプロジェクトであれば、追加のスクリプトなしでダークモード対応の精度を上げられる。

サイズクエリとの使い分け

サイズクエリは「コンテナの幅が300pxを超えたら」といったレイアウト制御に強い。一方でスタイルクエリは「テーマ」「状態」「モード」といった意味的な条件に向いている。

両者は競合するものではなく、補完関係にある。たとえば「サイドバーが存在し、かつダークテーマのとき」にスタイルを変える、といった複合的な条件設計も可能になる。コンテナクエリ全体がBaselineへと進んだことで、CSSの表現力は確実に一段階上がったと言える。

video と audio のネイティブ遅延読み込み

video と audio のネイティブ遅延読み込み

Chrome 148で <video><audio> 要素に loading="lazy" 属性が導入された。これにより、画像やiframeと同じく、メディア要素をビューポート付近まで読み込まない動作をブラウザネイティブで制御できる。

サイトのファーストビューに動画を置くケースは増えているが、初期ロードでユーザーの帯域を圧迫する問題は長年の課題だった。この機能はJavaScriptのIntersection Observerを使った手動実装を、宣言的な属性ひとつで置き換える。

実装と効果

実装はきわめてシンプルで、<video> タグに loading="lazy" を追加するだけだ。特別なポリフィルやライブラリは不要で、対応ブラウザであればそのまま動作する。

<video src="hero.mp4" loading="lazy" controls></video>
loading=”lazy” なし(Before)
ページ読み込み直後 すべての動画リソースを先読み
※帯域を圧迫し、LCPが悪化する
loading=”lazy” あり(After)
ビューポート接近時 必要なタイミングで読み込み開始
※初期ロードの負荷が下がり、帯域を節約できる

効果は数値にも表れる。Squarespaceのエンジニアリングチームが公開した記事によれば、ネイティブ遅延読み込みによって動画の初期リクエスト数が大幅に減り、LCP(Largest Contentful Paint)の改善に貢献したという。詳細は同チームの技術記事「How To Use Standard HTML Video and Audio Lazy-Loading on the Web Today」を参照してほしい。

対応範囲と今後の展望

Chrome 148でサポートが始まったこの機能は、今後のブラウザ展開によってBaseline化が期待される。FirefoxやSafariの動向はまだこれからだが、loading="lazy" の属性自体は画像やiframeですでに確立された仕組みであり、メディア要素への拡張も自然な流れと言える。

未対応ブラウザでは属性が無視されるだけで壊れないため、今すぐ実装してもリスクは少ない。動画を多用するポートフォリオサイトやLPでは、とくに導入効果が大きい。

Document Picture-in-Picture API とその他のアップデート

Document Picture-in-Picture API とその他のアップデート

CSS以外でも重要な進展があった。Firefox 151でDocument Picture-in-Picture APIがデスクトップ向けに導入され、Web Serial APIもFirefoxデスクトップとChrome Androidでサポートが拡大されている。

Document Picture-in-Picture API の概要

従来のPicture-in-Picture APIは <video> 要素を常に前面の小窓で表示する機能だった。一方、Document Picture-in-Picture APIは任意のHTMLコンテンツを含むウィンドウを常に最前面に表示できる。

これにより、ビデオ会議の参加者グリッドや株価ティッカー、タイマーといったインタラクティブなオーバーレイを、ページ遷移後も維持できるようになる。デスクトップ向けのプログレッシブウェブアプリ(PWA)でとくに威力を発揮するAPIだ。

Web Serial API のプラットフォーム拡大

Web Serial APIは、マイクロコントローラーや3Dプリンター、開発ボードといったシリアルデバイスとウェブサイトが直接通信するための仕組みだ。Firefoxでは専用のサイト権限アドオンを導入することで安全に管理できる設計になっている。

Chrome 148ではAndroid向けにもサポートが拡大され、モバイルデバイスからシリアル機器を制御するユースケースが現実的になった。IoT分野や教育用途での活用が今後広がると見られている。

この記事のポイント

  • 2026年5月のブラウザ安定版で、複数のCSS機能とHTML属性がBaseline Newly availableに到達した
  • :open 疑似クラスで開閉状態のスタイリングが一元的に書けるようになった
  • 名前のみのコンテナクエリにより、サイズ条件なしで親コンテナの存在を参照できる
  • style() クエリでカスタムプロパティを条件としたテーマ切り替えがCSSだけで実装可能
  • <video><audio>loading="lazy" でメディアの遅延読み込みがネイティブ化され、初期ロードの負荷が軽減される
2026年4月のBaseline新機能、contrast-color関数やsearch要素が利用可能に

2026年4月のBaseline新機能、contrast-color関数やsearch要素が利用可能に

2026年4月のBaseline月次ダイジェストが公開された。新たに利用可能になった機能として、CSSのcontrast-color()関数やJavaScriptのMath.sumPrecise()メソッドがある。合わせて、search要素やARIA属性リフレクションなど、すでに広く使える段階に達した機能も紹介されている。

今回のアップデートは、アクセシビリティ対応と開発効率の両面で重要な節目だ。ブラウザが自動的に最適な色を算出したり、セマンティックな構造をネイティブに解釈したりする機能が揃い、従来はカスタム実装に頼っていた領域が標準化されつつある。

この記事では、2026年4月のBaselineダイジェストの内容をもとに、新機能の具体的な使い方と、それが開発現場にもたらす変化を解説する。

Baselineとアクセシビリティをめぐる2026年の動向

Baselineとアクセシビリティをめぐる2026年の動向

web.devの記事では、A11y Upが公開した「Baseline and accessibility in 2026」という分析が紹介されている。この分析の核心は、アクセシビリティ対応をウェブ標準に委ねることで、開発の堅牢性と効率が大きく向上するという主張だ。

これまで多くの開発チームは、スクリーンリーダー対応やキーボードナビゲーションといったアクセシビリティ機能を、カスタムのJavaScript実装で再現してきた。しかし、そうした手作りのソリューションは往々にして壊れやすく、支援技術との相性問題を抱え、メンテナンスコストも高かった。

Baselineは、ある機能が主要ブラウザで相互運用可能になった時点を知らせる指標として機能する。この指標を活用すれば、開発者は標準機能への移行タイミングを判断しやすくなる。結果として、ブラウザが自動的に正しいセマンティクスをスクリーンリーダーに伝えてくれるため、開発者が手作業で調整する負担が減るというわけだ。

従来のアプローチ(カスタム実装依存)
開発者 手作りJSでアクセシビリティ実装 支援技術 誤動作・破損のリスク
⚠ メンテナンスコストが高く、壊れやすい
Baseline標準に則ったアプローチ
開発者 標準のsearch要素を使用 ブラウザ 自動でARIAロールを割り当て
✅ 堅牢でメンテナンスフリー

このデモが示すように、カスタム実装に頼る旧来の手法から、標準化された要素やAPIに移行することで、アクセシビリティの品質が安定し、開発者の負荷も低減する。

Baselineで新たに利用可能になった機能

Baselineで新たに利用可能になった機能

2026年4月の時点で、主要ブラウザ(Chrome、Firefox、Safari)すべてがサポートを開始し、Baseline newly available(新規利用可能)と位置づけられた機能が2つある。CSSのcontrast-color()関数と、JavaScriptのMath.sumPrecise()メソッドだ。

CSSのcontrast-color()関数

contrast-color()は、指定した背景色に対して最も読みやすい対照色(通常は黒か白)をブラウザが自動的に算出するCSS関数だ。動的なテーマエンジンやカスタマイズ可能なコンポーネントを扱う際、開発者がこれまで手作業で管理してきた「背景色に応じた文字色の切り替え」という負担を大幅に軽減する。

具体的な動作として、関数にベースとなる色を渡すと、ブラウザのエンジンがその色の輝度を評価し、最もコントラスト比が高い色を返す。これにより、ユーザーが好みの背景色を選べるUIでも、文字が読みにくくなる問題を自動的に回避できる。

.card-header {
  background-color: var(--dynamic-bg-color);
  /* 背景色に応じて自動的に最適な文字色が決まる */
  color: contrast-color(var(--dynamic-bg-color));
}
背景色 #1a1a2e(暗色)
contrast-color が自動で白文字を選択
コントラスト比 約15.3:1(WCAG AAA達成)
背景色 #fff8e1(明色)
contrast-color が自動で黒文字を選択
コントラスト比 約14.8:1(WCAG AAA達成)

上記のデモはcontrast-color()の概念を示したイメージだ。実際のブラウザでは、この関数が自動的に背景色を分析し、最も読みやすい文字色を適用する。中間的な明るさの背景色に対しては、ブラウザがどちらを選ぶか注意深く確認する必要があるが、大半のケースでは手動の分岐ロジックが不要になる。

Math.sumPrecise()メソッド

JavaScriptで浮動小数点数の合計を計算する際、従来のArray.prototype.reduce()や単純なループでは、丸め誤差が蓄積する問題があった。金融計算やテレメトリデータの集計といった、正確さが求められる場面ではこの誤差が致命的になることもある。

Math.sumPrecise()は、この問題に対処するために設計された静的メソッドだ。数値のイテラブル(配列など)を受け取り、精度を保ったまま安全に合計を返す。

// 従来の方法では浮動小数点誤差が発生する可能性がある
const values = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0];
const preciseTotal = Math.sumPrecise(values);
// 誤差なく正確な合計値を返す

内部的には、標準化された高精度な加算アルゴリズム(Kahan summation algorithmや類似の手法)を用いて、丸め誤差を最小化する。ECサイトの売上集計や、センサーデータの分析など、正確性が重視されるシナリオで特に有効だ。

従来の Array.reduce() による加算
[0.1, 0.2, 0.3].reduce((a,b)=>a+b)
結果: 0.6000000000000001
通貨計算では誤差が問題になる
Math.sumPrecise() による加算
Math.sumPrecise([0.1, 0.2, 0.3])
結果: 0.6
正確で信頼できる

この関数を使うことで、フロントエンドでの計算結果に対する信頼性が一段上がる。特に数値の正確さがビジネス上の要件に直結するアプリケーションでは、導入を検討する価値が高い。

Baselineで広く利用可能になった機能

Baselineで広く利用可能になった機能

以下の機能は、すでに主要ブラウザで長期間サポートされ、Baseline widely available(広く利用可能)のステータスに達した。実質的にどのプロジェクトでも安心して採用できる段階だ。

search要素

HTMLのsearch要素は、検索フォームやフィルタリング機能といった、サイト内の検索体験を構成する要素群を明示的にラップするためのコンテナだ。従来はdivやformタグで代用されていたが、search要素を使うことでアクセシビリティ上の利点が生まれる。

具体的には、ブラウザがsearch要素に対して暗黙的にARIAランドマークロール「search」を割り当てる。これにより、form要素にrole=”search”を手動で付与する必要がなくなる。スクリーンリーダーのユーザーは、このランドマークを頼りに検索インターフェースへ素早く移動できる。

<search>
  <form action="/site-search">
    <label for="query">ドキュメントを検索</label>
    <input type="search" id="query" name="q">
    <button>実行</button>
  </form>
</search>
div 要素で検索エリアをマークアップ(非推奨)
<div>
<form role=”search”>…</form>
</div>
role属性の記述が必要。忘れるとアクセシビリティが損なわれる
search 要素でマークアップ(推奨)
<search>
<form>…</form>
</search>
ブラウザが暗黙的に role=”search” を付与。記述の手間と漏れがない

このシンプルな変更だけで、検索機能のアクセシビリティがワンランク向上する。既存のプロジェクトでも、該当するセクションをsearch要素に置き換えるリファクタリングを検討するとよい。

Web Authenticationの公開鍵アクセス

パスワードレス認証を実現するWeb Authentication(WebAuthn)APIにおいて、公開鍵情報の取り扱いが大幅に簡素化された。AuthenticatorAttestationResponseインターフェースに追加されたgetPublicKey()やgetPublicKeyAlgorithm()といったメソッドを使うことで、開発者が生のバイナリデータを手動で解析する必要がなくなった。

これまで公開鍵を抽出するには、CBOR(Concise Binary Object Representation)やDERエンコーディングといったバイナリ形式を手作業でパースする処理が必要だった。公開鍵の取り出しに失敗したり、アルゴリズムを誤認したりするリスクが常につきまとっていた。新しいメソッドはブラウザが直接プロパティとして公開鍵情報を提供するため、そのような低レイヤの処理が一切不要になる。

パスキー(Passkeys)の普及が加速する中、このAPIの安定化は認証フロー全体の信頼性を一段引き上げる要素だ。

String.prototype.isWellFormed()とtoWellFormed()

JavaScriptの文字列は内部的にUTF-16でエンコードされている。複雑な文字や絵文字の中には、サロゲートペアと呼ばれる2つの16ビットコード単位で表現されるものがある。文字列を途中で切断してしまうと、ペアの片方だけが残った「孤立サロゲート」という不正な文字が生まれる。

isWellFormed()は、文字列に孤立サロゲートが含まれていないかを真偽値で返すメソッドだ。toWellFormed()は、もし不正なサロゲートが見つかった場合、それをUnicodeの置換文字(U+FFFD)に置き換えた新しい文字列を返す。encodeURI()など、不正な文字列が渡されるとURIErrorをスローする関数にデータを渡す前に、これらのメソッドで検証と修正を行うのが主な用途だ。

const rawString = getUserInput();
// 不正な文字が混入していないか確認
if (!rawString.isWellFormed()) {
  // 問題があれば安全な形に修正してから処理を続行
  const cleanString = rawString.toWellFormed();
  const encoded = encodeURI(cleanString);
  // 安全にAPIリクエストなどを実行
}
不正な文字列の処理(従来)
不正文字列 encodeURI() URIError発生
アプリケーションがクラッシュするリスク
isWellFormed / toWellFormed で安全に処理
不正文字列 toWellFormed() 安全な文字列 encodeURI()
例外なく処理が完了

ユーザー入力や外部APIからのレスポンスを扱う場面では、予期せぬデータ不整合による例外発生を未然に防ぐ手段として、これらのメソッドが役立つ。

ARIA属性リフレクション

これまで、ARIA属性の値を更新するにはelement.setAttribute(‘aria-expanded’, ‘true’)のように、DOM属性を文字列で操作する必要があった。ARIA属性リフレクションは、この手順をオブジェクトプロパティへの代入に簡略化する。

ElementインターフェースがariaExpanded、ariaChecked、ariaHiddenといったプロパティを直接公開することで、ドット記法による読み書きが可能になった。これは単なるシンタックスシュガーではなく、UIフレームワークや状態管理ライブラリがアクセシビリティ状態をより正確に追跡し、スクリーンリーダーとの同期を保つうえで重要な基盤となる。

// トグルボタンのアクセシビリティ状態を簡潔に更新
toggleButton.ariaExpanded = toggleButton.ariaExpanded === "true" ? "false" : "true";
従来のsetAttributeによる操作(煩雑)
element.setAttribute(‘aria-expanded’, ‘true’)
element.getAttribute(‘aria-expanded’)
文字列操作のため、タイポや値の形式ミスのリスクがある
リフレクションによる操作(簡潔)
element.ariaExpanded = “true”
element.ariaExpanded
プロパティとして直感的にアクセス可能

ReactやVueのようなフレームワークで状態とARIA属性を紐付ける際、従来の文字列ベースの操作に比べてコードの見通しが格段に良くなる。特に複雑なUIコンポーネントを構築するチームにとって、採用するメリットは大きい。

この記事のポイント

  • contrast-color()関数で、背景色に応じた文字色の自動選択が可能になった
  • Math.sumPrecise()で浮動小数点数の正確な合計計算を実現
  • search要素が広く利用可能になり、アクセシビリティ対応が容易に
  • WebAuthnの公開鍵抽出がメソッド一発で完了するように簡略化
  • ARIA属性リフレクションで、状態管理と支援技術の同期が強化