Firefoxの直近の版で使えるようになったCSSと画像まわりの変更

つくば市のホームページ制作会社

Firefoxは9月29日に157、10月13日に158を公開しました。MDNの開発者向けリリースノートを読むと、派手さはないものの、サイト制作の現場で効いてきそうな変更がいくつか並んでいます。ここでは、ふだんのサイト制作や運用に関わりそうなものを順に拾ってみます。

その1 JPEG XL画像が既定で表示されるようになった

Firefox 158で、JPEG XL形式(image/jxl)の画像が既定で表示されるようになりました。JPEG XLは使用料のかからない画像形式で、非可逆と可逆の両方の圧縮、透過、アニメーション、HDRに対応しています。既存のJPEGを画質を落とさずに変換し直せる点も特徴とされています。

あわせて、画像を取りにいくときの既定のAcceptヘッダーにimage/jxlが加わり、AVIFの次、WebPの前という並びになりました。サーバー側でAcceptヘッダーを見て配信する形式を切り替えている場合は、この並びの変化が判定に影響しないか一度確かめておくと安心です。

その2 単位の違う値どうしをcalc()で割れる

158では、CSSの型付き算術(typed arithmetic)に対応しました。calc()などの中で、同じ種類の値であれば単位が違っても割り算ができ、その結果は単位のない数になります。この数をほかの種類の値に掛け直すことで、たとえば画面幅と要素の幅の比率から文字の大きさや余白を決める、といった関係づけをCSSだけで書けるようになります。

これまでJavaScriptで寸法を測って計算していた処理の一部が、CSS側に移せる可能性があります。ほかのブラウザの対応状況を見ながら、段階的に取り入れていく類いの機能です。

その3 スクロールの受け渡しだけを許すchain

157では、overscroll-behaviorとその個別プロパティにchainという値が加わりました。内側のスクロール領域の端まで来たときに外側へスクロールを引き継ぐ一方で、ブラウザ標準の跳ね返るような動きは起こさない、という指定です。

モーダルやドロワーメニューの中にスクロール領域があるページでは、端での挙動が気になる場面が少なくありません。既存のautoやcontainと比べて、中間の選択肢が増えたと考えるとわかりやすいと思います。

その4 アットルールの対応を@supportsで確かめる

同じく157で、@supportsの中でat-rule()関数が使えるようになりました。@supports at-rule(@scope) のように書くと、そのアットルールにブラウザが対応しているかを条件にできます。@importのsupports()の中でも使えます。

@scopeのように新しいアットルールを取り入れるとき、対応していないブラウザ向けの書き方を切り分ける手段がこれまで限られていました。条件分岐が素直に書けるようになるので、新しい指定を試すときの心理的な負担が少し下がりそうです。

その5 通知をクリックしたときの移動先を指定できる

158では、Notification()やServiceWorkerRegistration.showNotification()にnavigateという指定が加わりました。通知をクリックしたときに開くURLをあらかじめ渡しておけるので、ページを開くだけのためにクリック時の処理を書く必要がなくなります。157では試験的な扱いでしたが、158で正式に使えるようになっています。

その6 安全でない差し込み方でもjavascript:のURLを外せる

HTMLを安全に差し込むためのHTML Sanitizer APIにも手が入りました。158では、setHTMLUnsafe()のような安全確認を緩めた方法で差し込む場合でも、既定の設定ではhref=”javascript:…”のような属性が取り除かれるようになりました。setHTML()のような安全な方法では、これまでどおり常に取り除かれます。

試験的に入った機能にも目を向けておく

既定では無効ですが、158にはCSSのrandom()関数、角の形を変えるcorner-shape、必要になるまでモジュールの実行を遅らせるimport deferなども試験的に入っています。Speculation Rules APIでは、リンクに少しのあいだカーソルを重ねると先読みを始める段階の指定も試せるようになりました。

どれもすぐ実案件で使うものではありませんが、主要ブラウザの足並みがそろってきた機能から順に、中小企業のサイトでも使える場面が増えていきます。リリースノートを数か月おきに眺めておくだけでも、次の改修で何が使えそうかの見当がつけやすくなります。

主要ブラウザすべてで使えるようになった小さな機能たち

つくば市のホームページ制作会社

Googleのweb.devが毎月まとめている「ウェブプラットフォームの新機能」の9月版が公開されました。9月はChromeとFirefoxが隔週リリースに移った最初の月で、Chrome 153と154、Firefox 155から157、そしてSafari 27が安定版として出ています。とくにSafari 27の登場で、Chrome、Firefox、Safariの三つがそろって対応した機能、いわゆる「Baseline Newly available」に入ったものが一気に増えました。

派手な新機能というより、これまで回避策で書いていた部分がそのまま書けるようになる、という種類のものが多い印象です。ここでは中小企業のサイト制作で出番がありそうなものを選んで紹介します。

その1 遅延読み込み画像のsizesを自動にできる

loading="lazy" を付けた画像で、sizes 属性に auto を指定できるようになりました。ブラウザが実際に表示される幅を見て、srcset の候補から適切な画像を選んでくれます。Chrome、Firefoxに続いてSafari 27が対応したことで、三つのブラウザがそろいました。

レスポンシブ画像の sizes は、レイアウトを変えるたびに書き直しが必要で、正直なところ正確に保守されていない現場も多いはずです。WordPressのように画像の表示幅がテーマやブロックによって変わる環境では、とくに恩恵がありそうです。

その2 読んでいる途中で画面がずれにくくなる

Safari 27でスクロールアンカリングが有効になり、overflow-anchor プロパティにも対応しました。スクロールアンカリングとは、見えている範囲より上で要素が増えたり減ったりしたときに、スクロール位置を自動で補正して、読んでいる場所が飛ばないようにする仕組みです。

広告枠や後から読み込まれる埋め込み、Cookie同意の帯などで本文がずれる問題は、スマートフォンでよく起きます。Safariが加わったことで、iPhoneの利用者にも同じ補正が効くようになりました。特定の要素を補正の基準から外したいときは overflow-anchor: none を指定します。

その3 ダークモードで画像も切り替えられる

light-dark() 関数は、これまで色の値にしか使えませんでした。今回、背景画像やグラデーションといった画像の値も指定できるようになり、Safari 27の対応で三つのブラウザがそろっています。ロゴや装飾の背景を、明るい表示と暗い表示で出し分けたい場合に、メディアクエリを書き分けずに済みます。

関連して、Firefox 157では alert() や confirm() のダイアログ、日付や色の選択画面、フォームの入力候補の一覧が、ページの明暗の設定に合わせて表示されるようになりました。ダークモード対応のサイトで、ブラウザ標準の部品だけ白く浮いてしまう違和感が少し減りそうです。

その4 色の透明度だけを変えるalpha関数

CSS Color 5の alpha() 関数も、Firefox 155とSafari 27の対応で三つのブラウザがそろいました。元の色をそのままに、透明度だけを変えた色を返す関数です。たとえば、サイトのブランドカラーを変数で持っておき、半透明の重ね色として使いたいときに、別の色の値を用意しなくて済みます。

配色を変数で管理しているテーマなら、色の追加や変更があっても半透明の派生色が自動で追従するので、手直しの手間が減ります。

その5 直前の指定だけを取り消すrevert-rule

CSS全体に使えるキーワードとして revert-rule が加わり、こちらもSafari 27で三つのブラウザがそろいました。いま書いているルールがなかった場合の値に戻す、という働きをします。既存の revert はブラウザ標準などの段階まで戻し、revert-layer は一つ前のカスケードレイヤーまで戻すので、それよりも細かい単位で取り消せるわけです。

他社が作ったテーマや、プラグインが出力するCSSの上から調整をかけるとき、上書きの上書きを重ねるより見通しのよい書き方ができるかもしれません。

使い始める前に確かめておきたいこと

「Baseline Newly available」は、主要ブラウザの最新版がそろって対応したという意味で、古い端末やOSの更新が止まったiPhoneでは動かないことがあります。上で挙げた機能の多くは、対応していないブラウザでは単に無視されるだけなので、見た目が多少変わる程度で済むものから取り入れるのが無難です。sizesの自動指定や overflow-anchor はその代表で、既存のサイトに足しても壊れにくい部類に入ります。

web.devのまとめには、このほかSafari 27でのカスタマイズ可能な <select> への対応や、ベータ版に入ったCSSの新機能なども並んでいます。毎月の一覧を眺めて、手元のサイトで書いている回避策が不要になっていないか確かめる習慣は、地味ですが効き目があります。

更新のたびに横へずれる数字はCSSの指定ひとつで止まる

つくば市のホームページ制作会社

料金表や集計の画面を作ったとき、データもレイアウトも正しいのに、なぜか数字の並びが落ち着かないと感じたことはないでしょうか。金額の列の右端がそろわない、カウンターの値が変わるたびに行全体が少し横に揺れる。海外のフロントエンド制作者が公開している記事で、この見慣れた違和感の正体と直し方があらためて整理されていました。

原因はCSSでもデータでもなく、フォントが標準で出してくる数字の形にあるそうです。多くのフォントでは数字が文字と同じように幅を変えて並び、1は0より細く詰められます。文章の中ではこれが自然ですが、縦にそろえたい表や、その場で値が切り替わる表示では、桁の幅が毎回変わるため列が崩れたり数字が踊ったりします。

フォントに眠っている別の数字を呼び出す

解決策は font-variant-numeric: tabular-nums; の指定です。MDNの解説によると、これはOpenTypeの tnum に対応する値で、すべての数字を同じ幅にそろえます。字形そのものは変わらず、同じ大きさの枠に一つずつ収まるので、金額の列は右端がきれいに並び、タイマーや在庫数のように刻々と変わる値も横に動かなくなります。記事の著者は、表や数値のパネル、カウンターに入る数字にはとりあえず付けておく、という使い方を勧めていました。

同じ記事では、ほかの切り替えも紹介されています。文章中の数字を小文字のように上下に出入りさせて行になじませる oldstyle-nums、「1/2」と打った文字を本物の分数の形にする diagonal-fractions、ラベルを太さを保ったまま小さな大文字にする font-variant-caps: small-caps です。分数の指定は日付のような斜線の入った数字まで巻き込むので、分数の部分だけを span で囲んで適用するのがよい、という注意も添えられていました。

ブラウザの対応についての心配はほとんどありません。MDNでは font-variant-numeric は2020年1月から主要ブラウザで使える状態とされています。一方で落とし穴もあり、著者によるとGoogle Fontsで配信される可変フォントの多くは、容量を減らすために旧来の数字の形や分数などを省いているとのことです。指定しても見た目が変わらないときは書き方の誤りではなく、フォントのファイルにその字形が入っていない可能性があります。字形が無い場合も普通の数字で表示されるだけなので、表示が壊れることはありません。

日本語のサイトでは、本文の数字が和文フォントの字形で表示されることも多く、フォントによって効き方が変わります。中小企業のサイトでも、料金表や営業時間、実績の数値を並べたページは意外と多いものです。見出しや本文を変えずに数字の部分だけ整えられるので、既存サイトの手直しのついでに、使っているフォントで tabular-nums が効くかを一度確かめておくと、表まわりの印象が少し締まるはずです。

リンクの下線の長さをCSSだけで整えられるようになった

つくば市のホームページ制作会社

9月22日に安定版が出たChromeの新版には、見た目の小さな調整に効く機能がいくつか入りました。先日このブログで取り上げた、埋め込みのiframeが中身に合わせて伸びる仕組みもそのひとつですが、今回はその陰に隠れがちなCSSの追加に目を向けます。中心になるのは、下線や打ち消し線の始まりと終わりの位置を調整できる text-decoration-inset というプロパティです。あわせて、スクロールで切り替わる表示につける目印の振る舞いを選べるようになった変更と、ポップオーバーやダイアログの閉じ方の改善も紹介します。

下線の端を内側にも外側にもずらせる

これまで、文字につける下線(underline)や上線、打ち消し線は、表示された文字列とまったく同じ長さで引かれていました。デザインの都合で「下線を少し短くしたい」「左右に少しはみ出させたい」と思っても、text-decoration 側にはその手段がありませんでした。

Chrome for Developersの解説によると、text-decoration-inset は線の始点と終点を文字列の端から調整するためのプロパティです。値には auto、長さ、パーセンテージを指定でき、ひとつの値で両端をまとめて、ふたつの値で始点と終点を別々に指定できます。たとえば次のように書くと、両端が10pxずつ内側に寄ります。

a {
  text-decoration: underline;
  text-decoration-inset: 10px;
}

正の値は線を内側に縮め、負の値は外側に伸ばします。始点と終点に違う値を入れれば、線を左右どちらかに寄せることもできます。見出しの下に短いアクセント線を引く、ボタン風のリンクで線の両端を少し余らせる、といった細かな調整が、線そのものの設定だけで済むようになります。

背景のグラデーションで描いていた下線の置き換え

制作の現場では、マウスを乗せたときに下線が左から伸びてくる演出がよく使われています。従来は、本物の下線ではなく background-image のグラデーションを細く敷いてその幅を動かしたり、::after の疑似要素で線を作ってアニメーションさせたりするのが定番でした。

公式の解説でも、このプロパティを使えば背景のグラデーションや追加の要素に頼らず、文字の装飾線そのもので「線が現れる」効果を作れると説明されています。本物の下線のまま扱えるので、線の太さや色、文字からの距離といった既存の指定と組み合わせやすく、複数行にまたがるリンクでも装飾線として素直に振る舞うことが期待できます。

一方で、今回の情報源はChrome側の発表で、ほかのブラウザでの対応状況は別に確かめる必要があります。対応していないブラウザでは通常の長さの下線になるだけなので、見た目の上乗せとして段階的に取り入れるのが無理のない使い方でしょう。既存サイトの疑似要素による実装を急いで書き換えるより、新しく作るパーツから試すほうが安全です。

スクロールの目印をタブとしても扱える

もうひとつのCSSの変更は、横スクロールのカルーセルなどで使う scroll-marker-group の拡張です。このプロパティは、スクロール領域の前後に目印のまとまりを自動で作るもので、新版ではその振る舞いを links と tabs のふたつから選べるようになりました。

リリースノートによると、既定の links では目印のまとまりがナビゲーション、個々の目印がリンクとして扱われ、Tabキーで順に移動できます。tabs を選ぶと、まとまりがタブの一覧、目印がタブ、中身がタブパネルとして扱われ、Tabキーで止まるのは選択中の目印だけになり、目印の間は矢印キーで移動します。選ばれていないパネルの中身は支援技術からも隠れます。

タブ切り替えのUIを自前で作ると、キー操作や役割の付与まで含めた実装はそれなりに手間がかかります。見た目だけでなく操作の約束事までCSSの指定で選べるのは、アクセシビリティの面でも意味のある変更だと感じます。ただしこちらも対応ブラウザは限られるため、当面はJavaScriptで作った既存のタブを置き換えるより、検証環境で挙動を確かめておく段階だと考えています。

外側を押すと閉じる動作の取りこぼしが減る

同じ版では、ポップオーバーやダイアログの外側をクリックして閉じる動作も見直されました。判定に使うイベントが、押した瞬間と離した瞬間の組み合わせから、クリックのイベントに変わっています。これにより、タッチ画面でのスクロール操作や右クリックで、意図せずポップオーバーやダイアログが閉じてしまうことがなくなるとされています。

スマートフォンでメニューを開いたまま中身をスクロールしようとして閉じてしまう、という問い合わせは小さな会社のサイトでも起こりがちです。ブラウザ側の変更なので制作側の作業は要りませんが、標準のポップオーバーやダイアログを使っている部分は、今後こうした改善が自動的に届く側に回ります。下線の長さのような細部も含めて、手作りしていた部分を少しずつ標準の機能に寄せていくと、保守の手間が軽くなっていくはずです。

埋め込みのiframeが中身の高さに合わせて伸びる仕組み

つくば市のホームページ制作会社

予約フォームやコメント欄、外部サービスの口コミ表示など、サイトに別ページを埋め込む場面ではいまも iframe がよく使われます。そのたびに悩まされるのが高さの問題です。中身が長くなると枠の中にスクロールバーが出てしまい、かといって大きめの固定値にすると下に不自然な余白が残ります。Chrome 154 では、この高さ合わせをブラウザ側に任せられる仕組みが入りました。

これまでの高さ合わせは手作業だった

iframe は既定では自分専用の表示領域を持ちます。埋め込まれた文書がその領域より縦に長ければ、利用者には枠の中にもう一本スクロールバーが見えることになります。ページ全体のスクロールと枠内のスクロールが二重になり、スマートフォンでは特に操作しにくくなります。

これを避けるため、制作現場では埋め込まれた側で中身の高さを測り、postMessage() で親ページへ送り、親ページ側の JavaScript で iframe の高さを書き換える、という手順を組むのが定番でした。Chrome for Developers の解説でも、今回の機能はこのよくある実装を置き換えるものと位置づけられています。外部サービスが配布する埋め込みコードに、高さ調整用のスクリプトが一緒に付いてくるのもこのためです。

この方法は動きますが、送る側と受け取る側の両方にコードが要り、送信元の確認を怠ると関係のないページからのメッセージで高さを変えられてしまうおそれもあります。小さなフォームひとつのために毎回これを書くのは、正直なところ手間でした。

親ページと埋め込み側の双方で宣言する

新しい仕組みでは、親ページ側で iframe に frame-sizing という CSS プロパティを指定します。縦方向に伸ばしたい場合は次のように書きます。

.embed {
  width: 100%;
  frame-sizing: content-height;
}

ただし、親ページが指定するだけでは有効になりません。埋め込まれる文書の側も、head に専用の meta 要素を置いて「中身の大きさに合わせてよい」と同意する必要があります。

<meta name="responsive-embedded-sizing" content="allow-origins=*">

frame-sizing には、従来どおりの動きを保つ auto のほか、content-width、content-height、content-inline-size、content-block-size が用意されています。横書きのサイトで縦に伸ばしたい埋め込みなら、content-height か content-block-size を使う場面がほとんどになりそうです。max-height: 80vh のような既存の CSS の制約と組み合わせることもできるので、長くなりすぎる中身に上限を設けておくこともできます。

中身が後から変わるときの扱い

ブラウザは埋め込み先のレイアウト変更を常に監視しているわけではありません。「もっと見る」でコメントを追加読み込みしたり、折りたたみを開いたりして中身が変わったときは、埋め込まれた側で window.requestResize() を呼んで計算し直しを求めます。解説によると、文書の変更をひととおり済ませてから呼ぶのがよいとされています。枠の大きさが変わると表示領域が変わり、それが中身を変え、また大きさが変わる、という繰り返しを避けるために、あえて明示的に呼ぶ形にしているそうです。

別ドメインの埋め込みでは許可先を絞る

この仕組みは、別ドメインから読み込む iframe でも使えます。その場合、埋め込まれる側の meta 要素で、高さ合わせを許す親ページのオリジンを指定できます。

<meta name="responsive-embedded-sizing" content="allow-origins=https://publisher.example">

複数のオリジンを許す場合は空白で区切って並べます。解説では、外部向けのウィジェットでは必要なオリジンだけに絞るよう勧めています。また、この指定はどのサイトが自分のページを埋め込めるかを決める Content Security Policy の frame-ancestors とは役割が別で、それを補う位置づけとされています。埋め込みを許すかどうかと、中身の大きさを親に伝えてよいかどうかは、分けて考えるということです。

自社で予約フォームや問い合わせフォームを別システムで動かし、複数のサイトに埋め込んでいるような構成なら、allow-origins=* で済ませず、実際に埋め込むドメインを書いておくのが無難です。

今の実装を残したまま試せる

現時点でこの機能を使えるのは Chrome 154 以降で、他のブラウザでの対応はこれからです。そのため、すぐに従来の高さ調整スクリプトを外すことはできません。解説では、@supports を使って対応ブラウザだけで新しい指定に切り替える書き方が紹介されています。

.widget {
  width: 100%;
  height: 500px;
}

@supports (frame-sizing: content-height) {
  .widget {
    height: auto;
    frame-sizing: content-height;
  }
}

埋め込まれた側でも、"requestResize" in window で有無を確かめてから呼べば、未対応のブラウザでエラーになることはありません。既存の postMessage() による調整を代替手段として残しつつ、対応ブラウザでは新しい仕組みに任せる、という段階的な移行がしやすい設計です。

WordPress で外部フォームや予約システムを埋め込んでいるサイトでは、埋め込み元のサービスがこの meta 要素に対応しないと親ページ側だけでは使えません。自社で埋め込み用のページを用意している場合は、まずそちらに meta 要素を入れて Chrome で挙動を見ておくと、他のブラウザが追いついたときにスクリプトを外す判断がしやすくなりそうです。iframe の高さという地味ながら長年の手当てが必要だった部分が、標準の書き方に置き換わっていく流れとして、覚えておいて損はないと思います。

スクロールバーの色指定を標準側に寄せる頃合い

つくば市のホームページ制作会社

サイトの一部に横スクロールの表や、高さを決めたお知らせ欄を置くと、スクロールバーの色をデザインに合わせたいという話がよく出ます。そのとき長く使われてきたのが、::-webkit-scrollbar で始まる一連の擬似要素です。9月15日に公開されたFirefox 156では、この古い書き方の扱いが少し変わりました。目立たない変更ですが、既存サイトのCSSを見直すきっかけになりそうなので紹介します。

Firefox 156で変わった判定の結果

MDNの開発者向けリリースノートによると、Firefox 156では @supports selector(::-webkit-scrollbar) という条件が、すべてのサイトで偽を返すようになりました。反対に @supports not (selector(::-webkit-scrollbar)) は真になります。

背景には、Firefox 155で入った仕組みがあります。設定で指定された一部のドメインに限って、Firefoxは ::-webkit-scrollbar の指定を実際に反映しています。156でもその反映自体は続きますが、対応しているとは答えなくなりました。リリースノートの説明では、多くのサイトがこの判定を関連する擬似要素一式が使える合図として扱っている一方、Firefoxは -thumb や -track といった仲間の擬似要素には対応していないため、とされています。

結果として、標準のスクロールバー指定を @supports not (selector(::-webkit-scrollbar)) の中に書いていたサイトでは、Firefoxでもその指定が適用されるようになります。

標準の指定はすでに主要ブラウザで使える

標準側の手段は、scrollbar-color と scrollbar-width の二つのプロパティです。MDNの scrollbar-color のページでは、2025年12月から主要ブラウザの最新版でそろって使える機能(Baseline 2025)として扱われています。

書き方は単純で、scrollbar-color に色を二つ並べると、最初がつまみ(サム)、二つ目が溝(トラック)の色になります。ルート要素に指定すれば、ページ全体のスクロールバーにも効きます。一方の ::-webkit-scrollbar はどの標準にも含まれない独自仕様で、つまみや上下のボタンまで細かく作り込めるかわりに、ブラウザによって効いたり効かなかったりします。

注意したいのは両者の優先関係です。MDNによると、ある要素の scrollbar-color や scrollbar-width の計算値が auto 以外だと、ブラウザはその要素の ::-webkit-scrollbar 系の指定を無視します。しかも scrollbar-color は継承されるため、親要素に色を指定しただけで、子の要素に書いた独自スクロールバーが効かなくなることがあります。その要素で scrollbar-color: auto を指定し直せば、独自の見た目が戻るとされています。

既存サイトで確かめておきたい書き方

MDNが紹介している代替の書き方は、まず @supports (scrollbar-color: auto) で標準プロパティが使えるかを確かめ、使えないブラウザに向けてだけ @supports selector(::-webkit-scrollbar) の中に独自の擬似要素を書く、という二段構えです。標準を先に置き、古い書き方を補助に回す形なので、今回のFirefoxの変更とも食い違いません。

見直しの対象になりやすいのは、以前に作ったテーマやページ単位の追加CSSで、Firefoxだけを別扱いにするつもりで ::-webkit-scrollbar の判定を分岐に使っているケースです。判定の前提が変わったので、Firefoxで見た目が変わっていないか一度開いて確認しておくと安心です。スクロールバーを display: none で消している箇所があれば、ブラウザごとに同じように消えているかもあわせて見ておきたいところです。

色を変える前に考えたいこと

MDNは、スクロールバーの見た目はなるべく既定のままにしておくよう勧めています。見慣れた形から離れると、使い勝手が損なわれやすいためです。変える場合は、つまみと溝の色の差を十分にとること(コントラスト比3対1が目安)、独自に作り込むなら指で触れる大きさを確保することが挙げられています。なお、ハイコントラスト表示のような強制カラーモードでは、scrollbar-color は自動的に auto に戻ります。

中小企業のサイトでも、ブランドカラーに合わせてスクロールバーまで塗りたいという要望は珍しくありません。色を合わせる程度なら、今は標準の二つのプロパティで十分に届きます。細かな作り込みは古い擬似要素に任せるとしても、土台を標準側に置いておくほうが、今回のようなブラウザ側の変更にも振り回されにくくなるはずです。

Safariの新版が前面に出したのは不具合修正だった

つくば市のホームページ制作会社

WebKitのブログに、Safariの新しいバージョンで入った変更をまとめた記事が出た。日付は9月17日。冒頭に置かれているのは新機能の一覧ではなく、今回いちばん大きな機能は機能ではない、という一文だった。1年かけて既存機能の不具合を844件直した、という話が中心に据えられている。6月の開発者向けイベントの時点では525件と発表していたので、そこからさらに6割ほど積み増したことになる。

修正はいくつかの筋に整理されている。ひとつは互換性で、特定のサイトでヒンディー語の入力が正しく通らない、検索結果から画像が消える、といった個別の不具合を地道に潰していったもの。もうひとつは土台の作り直しで、JavaScriptのモジュール読み込み処理を新しく書き直し、CSSのzoomも作り直し、行内要素の配置をサブピクセル単位で行うようにしたという。深掘りの筋ではSVGだけで66件の修正が入り、SMILアニメーションの実装は端から端まで見直された。表組みの絶対配置まわりや、HTTPキャッシュがCache-Controlの指定にきちんと従うかどうかといった、仕様との食い違いを詰める作業も含まれている。

目を引いたのは、組み合わせという括りがあることだ。-webkit-line-clampがWebKitに入ったのは2010年、text-wrap: balanceは2024年で、どちらも単体では問題なく動く。ところが同じ要素に両方を指定すると、行のバランス調整のほうが効かなくなっていたという。それが今回直った。単体では再現せず、組み合わせたときだけ崩れる。制作の現場で原因の切り分けにいちばん時間を取られるのは、だいたいこの種類の不具合ではないだろうか。

読んでいる位置が飛ばなくなる

新しく入った機能のなかで、既存のサイトにそのまま効きそうなのがスクロールアンカリングだ。記事を読んでいる途中で、いま見ている位置より上に画像や広告、コメントが遅れて読み込まれると、読んでいた部分が下に押し出されて画面が急に飛ぶ。よくある挙動だが、読み手にとっては行き先を見失う原因になる。新しいSafariはこの場合にスクロール位置のほうを自動で調整し、読んでいた場所を画面上の同じところに保つ。制作側で何かを書き足す必要はなく、既定で有効になっている。挙動を切りたい箇所だけ、overflow-anchorというCSSプロパティにnoneを指定する形だ。

ブラウザの更新というと、新しい書き方が使えるようになったかどうかに目が行きやすい。ただ、納品してしばらく経ったサイトの表示が、こちらが何もしなくても静かに正しくなっていくというのは、保守を抱える側にとっては地味に大きい。Safariでだけ表示が少しずれるという理由で回避策を入れた案件が手元にあるなら、新しい版で一度素の状態に戻して確かめてみる価値はある。回避策は放っておくと、いつのまにか誰も理由を説明できないコードになる。

コンテナクエリが知られているのに使われない理由

つくば市のホームページ制作会社

CSSのコンテナクエリ(container queries)が主要ブラウザにそろってから、それなりの時間がたちました。部品が置かれた場所の広さに合わせて見た目を変えたい、という要望は長年のCSSの願いごとの上位にあったはずです。ところが、実際の制作現場ではまだあまり使われていません。

Smashing Magazineが9月16日に公開した記事は、この「知られているのに使われない」状態を正面から取り上げています。筆者は、使われない理由よりも、使われたときの使い方のずれに関心を向けています。今回はこの記事を軸に、MDNの解説も参照しながら、メディアクエリとの役割分担や、手を出す前に知っておきたい落とし穴を整理してみます。

認知は高いのに利用が伸びていない

記事によると、コンテナクエリのブラウザ対応率はおよそ94%に達しています。一方で、State of CSSの調査では、存在を知っている開発者が86%なのに対し、実際に使っているのは41.4%にとどまるそうです。筆者自身も調査には偏りがあると断ったうえで、現時点で最も参考になる指標だとしています。

また、今年のSmashingConf Amsterdamでは、CSSの解説で知られるKevin Powell氏も普及の遅さに触れたと紹介されています。新機能というより、すでに使える道具が棚に置かれたままになっている状況といえます。

筆者が指摘するのは、コンテナクエリが見た目のうえでメディアクエリとよく似ていることです。書き方が似ているので、同じ目的で同じように動くものだと思い込みやすい。その結果、メディアクエリの置き換えとして試し、違いが分からないまま離れていく、という流れが起きやすいのだと考えられます。

外を見るメディアクエリ、内を見るコンテナクエリ

記事の整理はシンプルです。メディアクエリが確かめているのは、基本的に画面(ビューポート)の幅です。たとえば幅1024px以上でカードを横並びにする指定をしたとします。このカードを、1920pxの画面の中で幅300pxしかないグリッドの一枠に置いても、画面幅の条件は満たしているので横並びの指定が効いてしまい、中身が窮屈になったりはみ出したりします。

コンテナクエリは問いの立て方が違います。確かめるのは、その部品を包んでいる親要素にどれだけの幅があるかです。次のように親要素をコンテナとして宣言し、その幅を条件にします。

.card-wrapper {
  container-name: card;
  container-type: inline-size;
}

@container card (min-width: 450px) {
  .card {
    display: flex;
    flex-direction: row;
  }
}

こうするとカードは画面の広さに左右されず、置かれた場所に450px以上の横幅があるときだけ横並びになります。MDNも、コンテナクエリを使えば、同じカードをページのどこに置くかを意識せずに再利用できると説明しています。

記事は、現在のウェブには2,300種類を超える画面サイズがあるという数字も挙げています。768pxのような抽象的な境目を越えたから「タブレット用」の見た目になる、という考え方そのものに無理が出てきている、というのが筆者の主張です。

ページ全体の骨組みと部品の中身で使い分ける

記事が勧めるのは、どちらか一方に寄せることではなく、担当範囲を分けることです。ページ全体をまたぐヘッダーやフッター、メインのグリッド、ダークモードのような利用者の設定、タッチ操作の有無といった端末の特性は、これまでどおりメディアクエリの担当です。一方、カードやウィジェット、フォーム、ナビゲーションのように、割り当てられた場所に収まる必要がある部品の中身は、コンテナクエリの担当と考えます。

筆者自身の判断基準も分かりやすいものです。ひとつの部品が複数の場所で使われるならコンテナクエリ、ページの最上部に常にあるメインナビゲーションのように、ページ単位でしか存在しない部品ならメディアクエリ。前者は置き場所の広さが毎回違い、後者は画面の幅がそのまま頼れる目安になるからです。

WordPressで制作していると、この区別は実感しやすいはずです。同じ投稿カードや問い合わせボタンの部品が、トップページでは3列に並び、固定ページでは本文の幅いっぱいに置かれ、別の場所ではサイドバーに収まる。画面幅だけで分岐を書いていると、置き場所ごとに例外の指定が増えていきます。納品後に更新担当の方がブロックを並べ替えることを考えても、部品が自分の置かれた幅に応じて整う作りのほうが崩れにくくなります。

文字サイズと折り返しの判定にも使える

記事では、レイアウトの切り替え以外の使いどころも紹介されています。ひとつは文字サイズです。見出しの大きさを画面幅に連動するvw単位とclamp()で決めていると、その部品をサイドバーへ移したときに文字が大きすぎたり小さすぎたりします。コンテナクエリには専用の単位があり、MDNによると、cqwとcqhはコンテナの幅と高さ、cqiとcqbは行方向とブロック方向の大きさ、それぞれの1%を表します。cqminとcqmaxはcqiとcqbの小さいほうと大きいほうです。

.card-title {
  font-size: clamp(1rem, .5rem + 3cqi, 2rem);
}

このように書けば、見出しの大きさは部品が置かれた場所の幅に合わせて伸び縮みし、指定がその部品の中で完結します。なお、MDNでは、当てはまるコンテナが見つからない場合、これらの単位はその方向の小さいビューポート単位として扱われると説明されています。

もうひとつは、フレックスボックスの折り返しを検知する工夫です。CSSには、並んだ要素が次の行へ折り返したかどうかを直接知る仕組みがありません。記事ではKevin Powell氏から学んだ方法として、各アイテム自体をコンテナにし、伸びる設定を与えておくやり方が紹介されています。折り返しが起きると、次の行に落ちたアイテムが親の幅いっぱいまで広がり、その急な幅の変化をコンテナクエリが拾う、という仕組みです。これまでならJavaScriptのResizeObserverに頼っていた場面を、CSSだけで扱える可能性があります。筆者も完全無欠ではないと書いているので、試すときは実際の表示で確かめるのがよさそうです。

手を出す前に知っておきたい落とし穴

記事は、コンテナクエリ特有の注意点も3つ挙げています。

まず、コンテナは自分自身を条件にできない点です。カード要素をコンテナにして、そのカード自身の表示方法を切り替えようとしても動きません。自分の大きさで自分の見た目を変えると、無限に計算し直すことになるからです。そのため、カードの外側にもう一段包む要素を用意し、そちらをコンテナにする必要があります。既存のテーマやテンプレートに後から組み込む場合、この「もう一段の包み」をどこに置くかが最初の検討事項になります。

次に、container-typeにsizeを指定すると高さがつぶれることがある点です。sizeは縦横両方の大きさを条件にできる指定ですが、ブラウザは中身を見ずにコンテナの大きさを決めるため、高さや最小の高さ、縦横比を明示していないと高さが0pxになってしまいます。MDNも、コンテナの宣言には封じ込め(containment)が伴い、それは性能のために必要な仕組みだと説明しています。多くの場合は横方向だけを見るinline-sizeで十分で、縦方向が本当に必要な場面に限ってsizeを選ぶのが無難です。

最後に、条件の値にカスタムプロパティを使えない点です。デザインシステムで境目の幅を変数にまとめている場合でも、コンテナクエリの条件にvar()を書くことはできません。カスタムプロパティは要素の親子関係に沿って値が受け継がれるため、クエリの中でその値自体を書き換えると判定が循環してしまうからです。

スタイルクエリなど周辺の仕様も広がっている

今回のSmashing Magazineの記事が扱っているのは、大きさを条件にするサイズクエリです。MDNの解説を読むと、コンテナクエリの仕組みはそれだけではありません。現在は、サイズクエリ、コンテナの名前だけで絞り込む名前のみのクエリ、スタイルクエリ、スクロールの状態を条件にするクエリ、アンカー配置の状態を条件にするクエリ、の5種類が整理されています。

このうちスタイルクエリは、コンテナの計算済みのスタイルを条件にするものです。MDNによると、現時点で実際に条件にできるのはカスタムプロパティに限られ、通常のCSSプロパティを条件にする書き方はまだどのブラウザにも実装されていません。それでも、親要素に設定したテーマ用の変数の値によって子要素の見た目を切り替える、といった使い方はすでに検討できます。@propertyで型を登録しておくと、blueと#0000ffのように書き方の違う同じ色も一致として扱われる、という細かな挙動も解説されています。対応状況はブラウザごとに差があるので、採用する前に互換性の表を確認しておくのが安心です。

サイズクエリの基本がまだ手に馴染んでいない段階で、周辺の仕様まで一度に追う必要はありません。ただ、部品の置かれた状況をCSS側で判断する方向へ仕様全体が広がっていることは、頭の片隅に置いておく価値があります。

既存サイトへの取り入れ方

中小企業のサイトや地方の制作案件で、いきなり全体をコンテナクエリ前提で組み直す必要はないでしょう。記事の筆者も、すべてのプロジェクトでメディアクエリをコンテナクエリに置き換えるべきだとは考えていないと明言しています。

現実的なのは、置き場所によって崩れやすい部品から試すやり方です。お知らせの一覧カード、商品や事例の紹介カード、サイドバーにも本文にも置かれるバナーなど、同じ部品を複数の場所で使い回しているところが候補になります。こうした部品は、これまで置き場所ごとの追加指定で調整してきたことが多く、その追加指定を減らせるかどうかで効果を判断しやすいはずです。

書き方がメディアクエリに似ているぶん、使い分けの考え方さえ押さえてしまえば導入の壁はそれほど高くありません。ページの骨組みは画面の幅で、部品の中身は置かれた場所の幅で決める。この線引きを一度チーム内で共有しておくと、次のサイト改修のときに部品の作り方を見直すきっかけになりそうです。

回避策で埋めていた部分が標準機能に変わりつつある

つくば市のホームページ制作会社

九月に入ってから、ブラウザ側と WordPress の編集画面側で、更新の発表が重なりました。目立つ新機能というより、これまで回避策でしのいでいた部分が標準の機能に置き換わるものが多く、日々の制作にはむしろこちらのほうが効いてきます。

Chrome は次の版がベータに入り、編集画面まわりも新しい版が公開されています。実務で使えそうなものを並べて見ていきます。

下線の引き方をCSSだけで決められる

Chrome の次の版のベータには、text-decoration-inset と text-decoration-skip-spaces という二つのCSSプロパティが入っています。前者は、下線や上線、打ち消し線を文字の端からどれだけ内側に入れるか、あるいは外側に伸ばすかを指定するものです。auto のほか長さや割合で指定でき、開始側と終了側を別々に書くこともできます。

後者は、装飾の線を空白文字の下で途切れさせるかどうかを決めます。下線の位置を細かく調整したいとき、これまでは背景のグラデーションで線を描いたり、余計な要素を挟んだりして代用していました。文字装飾そのもので済むなら、あとから文字サイズを変えたときの崩れも減ります。

ポップアップが指の操作で勝手に閉じない

popover や dialog には、外側をクリックすると閉じる挙動が標準で備わっています。この判定が押した瞬間と離した瞬間の組み合わせで行われていたため、スマートフォンでポップアップの中身をスクロールしようとした指の動きや、右クリックでも閉じてしまうことがありました。

次の版では判定がクリックそのものに変わり、タッチでのスクロール操作や右クリックでは閉じなくなります。問い合わせフォームや絞り込みメニューをポップアップで出しているサイトなら、入力の途中で消えてしまう取りこぼしが減るはずです。

埋め込み枠の高さを中身に合わせられる

iframe の大きさを中身に合わせる仕組みも入ります。サイト側で明示的に有効にすると、親のページに置いた iframe 要素が、埋め込んだ文書の内容の高さに合わせて広がり、中の文書側にスクロールが発生するのを避けられます。

予約フォームや外部サービスの申し込み画面を埋め込むと、枠の中だけが二重にスクロールする状態になりがちで、これまでは高さを親のページに送り返す処理を自前で書いていました。標準の仕組みでまかなえるなら、埋め込み先ごとに用意していたスクリプトを減らせます。

カルーセルの印にどう振る舞わせるかを選べる

横スクロールで切り替わる領域に付く小さな印をまとめる scroll-marker-group に、links と tabs という二つのモードが加わります。links は既定のモードで、印の並びが案内リンクの一覧として扱われ、それぞれが順番にキーボード移動の対象になります。tabs のほうはタブの並びとして扱われ、選ばれている印だけが移動の対象になって、印の間は矢印キーで動きます。

見た目は同じでも、キーボードや読み上げでの扱いが変わる部分です。ここを自前のJavaScriptで作り込むと支援技術への対応まで自分で面倒を見ることになるので、指定ひとつで役割が切り替わるのは扱いやすいところだと思います。

編集画面では挿入ボタンを探さなくてよくなる

WordPress の編集画面側では、Gutenberg の新しい版でブロックの追加まわりが変わりました。選んでいるブロックによっては追加ボタンが見つけにくく、選択をやり直したり画面をスクロールしたりしていましたが、ブロックのツールバーから直接追加できるようになっています。グループの中に要素を足す、ギャラリーに画像をもう一枚足すといった操作が短くなります。

スタイルまわりでは、個別に上書きした指定が入っているブロックに印が付き、上書きのあるものだけを絞り込んで見られるようになりました。引き継いだサイトで、どこに手が入っているか分からないまま触るのが一番こわいので、一覧できるのは助かります。グループブロックの余白を縦と横で別々に指定できる、theme.json からラベル要素や入力欄、選択欄に指定を書ける、といった細かい追加も入っています。

直っているのは新機能だけではない

Safari の直近の版は、新機能よりも不具合の修正が中心でした。ページの拡大時に ic という文字幅の単位が仕様どおりの値にならない問題、位置指定に position-area を使った固定配置が本文をスクロールできる状態でうまく代替位置に回らない問題、本体のスクリプトが欠けた Service Worker の登録が自動で解除されず、新しいものを登録し直せない問題などが直っています。

この手の修正は告知を追っていないと気づきにくく、原因が分からないまま自分の書き方を疑って時間を使ってしまう部分でもあります。修正の一覧に目を通しておくと、次に似た症状に出くわしたときの見当が付きやすくなります。

こうして並べてみると、自前のスクリプトや回避策で埋めていた部分が、少しずつ標準の側へ移ってきているのが分かります。今あるサイトを急いで書き換える必要はありませんが、次にフォームや埋め込み、横スクロールの領域を作るときには、以前より短い書き方で済まないか一度確かめてみる価値はありそうです。

CSSで書けることが増えた直近のブラウザ更新

つくば市のホームページ制作会社

ブラウザの更新が続いていて、CSSだけで書ける範囲がまた少し広がっている。9月1日に公開されたFirefox 155と、8月にベータ版へ入ったChrome 153では、これまでJavaScriptを挟んで処理していたことや、回避策を組み合わせて実現していた表現が、スタイルシート側に移ってきた。

もちろん、実装されたばかりの指定をすぐ本番で使えるわけではない。ただ、どの方向に進んでいるかを知っておくと、いま組むサイトの設計や、数年後の書き直しの量が変わってくる。直近の更新から、頭の隅に置いておくと役に立ちそうなものを並べてみる。

HTMLの属性値をどのプロパティでも使えるようになった

CSSの attr() 関数は、これまで content プロパティの中でしか使えなかった。疑似要素にHTMLの属性値を文字として流し込む用途に限られていて、幅や時間の指定に使うことはできなかった。

Firefox 155では、この制限が外れて任意のプロパティで使えるようになった。width: attr(data-size px) のように単位を添えた型の指定ができ、値がなかったときのフォールバックや、名前空間つきの属性にも対応している。コンテナスタイルクエリの条件式の中でも使える。

棒グラフの長さや進捗バーの幅のように、データによって変わる数値をテンプレートから渡したい場面は多い。これまではインラインのstyle属性を書き出すか、JavaScriptで後から当てるかのどちらかだったが、data-属性に数値を入れておけばCSS側で受け取れる形になる。

色の透明度だけを差し替えられる関数

同じくFirefox 155で、alpha() 関数が使えるようになった。色を渡すと、他の成分はそのままに透明度だけを変えた色が返ってくる。関数の中では alpha というキーワードで元の色の透明度を参照できるので、alpha(from var(–brand) / calc(alpha * 0.5)) のように、元の値を基準にした計算も書ける。

ブランドカラーを変数でひとつ持っておき、ホバー時の背景や区切り線をそこから派生させる、といった使い方に向いている。色ごとに半透明版を別の変数として用意して二重に管理する、という手間が減らせる。

値の進み具合を数値として返す関数

progress() 関数も同じ更新で入った。開始値と終了値を渡すと、ある値がその間のどのあたりまで進んだかを数値で返す。opacity: calc(0.4 + progress(100cqw, 300px, 900px) * 0.6) と書けば、コンテナの幅が300pxから900pxへ広がるあいだに不透明度が変化していく。

これまでも calc() と clamp() の組み合わせで近いことはできたが、式が長くなって後から読み解きにくかった。どこからどこまで変化させたいのかが、そのまま式の形に出る。

スクロールの軸を分けて指定できるようにする動き

Chrome 153のベータでは、スクロールまわりの指定がふたつ増えている。ひとつは overflow プロパティで、scroll と clip を軸ごとに組み合わせて書けるようになる。overflow: scroll clip のように指定すると、position: sticky の固定範囲を軸ごとに別の祖先要素へ預けられ、clip を指定した側は動かないまま保てる。

もうひとつは scroll-axis-lock という新しいプロパティ。ブラウザは指やホイールの動きが片方の軸に大きく偏ると、その軸だけにスクロールを固定してしまうことが多い。誤操作を防ぐには合理的な挙動だが、地図や大きな図面のように斜めへ動かしたい領域では、固定がかからない角度から操作を始めないといけない、という不便につながる。この指定で、固定しないようブラウザへ伝えられる。

名前が変わったものと、まだ既定で無効なもの

Firefox 155では font-stretch プロパティが font-width という名前に変わった。旧名は別名として引き続き動くが、算出済みスタイルを列挙すると font-width のほうが返るようになっている。スタイルをJavaScriptから読み取って処理しているところがあれば、影響を受けないか確かめておきたい。

一方で、枠線の描画領域に背景を切り抜く background-clip の border-area や、スクロール量に連動するアニメーションは、Firefox 155では既定で無効のままだ。設定を切り替えれば試せるが、検証記事を読むときは、そのまま出荷されたものなのか、設定で有効にして試したものなのかを分けて見ておいたほうがいい。

ここに挙げたものは、いずれも片方のブラウザで実装が進んだ段階で、主要ブラウザで揃うまでにはまだ時間がかかる。中小企業のサイトで今日から使い始める類の話ではない。それでも、属性値や色や進み具合といった、これまでスクリプトに任せていた計算がCSS側へ降りてきているという流れは共通している。手元の案件で、これは本当にスクリプトが要るのかと一度立ち止まってみると、思ったより短く書ける箇所が見つかるかもしれない。