6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnoCSSのバグと Chromeのvar()に注意【OSS入門】

Last updated at Posted at 2025-04-01

要約

  • UnoCSSでバグを発見した: drop-shadow-xxx などのクラスがスタイルに反映されない
  • こちらでissueおよびPRを提出し現在は修正済
  • Chromeでは var() の中身を省略表示することがある

UnoCSSとは

「Atomic CSS エンジン」
=必要とされるスタイルだけ動的に生成する

バグ発覚

一休 Frontend Meetup での発表

2025年2月20日に株式会社一休さん主催のイベント 一休 Frontend Meetup が開催される

自社WebComponentsの開発に UnoCSS を利用していることが発表される

                                       
image.png
『一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜』より

サンプルアプリでのUnoCSS試用

上記講演を受けてVite + React環境でUnoCSS (66.1.0-beta.6) を試用することにした

                                       
image.png
index.htmlではアイコンのホバー中に影が描画される

するとpresetWind4利用時classNameにdrop-shadow-xxxを指定してもシャドーが描画されないことを確認

                                       
image.png
TailwindCSS V4 (右側)では問題なくシャドーが描画される

バグの原因

根本原因は CSS変数のフォールバック が設定されていないことだった

フォールバックとは

var() の第二引数のこと

※ フォールバックは特に正式名称ではない

関数の最初の引数は、置換されるカスタムプロパティの名前です。関数のオプションの 2 番目の引数は、代替値として機能します。最初の引数で参照されるカスタムプロパティが無効な場合、関数は2番目の値を使用します。

<var()> = 
  var( <custom-property-name> , <declaration-value>? )  

var()の仕様

var() に未定義のCSS変数が記載されている場合 CSSプロパティは none を返す

CSSプロパティが無効となる例
filter: var(--undefined-vars) drop-shadow(0 0 35px rgba(0, 0, 255, 0.5))

ただし , 単体でフォールバックしている場合 var() 自体は 空の値 を返す

このときCSSプロパティの値は none にはならない

※ そのCSSプロパティの構文・書式を満たしていることが前提

CSSプロパティが有効となる例
filter: var(--undefined-vars,) drop-shadow(0 0 35px rgba(0, 0, 255, 0.5))

drop-shadow-xxx クラスによって生成されるCSS

TailwindCSS V4 で 出力されるCSSは以下の通り

.drop-shadow-\[0_0_5px_rgba\(0\,0\,255\,0\.5\)\] {
    --tw-drop-shadow: drop-shadow(0 0 35px rgba(0, 0, 255, 0.5));
    
    filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,)
        var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,)
        var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}

上の例ではCSS変数の後ろに , を置きフォールバックを設定することで var() および filter の無効化を回避している

TailwindCSS V4 では filter を扱う際 沢山のCSS変数を用いて制御している

drop-shadow-xxx クラスを使う場合 --un-drop-shadow 以外のCSS変数は未定義であることがほとんどである

よってシャドーを描画させるためにはフォールバックが必要不可欠となる

対して UnoCSS で出力されるCSSは以下の通り

.drop-shadow-\[0_0_5px_rgba\(0\,0\,255\,0\.5\)\] {
    --un-drop-shadow: drop-shadow(0 0 35px rgba(0, 0, 255, 0.5));
    
    filter: var(--un-blur) var(--un-brightness) var(--un-contrast)
        var(--un-grayscale) var(--un-hue-rotate) var(--un-invert)
        var(--un-saturate) var(--un-sepia) var(--un-drop-shadow);
}

「未定義のCSS変数」に対して , によるフォールバックが設定されていない

                                       
image.png
左側では無効な var() により filternone になっている

これにより var() および filter プロパティが無効となり シャドーが描画されなくなる

Chromeの仕様

Chrome DevTools (134.0.6998.178) は
var() の第二引数が空値(, のみ)であるとき var() 内の , を省略して表示する

                                       
image.png
Tailwind CSS の PlayGrounddrop-shadow クラスを利用している場面

Chromeでは drop-shadow クラスのスタイルは上記のように表示される

                                       
image.png
スタイルを選択範囲している場面

この状態でクリップボードにコピーすると見た目通りの値がコピーされる

ここまでは極めて普通のことである

                                       
image.png
filter プロパティを編集するために値をクリックした場面

しかしプロパティの編集モードに切り替えることで 省略されていた第二引数が表示された

この状態になってはじめて , を含めてコピーすることができる

(このChromeの仕様がフォールバック実装漏れの一因になったと推察できる)

image.png

Firefox (136.0.3) では第二引数は省略されない

バグの修正

本事象を受けてUnoCSSにissueおよびPull Request(以下PR)を送付した

コントリビュートガイドの確認

まずは以下2点を確認する

本リポジトリではまずissueを作成すること、その後PR内にissueのリンクを貼ることが通例となっている

またUnoCSSは Anthony Fu さんのリポジトリであるため以下内容も確認する

特に環境構築時やPR作成時に役立つ

issueの作成

[事象/原因/詳細/対処]の見出しを立てて作成した

バグレポート用のissueの補足

  • Reproductionという必須項目が存在する
    ここにはバグを再現した PlayGround のURLを添付する
    • ライトモード・ダークモードそれぞれでテキストが背景色と同化しないようにすると見やすい
    • PlayGround のバージョンを指定するにはURL末尾に #version=66.1.0-beta.6 のように入力してリロードする
  • システム情報は任意項目
    • ただしCSSはブラウザや端末によって挙動や見え方が変化しうるためなるべく記載する

環境構築

基本ガイドラインを頼りに進めていく

今回はnode:23イメージからDockerコンテナ環境を作成した

一通り準備が完了したらvitestで今回の改修箇所のテストが通るか確認する

バグ修正

CSS変数名からあたりを付けて修正→ビルド→playgroundで動作確認 を繰り返す

最後にテストファイルも修正してvitestが通ることを確認する

PR作成

CIが途中で止まるが以下の実行には権限ユーザの承認が必要となる

image.png

ここはただ待つのみである
※ 今回は2~3日後に承認いただいた

その後CIに成功してレビュワーによってマージされれば無事終了となる

まとめ

メンテナーの方にもご協力いただいたことで66.1.0-beta.7以降のUnoCSSでは drop-shadow クラスを正常に使えるようになった

Chromeではスタイル表示時に空値フォールバックを隠してしまうため、 var() の実値を確認する際には一度プロパティ値をクリックすること

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?