Web プラットフォームの
Interoperabilityを実現する!

Open UIのあゆみとこれから

Burikaigi 2025
saku🌸 / @sakupi01

saku

🤗

Web Frontend Engineer
@Cybozu

🍏 / ☕ / 🌏 > ❤

Web プラットフォームの
Interoperabilityを実現する!

Open UIのあゆみとこれから

問題

Button要素ってどんな見た目?

Button要素ってこんな見た目!

「昔は?」

これぜーーーんぶブラウザネイティブのButton!

昔のButton要素の見た目

ref: Styling form controls | 456 Berea Street

これぜーーーんぶFFのブラウザネイティブButton!

昔のFF Button要素の見た目

これがMacOSのFFのブラウザネイティブButton

昔のMacOSのFF Button要素の見た目

Web UIの抱える課題

1993~1995: Web Form 1.0/HTML 2.0

Web Form 1.0

  • HTMLに最初のForm Controlが提案

HTML 2.0

  • 1995年にHTML Working Groupが設立。HTML標準の基礎となるHTML 2.0が策定
  • Form Controlに関する仕様も盛り込まれる
  • とはいえ、全然詳細は決まってない!どう実装されるか次第!

〜古今Input要素仕様比較〜

Form Controlの見た目

  • Form ControlのスタイルはブラウザとOSに依存

Form Controlの見た目

**- Form ControlのスタイルはブラウザとOSに依存

  • IE6またはそれ以前は、Form ControlはOSによってレンダリングされていた
  • ブラウザエンジンによってレンダリングされていなかった
  • 開発者からスタイルの上書きができない/大幅に制限されている

CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental. A future level of CSS may specify this further. - UA Conformance, CSS 2.1 Specification, W3C

1990年代後半: The Browser Wars

  • MSとNetscape間で、サポートする機能の優位性に関する競争が激化。
  • 両ブラウザがWeb標準に対する独自の解釈を持ったまま、独自機能を次々と開発。
    • Bug fixとかは二の次
  • ブラウザ間で一貫性の問題が激しくなる

A beta version of Internet Explorer 5 was then released, and it implemented a new and proprietary dynamic HTML, which meant that professional web developers needed to know five different ways of writing JavaScript.
The history of the Web - W3C Wiki

1990年代後半: The Browser Wars

  • MSとNetscape間で、サポートする機能の優位性に関する競争が激化。
  • 両ブラウザがWeb標準に対する独自の解釈を持ったまま、独自機能を次々と開発。
    • Bug fixとかは二の次
  • ブラウザ間で一貫性の問題が激しくなる

A beta version of Internet Explorer 5 was then released, and it implemented a new and proprietary dynamic HTML, which meant that professional web developers needed to know five different ways of writing JavaScript.
The history of the Web - W3C Wiki

開発者)どっちサポートする?!どの記法学んだらする?!
「Netscapeでは動作するが、IEでは動作しない」
「このサイトは...で表示するのが最適」

Web 標準の台頭

  • WaSP(Web Standards Project)が立ち上がる
  • W3Cの仕様を推奨事項ではなく標準に。仕様に準拠したブラウザ開発が働きかけられる

サポートしないブラウザの後退、またはモダンブラウザの登場

In six months, a year, or two years at most, all sites will be designed with these standards. […] We can watch our skills grow obsolete, or start learning standards-based techniques now.
A List Apart – For people who make websites

2004 ~ 2008: Web 2.0

送り手と受け手が双方向に情報発信できるように変化したWeb

  • Interactivityが向上した、よりリッチなUIが求められるように
  • Webを使用する文化が広がるにつれ、求められるUIパターンも変化

Living Standardの登場と、新しい標準 HTML5

Web2.0の流行に適応する、新たなHTML標準化の動き

  • W3C:HTML5
  • WHATWG(Apple, Mozilla, Opera):HTML Living Standard

Living Standardの登場と、新しい標準 HTML5

  • W3C:HTML5
    • IE, Edge(EdgeHTML時代)
  • WHATWG(Apple, Mozilla, Opera):HTML Living Standard
    • Chrome, Firefox, Safari, Opera, Edge(Chromium)

W3C and WHATWG to work together to advance the open Web platform | 2019 | Blog | W3C

ブラウザやOSに依存したForm Control、守られないW3Cの仕様と、ブラウザ戦争の激化によるWeb開発の限界、それを打開する動きとしてWeb Standards Project、標準に従ったモダンブラウザの実装、Web2.0に適応するHTML標準化開始と2つのHTML標準の対立、そしてLiving Standardへの統合へ。

それからおよそ20年が経とうとしてる

やっとみんな仕様に従ってくれるようになったし、仕様側も進化したけど、

今の仕様ってカンペキ?

今のForm Controlって本当にブラウザやOSへ依存してない?

CSS適用すれば、どこでもおんなじ見た目にできるんだっけ?

Chrome Windows FireFox Windows Safari MacOS Chrome MacOS Chrome Android
Chrome Windows FireFox Windows Safari MacOS Chrome MacOS Chrome Android

ブラウザやOSに依存してる!CSS適用できるやつとできないやつがある!しかも適用できる場所も違う!

Chrome Windows FireFox Windows Safari MacOS Chrome MacOS Chrome Android
Chrome Windows FireFox Windows Safari MacOS Chrome MacOS Chrome Android
✨

It’s time to modernize HTML once again!

✨
✨

It’s time to modernize HTML once again!

✨

It’s time to modernize HTML once again, and standardize the underlying technology needed by web developers to create the most common patterns of form and website-level UI controls. HTML alone won’t be enough, however. New CSS and JavaScript are needed as well. And rather than simply standardize specific interfaces, it’s time to create a more powerful underlying architecture so the creators of web sites and apps can design and build their own ideas for interfaces.

HTMLをもう一度モダナイズし、Web開発者が最も一般的なフォームやウェブサイトレベルのUIコントロールのパターンを作成するために必要な基盤技術を標準化する時が来ました。ただし、HTMLだけでは不十分です。新しいCSSとJavaScriptも必要です。特定のインターフェースを単に標準化するのではなく、Webサイトやアプリの作成者が独自のインターフェースのアイデアを設計して構築できるように、より強力な基盤アーキテクチャを作成する時が来ました。

🚀

Customizable Select Element

🚀

There're so many primitive features coming along.
...aaaaand it's shipping!!!

Anatomy of Customizable Select Element

display not animatable
select {
  /* opt into customizing select */
  &,
  &::picker(select) {
    appearance: base-select;
  }
}
🚀

Dive into the New CSE Features!

🚀

※ CSE = Customizable Select Element

Popover API

<button popovertarget="ex-select">Open</button>

<div popover id="ex-select">Yey</div>
  • Button(popovertarget)を押したら::pickerpopover)がTop Layerで開く
  • ::pickerはLight Dismiss
  • デフォルトでのTabフォーカス管理(popoverを開くと、Tabはpopover内に遷移する、など)
  • ビルトインのキーバインド(Escキーで閉じるCloseWatcher、など)
  • Button(popovertarget)と::pickerpopover)UAによるセマンティクスの関連づけ

fyi: popover属性は、そのままではセマンティックではない。コンテキストに応じた適切なARIAを併用する必要がある

CSS Anchor Positioning (used internally)

<button popovertarget="ex-select">Open</button>
<div popover id="ex-select">Yey</div>

<style>
  button {
    anchor-name: --anchor-btn;
  }
  [popover] {
    position-anchor: --anchor-btn;
    position-area: top center;
  }
</style>
https://github.com/w3c/csswg-drafts/issues/10857
  • Button(アンカー)を起点に、Top Layerの::pickerをどこに表示するのか決められるように
  • ...Invoker Relationship (Shipped in Chrome 133!) / HTML Anchor Attribute 💭

🚧interactivity: inert; (used internally)

select > button:first-child {
  /* Prevents button activation behavior so select can handle events */
  interactivity: inert;
}
ref: https://github.com/w3c/csswg-drafts/issues/10857
  • CSSでInertを実現する
  • Inertにはするが、元々Inertな要素をNon-Inertにはしない
  • inert属性と完全に同じ挙動ではなく、find-in-pageなどの検索機能には影響を与えない
  • CSEでは、独自<button>inertにし、<select>がイベントハンドリングを行えるように

Explainer: CSS Inertness
Implementation for CSE: Revert visibility:inert and implement interactivity:auto/inert (5979839)
Spec Draft: [css-ui-4] Add 'interactivity' property, per #10711 by tabatkins · Pull Request #11178 · w3c/csswg-drafts
Notable Comment: comment

How do we animate the ::picker?

Transition, Animate Keyword Sizes: interpolate-size: allow-keywords;

:root {
  interpolate-size: allow-keywords; /* ✅ opt in to intrinsic-size transition! */
}
select {
  &, &::picker(select) { /* opt in to customizing select */
    appearance: base-select;
  }
  &:not(:open)::picker(select) { /* initial closed picker state */
    height: 0;
  }
  &:open::picker(select) {
    height: auto; /* ✅ Transitions to intrinsic height */
  }
}
  • Intrinsic Size(auto, min/max/fit-content, etc)をTransition, Animationで利用可能にOpt-In!

calc-size()

/* ... opt in to interpolate-size: allow-keywords; ... */
select {
  /* ... opt in to customizing select ... */
  /* ... initial closed picker state ... */
  &:open::picker(select) {
    /* ✅ Transitions to half the intrinsic height: auto; */
    height: calc-size(auto, size * .5);
  }
}
  • automin-contentなどのIntrinsic Sizeを計算した値を指定できるように
display not animatable

CSS Display Module Level 3

transition-behavior: allow-discrete;

/* ... opt in to interpolate-size: allow-keywords; ... */
select {
  /* ... opt in to customizing select ... */
  /* ✅ enable discrete(-ish) transitions in the drop down */
  &::picker(select) {
    transition: display 0.5s allow-discrete, height ease 0.5s;
  }
  /* ... initial closed picker state ... */
  /* ... Transitions to half the intrinsic height: auto; ... */
}
  • 表示/非表示を内部的にdisplayの変更で行っている要素は、display/content-visibilityといった「離散値*1」をアニメーションさせる必要がある
  • ::pickerが閉じる時に、display: none;になるようにアニメーションできるように
  • アニメーション中は要素はinertになってくれる

*1: 厳密には、displaycontent-visibilityoverlayなどは離散値と全く同じ挙動をとるわけではない

Top Layerにいることを示す: overlay: auto;

`::picker`はTop Layerにいる

Animate overlay for Top Layer: allow-discrete for overlay

/* ... opt in to interpolate-size: allow-keywords; ... */
select {
  /* ... opt in to customizing select ... */
  /* enable discrete transitions in the drop down */
  &::picker(select) {
    transition: display 0.5s allow-discrete, height ease 0.5s, 
                overlay 0.5s allow-discrete; /* ✅ Animate overlay for Top Layer! */
  }
  /* ... initial closed picker state ... */
  /* ... Transitions to half the intrinsic height: auto; ... */
}
  • Top Layerに存在することを示すため、overlay: auto;がUAによって設定されている
  • ::pickerが非表示になる時、overlay: auto;からnoneになる ← 離散値のアニメーション!
  • overlayは、基本的にAuthorスタイルシートから触れないが、allow-discreteをつけられたoverlayについてのみ意味のあるCSS

@starting-style

/* opt in to interpolate-size: allow-keywords; */
select {
  /* ... opt in to customizing select ... */
  /* ... enable discrete transitions in the drop down ... */
  /* ... initial closed picker state ... */
  &:open::picker(select) {
    /* .. Transitions to half the intrinsic height: auto; ... */
    /* ✅ set where to enter stage from ! */
    @starting-style {
      height: 0;
    }
  }
}
  • 一連のアニメーションの終わりにoverlay: auto;display: <not-none>;になるので、実質アニメーションされてないように見える
  • ::pickerがTop Layerに現れた(displayが変わりきった)ときの初期値を擬似的に設定する
    • (例)height: 0;を初期値としてTop Layerでアニメーションが始まる

Put it all together!

:root {
  interpolate-size: allow-keywords; /* opt in to intrinsic size transition */
}
select {
  /* opt in to customizing select */
  &, &::picker(select) {
    appearance: base-select;
  }
  /* enable discrete value transitions in the drop down */
  &::picker(select) {
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete,
      height ease 0.5s;
  }
  &:not(:open)::picker(select) {
    height: 0;
  }
  &:open::picker(select) {
    height: calc-size(auto, size * 0.5); /* Transitions to half the intrinsic size */
    @starting-style { /* set where to enter stage from */
      height: 0;
    }
  }
}

View Transition for Element

@starting-styleや離散値の遷移を駆使してTop Layerとのアニメーションを実現する代わりに、特定のDOM要素の追加や削除に対してView Transitionを適用するのも一手!

Customizable Select Element

There're so many primitive features coming along! 🤩

Popover API / CSS Anchor Positioning / interactivity: inert / Transition, Animate Keyword Sizes interpolate-size: allow-keywords; / calc-size() / transition-behavior: allow-discrete; / Animate overlay for Top Layer / @starting-style

Customizable Select Element

There're so many primitive features coming along! 🤩

Popover API / CSS Anchor Positioning / interactivity: inert / Transition, Animate Keyword Sizes interpolate-size: allow-keywords; / calc-size() / transition-behavior: allow-discrete; / Animate overlay for Top Layer / @starting-style


Light DOM Manipulation from UA (First time in the whole HTML history!) / Timing of Cloning for the <selectedcontent> element / :open pseudo-class / appearance: base-select; to turn on CSE features / Default Style Definition / <select> Parser Relaxation ... aaaand more!✨

まとめ

20年で実現した差分

2005 2025
Select Box 1995 Select Box 2025

Check out Open UI Advent Calendar 2024 for more!🎄

Open UI Advent Calendar 2024
✨

Are we ready for Next Generation Web UI?

✨

ご清聴ありがとうございました!

Thank you!

Appendix