ツールバーのオーバーフロー判定ロジックを改善し、不要な表示とSafariのバグを修正
Lexxyのツールバーにおいて、オーバーフローメニューが実際には不要な場合でも表示される問題と、Safariで125%以上のズームレベル時に誤ってオーバーフローが発生する問題を修正しました。
背景
リッチテキストエディタのツールバーでは、ウィンドウ幅が狭くなった際に収まりきらないボタンをオーバーフローメニューに格納する仕組みが一般的です。しかし、#672では以下2つの問題が報告されていました:
- ツールバーのアイテムが実際には収まっているにもかかわらず、オーバーフローメニューが表示される
- Safariで125%以上のウィンドウズーム時に、不正確な
clientWidth値が報告され、誤ったオーバーフロー判定が発生する
技術的な変更
変更前:
#toolbarIsOverflowing() {
return this.scrollWidth > this.clientWidth
}
変更後:
#toolbarIsOverflowing() {
// Safari can report inconsistent clientWidth values on more than 100% window zoom level,
// that was affecting the toolbar overflow calculation. We're adding +1 to get around this issue.
return (this.scrollWidth - this.#overflow.clientWidth) > this.clientWidth + 1
}
変更のポイントは2つです:
オーバーフローメニュー自体の幅を考慮:
this.scrollWidth - this.#overflow.clientWidthとすることで、オーバーフローメニュー要素自体の幅を除外してから比較を行います。これにより、メニューが実際に必要な場合のみ表示されるようになります。Safari対応のための+1マージン:
this.clientWidth + 1として1pxのマージンを追加することで、Safariが高ズームレベル時に報告する不正確なclientWidth値による誤判定を回避します。
設計判断
この修正では、オーバーフロー判定の精度を高めるために2つの要素を考慮しています:
オーバーフローメニュー自体のサイズ考慮: 従来のロジックではscrollWidth > clientWidthという単純な比較でしたが、これはオーバーフローメニュー要素自体もコンテンツに含まれるため、メニューが不要でも表示される原因となっていました。新しいロジックでは、メニューの幅を事前に差し引くことで、「メニューを除いた実際のコンテンツ」が収まるかどうかを判定しています。
ブラウザ実装の差異への対応: SafariのclientWidth計算における浮動小数点の丸め誤差やズーム時の不整合に対して、1pxという最小単位のマージンで対処しています。これはブラウザ間の差異を吸収する実用的なアプローチです。より厳密な判定を行うと、微妙な計算誤差で頻繁にレイアウトが変わってしまう可能性があります。