1. ホーム
  2. javascript

[解決済み] CSS オーバーフローの hidden と visible が親要素の位置に与える奇妙な効果 [重複] について

2022-03-03 08:02:34

質問

要素の overflow プロパティが要素の配置にこのような奇妙な影響を与えることを示唆する記述を読んだことがありません。

https://codepen.io/kshetline/pen/ZEzLVxN

この例のトグルボタンをトグルすると、なぜか <div> 不思議なことに、コンテンツは画面に対して同じ位置にあるにもかかわらず、前のコンテンツを覆うように上方にスライドします(つまり、コンテンツは親の背景に対して下方に移動しています)。

この例は、私がAngularコンポーネントで行おうとしていることを非常に単純化したものです。 <ng-content> - しかし、この例はCSSとHTMLだけで、関連する変数を分離しようとしているため、JavaScriptはほんの少ししか使っておらず、Angularは使っていません。

コンテンツ を使用すると、HTML 要素を縮小することができます。 transform: scale( 1より小さい倍率 ) しかし、要素のコンテンツが小さく表示されても、デフォルトでは要素のピクセル寸法は同じままです。コンテンツは(特に指定がない限り)要素の中心に向かって縮小し、コンテンツの周囲には空白のスペースが残り、要素は元の縮小されていない寸法のままです。

要素自体が小さくなったと見なすためには、拡大縮小の度合いに合わせて負の余白を計算する必要があります。私もそうしてきましたが、拡大縮小された要素のコンテナにCSSの overflow に設定します。 hidden ネガティブマージンによって取り除かれるはずの余分な空白が、他の要素のレイアウト全体に部分的で説明しにくい影響を及ぼしているような、奇妙な位置関係が発生する可能性があります。

この動作は、Chrome、Firefox、Safari、Edgeで確認されています。したがって、これはCSSの正しい動作だと思いますが、私には理解できません。私は overflow に設定します。 visible これにより、拡大縮小されたコンテンツは、要素の境界で切り取られることなく、フローティングドロップダウンメニューを表示するなどの処理を行うことができます。

let hidden = true;
const inner = document.getElementById('inner')

function toggleOverflow() {
  hidden = !hidden;
  inner.style.overflow = hidden ? 'hidden' : 
  'visible'
}
html, body {
  height: calc(100vh - 10em);
}

.page {
  font: 32px Arial, Helvetica, sans-serif;
  height: calc(100% - 1em);
}

.container {
  background-color: #ACF;
  height: 100%;
}

.outer-wrapper {
  background-color: rgba(187, 255, 204, 0.5);
  font-size: 2em;
  margin: 0 1em;
  position: relative;
}

.inner-wrapper {
  overflow: hidden;
  position: relative;
  width: fit-content;
}

.ng-content {
  margin: -18.75px 0;
  transform: scale(0.5);
}

.container-text {
  display: inline-block;
  position: absolute;
  bottom: 1em;
}
<div class="page">
  <button onclick="toggleOverflow()">Toggle Overflow</button><br>
  Content outside of the<br>
  panel being scaled and its<br>
  containing &lt;div&gt;, 32pt font<br>
  <div class="container">
    <!--Angular component start tag goes here -->
    <div class="outer-wrapper">
      <div id="inner" class="inner-wrapper">
        <div class="ng-content">
          50% scaled content goes here, 64pt font
        </div>
      </div>
    </div>
    <!-- Angular component end tag goes here -->
    <span class="container-text">This is an absolutely positioned &lt;span&gt; in the same &lt;div&gt;</span>
  </div>
</div>

解決方法は?

から CSS 2.2仕様

新しいブロックフォーマットコンテキストを確立する要素(フロートおよび 'visible' 以外の 'overflow' を持つ要素など)のマージンは、それらのインフロー子と共に折り畳まれない。

そのため overflow:hidden は、余白が崩れるのを防いでいます。