Schwebende Elemente innerhalb eines Div schweben außerhalb von Div. Warum?

274

Angenommen, Sie haben eine div, geben Sie eine bestimmte widthund setzen Sie Elemente hinein, in meinem Fall eine imgund eine andere div.

Die Idee ist, dass der Inhalt des Containers dazu divführt, dass sich der Container divausdehnt und ein Hintergrund für den Inhalt ist. Aber wenn ich das mache, divschrumpft der Inhalt, um zu den nicht schwebenden Objekten zu passen, und die schwebenden Objekte sind entweder ganz heraus oder halb raus, halb rein und haben keinen Einfluss auf die Größe der großen div.

Warum ist das? Gibt es etwas , was ich bin fehlt, und wie kann ich Einzelteile erhalten schwebte die auszustrecken heighteines enthält div?

DavidR
quelle

Antworten:

397

Am einfachsten ist es, overflow:hiddendas übergeordnete Div anzuziehen und keine Höhe anzugeben:

#parent { overflow: hidden }

Eine andere Möglichkeit besteht darin, das übergeordnete div zu schweben:

#parent { float: left; width: 100% }

Ein anderer Weg verwendet ein klares Element:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

CSS

span.clear { clear: left; display: block; }
Doug Neiner
quelle
17
Es funktioniert, aber jetzt bin ich doppelt so verwirrt: Gibt es eine Erklärung dafür oder ist es einfach so?
DavidR
7
Ja, es gibt eine Erklärung, aber ich habe sie inzwischen vergessen :( Es ist einfach so, wie es ist. Das overflow:hiddenzwingt den Browser so gut es geht, die
untergeordneten
5
Ich denke, die Erklärung dafür overflow: hiddenist hier: Link . Und vielen Dank, es hat bei mir funktioniert
Vikas Arora
6
@DavidR Die einfachste Erklärung ist, dass HTML / CSS eine veraltete, schlecht durchdachte und schlecht implementierte Technologie ist. Tatsächlich erklärt diese Argumentation viele HTML / CSS-Macken, auf die Sie zweifellos gestoßen sind, seit Sie diesen Beitrag verfasst haben.
Geringfügige
1
Denken Sie daran, dass overflow: hiddennur Teile eines Elements ausgeblendet werden, die aus dem übergeordneten Container herausfließen. Für mich führte dies dazu, dass bestimmte Textteile nicht mehr lesbar waren.
Top Cat
160

Grund

Das Problem ist, dass schwimmende Elemente nicht mehr fließen :

Ein Element wird als nicht fließend bezeichnet, wenn es schwebend, absolut positioniert oder das Wurzelelement ist.

Daher sie haben keine Auswirkungen auf Elemente als umgebende in Strömungselement würde.

Dies wird in 9.5 Floats erklärt :

Da sich kein Float im Flow befindet, fließen nicht positionierte Blockboxen, die vor und nach dem Floatbox erstellt wurden, vertikal, als ob der Float nicht vorhanden wäre. Die aktuellen und nachfolgenden Zeilenfelder, die neben dem Float erstellt werden, werden jedoch nach Bedarf gekürzt, um Platz für das Randfeld des Floats zu schaffen.

Geben Sie hier die Bildbeschreibung ein

Dies wird auch in 10.6 Berechnung von Höhen und Rändern angegeben . Für „normale“ Blöcke ,

Es werden nur Kinder im normalen Fluss berücksichtigt (dh schwimmende Boxen und absolut positionierte Boxen werden ignoriert […]).

Geben Sie hier die Bildbeschreibung ein

Hacky Lösung: Clearance

Eine Möglichkeit, das Problem zu lösen, besteht darin, ein unterströmendes Element unter allen Schwimmern zu platzieren. Dann wächst die Höhe des übergeordneten Elements, um dieses Element (und damit auch die Floats) zu umschließen.

Dies kann mit der clearEigenschaft erreicht werden :

Diese Eigenschaft gibt an, welche Seiten der Box (en) eines Elements möglicherweise nicht an eine frühere schwebende Box angrenzen.

Geben Sie hier die Bildbeschreibung ein

Eine Lösung besteht also darin, ein leeres Element clear: bothals letztes Geschwister der Floats hinzuzufügen

<div style="clear: both"></div>

Das ist jedoch nicht semantisch. Generieren Sie also besser ein Pseudoelement am Ende des übergeordneten Elements :

.clearfix::after {
  clear: both;
  display: block;
}

Es gibt mehrere Varianten dieses Ansatzes, z. B. die Verwendung der veralteten Einzelpunkt-Syntax :afterzur Unterstützung alter Browser oder die Verwendung anderer Anzeigen auf Blockebene wie display: table.

Lösung: BFC-Wurzeln

Es gibt eine Ausnahme auf das problematische Verhalten zu Beginn definiert: Wenn ein Block Element eines legt Blockforma Context (BFC ist eine Wurzel), dann wird es auch seinen schwebenden Inhalt wickeln.

Gemäß 10.6.7 'Auto'-Höhen für Blockformatierungskontextwurzeln ,

Wenn das Element schwebende Nachkommen hat, deren untere Randkante unter der unteren Inhaltskante des Elements liegt, wird die Höhe erhöht, um diese Kanten einzuschließen.

Geben Sie hier die Bildbeschreibung ein

Wie in 9.5 Floats erläutert , sind BFC-Wurzeln außerdem aus folgenden Gründen nützlich:

Das Rahmenfeld einer Tabelle, ein ersetztes Element auf Blockebene oder ein Element im normalen Ablauf, das einen neuen Blockformatierungskontext erstellt […], darf das Randfeld von Floats im selben Blockformatierungskontext wie das Element selbst nicht überlappen .

Geben Sie hier die Bildbeschreibung ein

Ein Blockformatierungskontext wird von erstellt

  • Blockboxen mit overflowanderen als visiblezhidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
  • Block Container , die Boxen nicht blockieren: wenn displayeingestellt ist inline-block, table-celloder table-caption.

    .bfc-root {
      display: inline-block;
    }
  • Schwimmelemente: Wenn floatgesetzt wird leftoder right.

    .bfc-root {
      float: left;
    }
  • Absolut Elemente positioniert: Wenn positiongesetzt wird absoluteoder fixed.

    .bfc-root {
      position: absolute;
    }

Hinweis die unerwünschte Nebenwirkungen haben kann, wie überfüllt Clipping Inhalt, Berechnen von Autobreiten mit dem Schrumpf-to-fit - Algorithmus, oder wird out-of-flow. Das Problem ist also, dass es nicht möglich ist, ein Element auf Blockebene mit sichtbarem Überlauf zu haben, das einen BFC erstellt.

Display L3 behebt folgende Probleme:

Geschaffen , um die flowund inneren Darstellungsarten zu einer besseren Strömungs Express Layout Anzeigetypen zur Herstellung eines Elements A und ein explizites Schalter zu schaffen BFC Wurzel. (Dies sollte die Notwendigkeit für Hacks wie und […] beseitigen. )flow-root ::after { clear: both; }overflow: hidden

Leider gibt es noch keine Browserunterstützung. Möglicherweise können wir verwenden

.bfc-root {
  display: flow-root;
}
Oriol
quelle
1
Floated Boxes werden also nicht von ihren übergeordneten Containern erkannt, daher der Höhenkollaps, sondern von ihren Geschwistern, daher der Clearfix?
Symlink
@symlink Ja, übergeordnete Container wachsen nicht, um Floats einzuschließen, es sei denn, es handelt sich um BFC-Roots. Geschwister, die keine BFC-Wurzeln sind, sind nicht direkt von Blöcken betroffen (ihre Linienfelder jedoch). Durch das Spiel werden sie jedoch unter den vorherigen Schwimmer verschoben.
Oriol
"Geschwister, die keine BFC-Wurzeln sind, sind nicht direkt von Blöcken betroffen (ihre Linienfelder jedoch)." - Können Sie das bitte klarstellen? Meinen Sie damit, dass in dieser jsFiddle: jsfiddle.net/aggL3Lk7/2 das schwebende Inline-Bild keinen Einfluss auf den Bereich hat (daher überlappt der Rand des Bereichs ihn), aber das Bild wirkt sich auf den Text (der das Linienfeld darstellt) aus, wie gezeigt durch die Tatsache, dass der Text das Bild nicht unterlappt?
Symlink
1
@symlink Ja genau. Nun, in Ihrer Geige gehört die Grenze dem Elternteil, aber für Geschwister wäre es im Grunde dasselbe: jsfiddle.net/aggL3Lk7/3
Oriol
1
Ich stimme zu. Dies sollte die akzeptierte Antwort sein. Es ist interessant für mich, dass der W3 die Art und Weise nennt, wie wir gezwungen sind, einen "Hack" zu codieren. Jemand hat es schlecht gemacht.
DR01D
20

Setzen Sie Ihr Floating div(s)in ein divund in CSS geben Sie overflow:hidden;
es wird es gut funktionieren.

Nad
quelle
Ich habe das versucht, aber es hat mich nicht gelöst: stackoverflow.com/questions/25329349/…
SearchForKnowledge
11

Es fehlt nichts. Float wurde für den Fall entwickelt, dass ein Bild (zum Beispiel) neben mehreren Textabschnitten stehen soll, damit der Text um das Bild herum fließt. Das würde nicht passieren, wenn der Text den Container "dehnen" würde. Ihr erster Absatz würde enden und dann würde Ihr nächster Absatz unter dem Bild beginnen (möglicherweise mehrere hundert Pixel darunter).

Und deshalb erhalten Sie das Ergebnis, das Sie sind.

Lucas Wilson-Richter
quelle
3
Wie hat das etwas damit zu tun, dass das schwebende Element die Höhe des Elternteils richtig ausdehnt?
Geringfügige
11

In einigen Fällen, dh wenn (wenn) Sie nur floatElemente in derselben "Linie" fließen lassen, können Sie diese verwenden

display: inline-block;

anstatt

float: left;

Andernfalls clearfunktioniert die Verwendung eines Elements am Ende, auch wenn es möglicherweise gegen den Strich geht, ein Element zu benötigen, um die CSS-Arbeit auszuführen.

LSerni
quelle
11

Hier ist ein moderner Ansatz:

.parent {display: flow-root;} 

Keine Clearfixes mehr.

ps Überlauf verwenden: versteckt; versteckt den Kastenschatten also ...

anstehender Fuchs
quelle
Funktioniert auch in Safari 11
Pendingfox
7

Danke LSerni, du hast es für mich gelöst.

Um das zu erreichen :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

Das musst du machen :

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>
Flyout91
quelle
4

Wie Lucas sagt, beschreiben Sie das beabsichtigte Verhalten für die Eigenschaft float. Was viele Leute verwirrt, ist, dass float weit über seinen ursprünglichen Verwendungszweck hinausgeschoben wurde, um Mängel im CSS-Layoutmodell auszugleichen.

Werfen Sie einen Blick auf Floatutorial , wenn Sie ein besseres Verständnis davon , wie diese Eigenschaft Werke bekommen möchten.

Sam Murray-Sutton
quelle
0

Sie können es einfach tun, indem Sie zuerst den Div-Flex machen und rechts oder links begründende Inhalte anwenden, und Ihr Problem ist gelöst.

<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">
					<button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>
				</div>

Vijay Tiwari
quelle