Chrome 73 によるフレックスレイアウトの崩れの解析と解決方法

Chrome 73 によるフレックスレイアウトの崩れの解析と解決方法

現象

プロジェクトにはネストされたフレックス構造がいくつかあります。

<スタイル>
  /* 一般的なスタイル */
  .カード{
    幅: 200ピクセル;
    高さ: 300px;
    マージン: 20px;
    境界線: 1px 実線 #999;
  }
  .flex {
    ディスプレイ: フレックス;
    flex-direction: 列;
  }
  .ヘッダー{
    フレックス: なし;
    高さ: 40px;
    下部境界線: 1px 実線 #333;
  }
  .スクロール{
    オーバーフロー-y: 自動;
  }
  .p {
    マージン: 10px;
    高さ: 400px;
    背景色: rgba(0, 0, 0, 0.2);
  }  
</スタイル>
  
<!-- レイアウト 1-->
<div class="カードフレックス">
  <div class="header">ヘッダー</div>
  <div class="flex">
    <div class="スクロール">
      <div class="p"></div>
    </div>
  </div>
</div>
  
<!-- レイアウト 2-->
<div class="カードフレックス">
  <div class="flex">
    <div class="header">ヘッダー</div>
    <div class="scroll" style="flex-grow:1;">
      <div class="p"></div>
    </div>
  </div>
</div>

Chrome 73 より前 (Electron を使用 — Chrome 69) では、実際には次のように動作していました。

これらはすべて想定通りの結果です。スクロールはスクロール可能な領域です。ただし、Chrome 73 の表示効果は次のようになります。

親要素の高さが子要素によって引き伸ばされ、スクロール要素がスクロールできなくなります。何?なぜ?

理由

その理由は、仕様書における高さの説明が以下のように簡潔にまとめられているからです。

フレックス アイテムの最小サイズ (主軸に応じて高さまたは幅のいずれか) は、その内部コンテンツのサイズになります。つまり、min-height/min-width のデフォルト値は「auto」です。

えーっと…「標準」を1000回読めば意味が分かると思います。この結論を何度も理解すると、新しいバージョンの Chrome の実装は仕様に準拠しているようです。実際、Chrome の変更は、ブラウザのフレックス レイアウトの動作を仕様に近づけることを目的としています。

Chrome コミュニティにおけるこの問題: Flexbox レンダリングは Chrome 71 と 72 の間で変更され、上記の問題 (レイアウト 2) について白熱した議論が行われ、最終的には公式のロールバックに至りました。

なぜ私たちがこの問題に気づくのが遅く、73 年まで大規模に公開されなかったのかについては、次のハイライトで詳しく説明します。

しかし、規範に従うことは完全に政治的に正しく、すべてが正しいのです!開発者はトレンドに合わせて変化することしかできません。

修理

実際、この現象を見た後、私はそれほどショックを受けませんでした。なぜなら、min-width がすでに私にいくつかの準備レッスンを与えていたからです (詳細については、次のハイライトを参照してください)。それで私はすぐに自分自身を解放する方法を見つけました。

最も外側の伸びている要素を見つけます。上記の 2 つのレイアウトでは、スクロールの直接の親要素です。これに min-height: 0 属性を追加すると、異常なレイアウトを修正できます。

min-height の動作が本当に理解できない場合は、overflow: hidden (non-visible) で同じ効果を実現できます。オーバーフローは通常より頻繁に使用され、次の例に示すように、より物理的な感覚になります。

<div style="height: 200px;overflow: scroll;">
  <div style="height: 400px"></div>
</div>

親要素に overflow:hidden/scroll が設定されている場合、親要素は子要素を表示するときにそのオーバーフロー部分を非表示にします。

もちろん、フレックスレイアウトにおけるオーバーフローの実際の機能は、min-height を 0 に設定することです。

さらに、子要素、つまり上記の例ではスクロール要素に height: 100% を設定することでこれを修正することもできます。しかし、階層が多い場合は、属性を階層ごとに継承する必要があり、環境に優しくありません。

ハイライト

問題は無事解決しました。いくつかエピソードをご紹介します〜

1. クローム 71->72->73

この変更は Chrome 72 で初めて導入されましたが、なぜ Chrome 73 まで気づかなかったのでしょうか? Chrome 72 のリリース後、大きな反響があったため、Chrome は開発者が変更に適応するための時間を増やすために、まず変更をロールバックすることを決定しました。

しかし、Chrome 72 のリリースとその後の 72 へのロールバックは旧正月の休暇中に行われ、ユーザーからのフィードバックはほとんどありませんでした。私のような中国の開発者は、この警告にまったく気づきませんでした。 。 。

2. 最小幅の幼児教育

なぜ私は min-width によって事前に教育を受けていると言うのでしょうか?

エディターに似たタブを実装しました。

ネストされたフレックス水平レイアウトがこちらです。デフォルトのスタイルでは、スクロール領域は子要素によって引き伸ばされます。このとき、min-width: 0 という書き方を初めて体験しましたが、当時は非常に奇妙だと思いました。

では、なぜその時点で親要素の min-width を明示的に宣言する必要があるのでしょうか?また、今回のアップグレードによって発生した事故はすべて、垂直レイアウトのフレックスで発生しました。水平レイアウトのフレックスには影響がありますか?

答えは実はかなりばかげています。なぜなら、Chrome の min-width のデフォルト値は、非常に初期の段階から仕様に沿って「auto」に設定されていたからです。 。 。

参照する

  1. Flexboxは内部要素の高さを0に設定します
  2. MDN 最小高さ
  3. MDN 最小幅

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

<<:  Vueでシングルサインオンを実装する方法のまとめ

>>:  Tomcatでcatalina.batがUTF-8に設定されている場合、コンソールに文字化けした文字が表示されます

推薦する

Linux ネットワークプログラミング機能の簡単な分析

目次1.ソケットを作成する2. ソケットをバインドする3. 聞き手を作る。聞く4. 接続が受け入れら...

Ubuntu 18.04 が VMware 仮想マシンでネットワークに接続できない問題の解決策

仮想マシン内のUbuntu 18.04がネットワークに接続できない問題の解決策は次のとおりですVMw...

Day.js をベースにした JavaScript での日付処理のよりエレガントな方法

目次day.js を使用する理由モーメントデイ.js day.js がなければどうなるでしょうか? ...

docker-compose を使用して MySQL を実行する方法

ディレクトリ構造 。 │ .env │ docker-compose.yml │ └─mysql ├...

CUDA8.0とCUDA9.0はUbuntu16.04で共存します

序文Github にある以前のコードには、CUDA 8.0 環境が必要なものもあります。初心者の場合...

MySQL ステートメントの概要

目次1. データベースの使用を選択2. 情報を表示する3. テーブルを作成する4. データを挿入する...

Linux で gdb を使用してコア ファイルをデバッグする方法

1.コアファイルプログラム実行中にセグメンテーション エラー (コア ダンプ) が発生すると、プログ...

Zabbix で複数の JVM プロセスを監視する方法

1. シナリオの説明:私たちの環境ではマイクロサービスを使用しています。各プログラムには個別のプロセ...

MySQL 文字列連結と null 値の設定のためのインスタンス メソッド

#文字列連結 concat(s1,s2); テーブル内の last_name と first_nam...

Windows で Nginx を使用して https サーバーとリバース プロキシを構成する際の問題

リクエストロジックフロントエンド --> https経由でnginxをリクエストnginx -...

Dockerはコンテナにポートを動的に公開します

コンテナのIPアドレスを表示するdocker examine <コンテナ名またはID> ...

MySQLでルートユーザーのパスワードを変更する方法

方法1: SET PASSWORDコマンドを使用する mysql> username@loca...

js での Object.create インスタンスの使用法の詳細な説明

1. Object.create() メソッドを使用して新しいオブジェクトを作成し、既存のオブジェク...

Nginxを使用してストリーミングメディアサーバーを構築し、ライブブロードキャスト機能を実現する

前面に書かれた近年、ライブストリーミング業界は非常に人気が高まっています。伝統的な業界でのライブスト...

vue-nuxt ログイン認証の実装

目次導入リンク始めるコードを読み進めてくださいプロキシ設定傍受を要求する異なるプレフィックスを持つイ...