web-dev-qa-db-ja.com

CSS:要素をフローティングするときのマージン崩壊の問題に対するクリーンな解決策

HTML + CSSの例:

<html>
  <body style="padding: 0; margin: 0;">
    <div style="float: right;">first</div>
    <div style="margin-top: 2em;">second</div>
  </body>
</html>

望ましい動作:firstdivはウィンドウの右上に浮かんでいます。 実際の動作:目的の位置から2em下に浮きます。 理由:マージンの崩壊

問題を特定したにもかかわらず、私が思いつく解決策はハックのように感じます。

  • bodyスタイルをmargin: -1px 0 0 0; border-top: 1px solid;に変更します。
  • firstの前に<div style="height: 1px; margin-bottom: -1px;"></div>を挿入します
  • 上記の<div>firstsecondの間に挿入します

この問題を回避するためのクリーンで慣用的な方法はありますか?

22
jameshfisher

overflow: hidden;bodyに追加すると、問題が解決するはずです。この記事で説明されているように、新しいブロックフォーマットコンテキストを定義します: オーバーフローの魔法:非表示

jsFiddle DemobodyタグはjsFiddleによって自動的に追加されるため、HTMLマークアップに含めていません)

[〜#〜] update [〜#〜](thx to @clairesuzy):bodypadding: 0がある場合、このソリューションは機能しません。より良い方法が見つかるまで、2つのdivの周りにラッパーを追加することを提案することしかできません(少なくとも今は@Marcelのダウンウォートに値します:))。これは、OPによって投稿されたソリューションよりもクリーンだと思います。私は通常、フロートされたもののラッパーを追加します(ほとんどの場合、古いブラウザーの処理が容易になります)。論理的および意味的に必要なため、ほとんどの場合、意図的に追加する必要はありません。

だから今のところ、私はこれを思い付くことができます:

<body style="padding: 0; margin: 0;">
   <div id="container" style="overflow: hidden;">
       <div style="float: right;">first</div>
       <div style="margin-top: 2em;">second</div>
   </div>
</body>

jsFiddleデモ

UPDATE 2:よく考えてコメントを読んだ後、コンテナのoverflow: hidden(またはoverflow: visible以外のもの)が正しい解決策だと本当に思います。それが機能しなかった唯一の例外は、body要素に設定することです。これは、とにかく非常にまれな状況です。これらのまれな状況では、フローティングの代わりにposition: absolute; top: 0; right: 0;を使用してみることができます。

別の可能な回避策:bodydisplay: inline-block; width: 100%;を設定すると実際に機能することもわかりました。

jsFiddleデモ

22
kapa

親にdivこれを追加します#parent {padding 1px 0; }これは私にとって大きな問題であり、解決策を見つけるのに永遠に時間がかかりました。私は2年のような投稿で見ました、そしてこれは崩壊を修正します。

2
user2127170

解決

htmlタグとbodyタグの両方にoverflow: auto;またはoverflow: hidden;またはoverflow: scroll;を追加します。

理由を知りたい場合

bodyタグにブロックフォーマットコンテキスト(BFC)を作成します。

overflow: hidden;bodyにのみ追加すると機能しないのはなぜですか?

理由は次のとおりです。

W3C#block-formatting

フロート、絶対配置された要素、ブロックボックスではないブロックコンテナ(インラインブロック、テーブルセル、テーブルキャプションなど)、および「可視」以外の「オーバーフロー」を持つブロックボックス(その値がビューポートに伝播された場合を除いて)コンテンツの新しいブロックフォーマットコンテキストを確立します。

W3C#overflow

UAは、ルート要素に設定された「オーバーフロー」プロパティをビューポートに適用する必要があります。

ルート要素がHTML「HTML」要素またはXHTML「html」要素であり、その要素が子としてHTML「BODY」要素またはXHTML「body」要素を持っている場合、ユーザーエージェントは代わりに「overflow」プロパティを適用する必要があります最初のそのような子要素からビューポートまで(ルート要素の値が 'visible'の場合)。

ビューポートに使用する場合の「visible」値は、「auto」として解釈する必要があります。

値の伝播元の要素には、「可視」の「オーバーフロー」に使用される値が必要です

この場合、the first such child elementおよびThe element from which the value is propagatedbodyタグを参照します。

言い換えれば、bodyの値s htmlプロパティ(overflowまたはvisibleまたはbody)意志のoverflowプロパティはhiddenautoの値である「中にscrolloverflow: hidden;またはoverflow: auto;またはoverflow: scroll;を追加した場合ビューポートに伝播されます。したがって、最初のW3Cの引用によれば、bodyは新しいブロックフォーマットコンテキストを確立しません。

ただし、overflow: hidden;またはoverflow: auto;またはoverflow: scroll;htmlに追加すると、「body」のoverflow値は伝播されないため、新しいブロックフォーマットコンテキストが確立されます。

2
medifle

追加 float: left;2番目のdivに。

フィドル

1
Jawad

W3C仕様では、マージンの折りたたみについて次のように説明しています。

「この仕様では、マージンを折りたたむという表現は、2つ以上のボックス(互いに隣接しているかネストされている場合があります)の隣接するマージン(空でないコンテンツ、パディング、境界領域、またはそれらを区切るクリアランスがない)が組み合わされて形成されることを意味します単一のマージン。」

http://www.w3.org/TR/CSS21/box.html#collapsing-margins

マージンの折りたたみに対処する最善の方法は、マージンが折りたたまれている要素の上部または下部のパディングに1ピクセルを追加することです。

マージンが上で崩壊していた場合..その後:

#element-with-collapsed-margin {
   padding-top:1px;
}

またはborder-topもこれを修正します

#element-with-collapsed-margin {
   border-top:1px solid transparent;
}

下マージンが折りたたまれている場合は、padding-bottom:1px;またはborder-top:1pxsolidを追加します透明;

基本的に、上部または下部の境界線またはパディングは、マージンが上下にある場合、またはマージンが崩壊している要素が互いにネストされている場合でも、マージンが崩壊するのを防ぎます。

良い参考資料:

http://reference.sitepoint.com/css/collapsingmargins

..

1

overflow:hiddenが適切でない場合に使用できるもう1つのトリック:

.clr:before, .clr:after {
    display: table;
    content: " ";
    clear: both;
    font-size: 0;
}

このスニペットには、すべてのフロートも含まれるという副作用があります。

1
Henry Chan

奇妙かもしれませんが、ChromeおよびMozillaの新しいバージョンでは、ボーダー付きのラッパーdivを追加することで、目的の動作を実現できます(最初のdivは右上にあります)。

<html>
  <body style="padding: 0; margin: 0;">
    <div style="border: 1px solid black">
        <div style="float: right;">first</div>
        <div style="margin-top: 2em;">second</div>
    </div>
  </body>
</html>
0
user2351934