Warum wird dieses Inline-Block-Element nach unten gedrückt?

238

Das Folgende ist mein Code und ich möchte verstehen, warum #firstDiv von allen Browsern nach unten gedrückt wird. Ich möchte wirklich das Innenleben der Tatsache verstehen , warum es nach unten gedrückt wird, anstatt es auf die eine oder andere Weise nach oben zu ziehen. (und ich weiß, wie man ihre Tops ausrichtet :))

Und ich weiß, dass es überläuft: versteckt, was es verursacht, aber nicht sicher, warum es dieses Div nach unten drückt.

body {
  width: 350px;
  margin: 0px auto;
}

#container {
  border: 15px solid orange;
}

#firstDiv {
  border: 10px solid brown;
  display: inline-block;
  width: 70px;
  overflow: hidden;
}

#secondDiv {
  border: 10px solid skyblue;
  float: left;
  width: 70px;
}

#thirdDiv {
  display: inline-block;
  border: 5px solid yellowgreen;
}
<div id="container">
  <div id="firstDiv">FIRST</div>
  <div id="secondDiv">SECOND</div>
  <div id="thirdDiv">THIRD
    <br>some more content<br> some more content
  </div>
</div>

http://jsfiddle.net/WGCyu/ .

Shawn Taylor
quelle

Antworten:

360

Grundsätzlich haben Sie Ihrem Code mehr Unordnung hinzugefügt, was zu mehr Verwirrung führt. Daher versuche ich zunächst, Unordnung zu beseitigen, die das Verständnis des eigentlichen Problems behindert.

Zunächst müssen wir feststellen, was die eigentliche Frage ist. Deshalb wird das inline-blockElement " " nach unten gedrückt.

Jetzt beginnen wir es zu verstehen und beseitigen zuerst die Unordnung.

1 - Warum nicht allen drei Divs die gleiche Randbreite geben? Lass es uns geben.

2 - Hat das Floating-Element eine Verbindung zum Inline-Block-Element, das nach unten gedrückt wird? Nein, das hat nichts damit zu tun.

Also haben wir dieses Div komplett entfernt . Und Sie erleben dasselbe Verhalten, wenn das Inline-Block-Element nach unten gedrückt wird.

Hier ist die Literatur an der Reihe , die Idee von Zeilenumbrüchen zu verstehen und wie sie in derselben Zeile angeordnet sind. Lesen Sie den letzten Absatz sorgfältig durch, da dort die Antwort auf Ihre Frage liegt.

Die Basislinie eines 'Inline-Blocks' ist die Basislinie seines letzten Zeilenfelds im normalen Fluss, es sei denn, es hat entweder keine In-Flow-Zeilenfelder oder seine 'Überlauf'-Eigenschaft hat einen anderen berechneten Wert als' sichtbar 'in In diesem Fall ist die Grundlinie die untere Randkante.

Wenn Sie sich über die Grundlinie nicht sicher sind, finden Sie hier eine kurze Erklärung in einfachen Worten.

Alle Zeichen außer 'gjpqy' werden auf die Grundlinie geschrieben. Sie können sich die Grundlinie so vorstellen, als ob Sie eine einfache horizontale Linie zeichnen, die der Unterstreichung direkt unter diesen "zufälligen Zeichen" entspricht. Dann ist dies die Grundlinie, aber wenn Sie jetzt eines von 'gjpqy' schreiben. Zeichen in derselben Zeile, dann würde der untere Teil dieser Zeichen unter die Zeile fallen.

Wir können also sagen, dass alle Zeichen außer 'gjpqy' vollständig über der Grundlinie geschrieben sind, während ein Teil dieser Zeichen unter der Grundlinie geschrieben ist.

3 - Warum nicht überprüfen, wo sich die Basislinie unserer Linie befindet? Ich habe einige Zeichen hinzugefügt , die die Grundlinie unserer Linie zeigen.

4 - Warum nicht auch einige Zeichen in unsere Divs einfügen, um ihre Basislinien im Div zu finden? Hier werden einige Zeichen in divs hinzugefügt, um die Grundlinie zu verdeutlichen .

Wenn Sie sich mit der Grundlinie vertraut gemacht haben, lesen Sie die folgende vereinfachte Version über die Grundlinie von Inline-Blöcken.

i) Wenn für den fraglichen Inline-Block die Überlaufeigenschaft auf sichtbar gesetzt ist (dies ist standardmäßig so, dass keine Einstellung erforderlich ist). Dann wäre seine Grundlinie die Grundlinie des enthaltenden Linienblocks.

ii) Wenn für den fraglichen Inline-Block die Überlaufeigenschaft auf ANDERE ALS sichtbar gesetzt ist. Dann würde sich sein unterer Rand auf der Grundlinie der Zeile des enthaltenen Kastens befinden.

  • Erster Punkt im Detail

Schauen Sie sich das jetzt noch einmal an, um Ihr Konzept zu verdeutlichen, was mit green div passiert . Wenn noch Verwirrung herrscht, werden hier weitere Zeichen in der Nähe von grünem Div hinzugefügt, um die Grundlinie des enthaltenen Blocks festzulegen, und die grüne Grundlinie wird ausgerichtet.

Nun, ich behaupte jetzt, dass sie die gleiche Grundlinie haben? RICHTIG?

5 - Warum überlappen Sie sie dann nicht und prüfen Sie, ob sie richtig zueinander passen? Also bringe ich den dritten Teil links: 35px; um zu überprüfen, ob sie jetzt die gleiche Grundlinie haben ?

Jetzt haben wir unseren ersten Punkt bewiesen.

  • Zweiter Punkt im Detail

Nun, nach der Erklärung des ersten Punktes ist der zweite Punkt leicht verdaulich und Sie sehen, dass der untere Rand des ersten Divs, dessen Überlaufeigenschaft auf nicht sichtbar (versteckt) eingestellt ist, auf der Basislinie der Linie liegt.

Jetzt können Sie einige Experimente durchführen, um dies weiter zu veranschaulichen.

  1. Stellen Sie den ersten Div-Überlauf ein: sichtbar (oder entfernen Sie ihn ganz) .
  2. Stellen Sie den zweiten Div-Überlauf ein: nicht sichtbar .
  3. Stellen Sie beide divs Überlauf: andere als sichtbar .

Bringen Sie jetzt Ihre Unordnung zurück und sehen Sie, ob alles für Sie in Ordnung ist.

  1. Bringen Sie Ihr schwebendes Div zurück (natürlich muss
    die Körperbreite vergrößert werden). Sie sehen, dass es keine Wirkung hat.
  2. Bringen Sie die gleichen ungeraden Ränder zurück .
  3. Setzen Sie grünes Div auf Überlauf: sichtbar, wie Sie es in Ihrer Frage festgelegt haben (diese Fehlausrichtung ist auf die Vergrößerung der Rahmenbreite von 1 Pixel auf 5 Pixel zurückzuführen. Wenn Sie also das negative Links links anpassen, sehen Sie, dass es kein Problem gibt).
  4. Nun zusätzliche Zeichen entferne ich zu Hilfe hinzugefügt zu verstehen . (und natürlich das negative linke entfernen)
  5. Reduzieren Sie schließlich die Körperbreite, da wir keine breitere mehr benötigen.

Und jetzt sind wir wieder da, wo wir angefangen haben.

Hoffentlich habe ich deine Frage beantwortet.

Gary Lindahl
quelle
1
Vielen Dank für diese großartige Erklärung, aber ich habe Ihren Punkt nicht verstanden. "Dann wäre seine Grundlinie die Grundlinie des enthaltenen Blocks der Linie." Entspricht es der Grundlinie der Linie, die Sie im zweiten Punkt deutlich gemacht haben?
Shawn Taylor
2
Späte Antwort. Ich habe gerade das gleiche Problem festgestellt und wollte mich nur bei Gary Lindahl für die NICE-Erklärung bedanken.
TimSPQR
+1 ntgCleaner Obwohl ich gute Antworten schätze, ist Gary Lindahls so viel zu lesen und mir fehlen nur die wenigen Zeilen, in denen 'Solution: XY'
Basic Coder
Ich fand diese ausführliche Erklärung unglaublich informativ, danke. Ich hatte eine Weile mit einem Konzept zu kämpfen und habe eine aktualisierte Geige erstellt, die für andere klarstellen könnte.
jonsanders101
@ntgCleaner danke Mann .. trotz all der Erklärung konnte ich es nicht zum Laufen bringen. aber dein Kommentar hat es geschafft :)
Supersan
329

Der Standardwert für vertical-alignin CSS ist baseline& diese Regel gilt auch für das inline-blockLesen dieser http://www.brunildo.org/test/inline-block.html

Schreiben Sie vertical-align:topin Ihre inline-blockDIV.

Überprüfen Sie dies http://jsfiddle.net/WGCyu/1/

Sandeep
quelle
3
Hast du meine Frage gelesen? Ich habe nie darum gebeten, das Problem zu beheben.
Shawn Taylor
23
@ShawnTaylor: Der Fragentitel ist sehr irreführend. Wir lesen instinktiv den Titel und suchen dann nach dem Code, falls vorhanden. Wir lesen selten den eigentlichen Text. Es ist eine schlechte Angewohnheit, aber Sie sollten wahrscheinlich verstehen, warum es passiert. : P
Purag
@sandeep: in Bezug auf Ihre Bearbeitung dann, warum firstDiv nach oben ausgerichtet ist, auch wenn vertikale Ausrichtung davon entfernt wird
Shawn Taylor
@sandeep: Der von Ihnen angegebene Link ist informativ, hilft aber bei dieser Frage nicht weiter, da er nicht das Verhalten von display:inline-blockkombiniert mit beschreibt float:left/right.
Zeta
2
@ThomasMcCabe Kaum; Wenn jemand eine schlechte Antwort veröffentlicht, verdient es, herabgestimmt zu werden, um zukünftigen Zuschauern zu signalisieren, dass etwas damit nicht stimmt, unabhängig von ihren guten Absichten. Trotzdem glaube ich nicht, dass diese Antwort jemals eine Ablehnung verdient hat. Selbst in seiner ursprünglichen Form lieferte es ein Schlüsselelement des Puzzles, das in der akzeptierten Antwort weggelassen wurde - dass die Grundlinienausrichtung nicht die einzige Möglichkeit ist, Elemente vertikal auszurichten, und dass, wenn Sie die vertical-alignEigenschaft ändern , keine der in der akzeptierte Antwort gilt.
Mark Amery
33

Benutz einfach vertical-align:top;

Demo

Elyor
quelle
9

Sehen Sie sich dieses alternative Beispiel an. Der Grund für ein solches Verhalten ist im CSS3-Modul beschrieben: Zeile: 3.2. Zeilenumbruch [1] :

Im Allgemeinen berührt die Startkante eines Linienfelds die Startkante seines enthaltenden Blocks und die Endkante die Endkante seines enthaltenden Blocks. Floating Boxes können jedoch zwischen der enthaltenen Blockkante und der Line Box-Kante liegen. Obwohl Linienfelder im gleichen Inline-Formatierungskontext im Allgemeinen den gleichen Inline-Fortschrittsfortschritt (den des enthaltenden Blocks) aufweisen, können sie variieren, wenn der verfügbare Inline-Fortschrittsraum aufgrund von Floats reduziert wird [...]

Wie Sie sehen können, wird das dritte Element nach unten gedrückt, obwohl es keine overflowEigenschaft hat. Der Grund muss woanders zu finden sein. Das zweite Verhalten, das Sie bemerken, wird in Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) beschrieben. Spezifikation: 9.5 Floats [2] :

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.

Alle Ihre display:inline-block;Divs verwenden baselinein diesem Fall eine spezielle Art von 10.8 Berechnungen der Linienhöhe: die Eigenschaften 'Linienhöhe' und 'Vertikalausrichtung' (ganz am Ende) [3] :

Die Basislinie eines 'Inline-Blocks' ist die Basislinie seines letzten Zeilenfelds im normalen Fluss, es sei denn, es hat entweder keine In-Flow-Zeilenfelder oder seine 'Überlauf'-Eigenschaft hat einen anderen berechneten Wert als' sichtbar 'in In diesem Fall ist die Grundlinie die untere Randkante.

Wenn Sie also schwebende Elemente und inline-blockElemente verwenden, wird das schwebende Element zur Seite geschoben und die Inline-Formatierung wird gemäß 1 neu berechnet . Andererseits werden die nächsten Elemente gekürzt, wenn sie nicht passen. Da Sie bereits mit einem minimalen Speicherplatz arbeiten, gibt es keine andere Möglichkeit, Ihre Elemente zu ändern, als sie zu verschieben 2 . In diesem Fall definiert das höchste Element die Größe Ihres Umhüllungsdivs und damit die baseline 3 , während die in 2 angegebene Änderung von Position und Breite nicht auf solche Elemente mit minimalem Abstand und maximaler Höhe angewendet werden kann. In diesem Fall ergibt sich ein Verhalten wie in meiner allerersten Demo.

Schließlich der Grund, warum Ihr overflow:hiddenWille verhindert #firstDiv, an den unteren Rand Ihres Willens geschoben zu werden #container, obwohl ich in Abschnitt 11 keinen Grund finden konnte . Ohne overflow:hiddenfunktioniert es wie ausgenommen und definiert durch 2 und 3 . Demo

TL; DR: Sehen Sie sich die W3-Empfehlungen und die Implementierungen im Browser genau an. Meiner bescheidenen Meinung nach zeigen schwebende Elemente unerwartetes Verhalten, wenn Sie nicht alle Änderungen kennen, die sie an Ihren umgebenden Elementen vornehmen. Hier ist eine weitere Demo, die ein häufiges Problem mit Floats zeigt.

Zeta
quelle
3
Dieser "Standard" ist ein unglaubliches Durcheinander. Es ist erstaunlich, dass sie es geschafft haben, dass sich dieses Zeug über alle Browser hinweg konsistent verhält. Oh warte, nein, das haben sie noch nie geschafft.
Triynko
6

Ich habe ursprünglich damit begonnen, diese Frage zu beantworten , aber sie wurde als Betrug gesperrt, bevor ich fertig werden konnte. Deshalb poste ich die Antwort stattdessen hier.

Zuerst müssen wir verstehen, was inline-blockist.
Die Definition in MDN lautet:

Das Element generiert ein Blockelementfeld, das mit dem umgebenden Inhalt wie ein einzelnes Inline-Feld übertragen wird (ähnlich wie ein ersetztes Element).

Um zu verstehen, was hier vor sich geht, müssen wir uns vertical-alignden Standardwert ansehen baseline.

vertikale Positionsvisualisierungen
In dieser Abbildung haben Sie diese Farbkarte:
Blau: Die Grundlinie
Rot: Die Ober- und Unterseite der Zeilenhöhe
Grün: Die Ober- und Unterseite des Inline-Inhaltsfelds.

Im Element #left haben Sie Textinhalte, die die Basislinie steuern. Dies bedeutet, dass der darin enthaltene Text die Grundlinie für #left definiert.
In #right gibt es keinen Inhalt, daher hat der Browser keine andere Option, als das Feld unten als Basis zu verwenden.

Sehen Sie sich diese Visualisierung an, in der ich die Grundlinie in einem Beispiel gezeichnet habe, in dem der erste Inline-Container Text enthält und der nächste leer ist:

Grundlinie gezeichnet

Wenn Sie ein Element speziell nach oben ausrichten, sagen Sie wirklich, dass Sie die Oberseite dieses Elements nach oben im Linienfeld ausrichten.

Dies könnte anhand eines Beispiels leichter zu verstehen sein.

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
    vertical-align: baseline;
}
div#middle {
    vertical-align: top;
    height: 50px
}
   
div#right {
    font-size: 30px;
    height: 100px
}
<div id="left">
  <span>groovy</span>
</div>
<div id="middle">groovy</div>

<div id="right">groovy</div>

Das Ergebnis ist folgendes - und ich habe die blaue Grundlinie und das rote Linienfeld hinzugefügt: Was hier passiert, ist, dass die Höhe des Linienfelds davon abhängt, wie der Inhalt der gesamten Linie angeordnet ist. Dies bedeutet, dass zur Berechnung der oberen Ausrichtung zuerst die Basislinienausrichtungen berechnet werden müssen. Das Element hat , daher wird dies nicht für die Grundlinienpositionierung verwendet. aber die und sind vertikal positioniert, so dass ihre Basislinien ausgerichtet sind. In diesem Fall hat sich die Höhe des Linienfelds erhöht, da das Element aufgrund der größeren Schriftgröße etwas nach oben verschoben wurde. Dann kann die obere Position für das Element berechnet werden, und diese befindet sich am oberen Rand des Linienfelds.Erklärt vertikal ausrichten
#middlevertical-align:top#left#right#right#middle

Scheu
quelle
1

Das Problem ist, dass Sie float angewendet haben: links auf dem zweiten div. Dadurch kommt das zweite Div auf die linke Seite und Ihr erstes Div fällt ab und kommt nach Ihrem zweiten Div. Wenn Sie float anwenden: links auch auf dem ersten div, ist Ihr Problem weg.

Überlauf: versteckt verursacht kein Problem mit Ihrem Layout, Überlauf: versteckt betrifft nur innere Elemente eines Div, es hat nichts mit anderen Elementen zu tun, die sich außerhalb befinden.

Pal Singh
quelle
Nun, wenn es gedrückt wird, weil es nach Floated Div an zweiter Stelle steht, warum geht ThirdDiv dann nicht nach unten?
Shawn Taylor
weil die dritte Div eine zweite Div vor sich hat, die kein Float hat: left;
Pal Singh
Aber wo wird diese Regel erwähnt, dass wenn ein Div nach dem schwebenden Div kommt, es nach unten fällt? Ich habe w3.org überprüft.
Shawn Taylor
Das Element, das nicht schwebt, fällt auf die Grundlinie und wenn Sie negativ abgestimmt haben, dann muss ich sagen, dass es die logischste Antwort war
Pal Singh
Nein, ich habe nicht negativ gestimmt und ja, Ihre Antwort verdient kein Negativ. Gerade nach oben gestimmt.
Shawn Taylor
0

Versuchen Sie padding:0;, dem Körper etwas hinzuzufügen und den Rand Ihrer Divs zu entfernen.

Fügen Sie background-color:*anyneben dem Hintergrund * Farbe hinzu, um den Unterschied zu überprüfen.

LOLZ
quelle
Bearbeiten Sie die Antwort zum Formatieren von Code. Sie können Code formatieren, indem Sie das Symbol `vor dem Starten des Codes und nach dem Beenden des Codes hinzufügen. als codezB :. background-color:any color
JINO SHAJI
0

Versuchen Sie, alle CSS-Eigenschaften aller Elemente gleich zu machen.

Ich hatte ein ähnliches Problem und als ich dieses Problem behebte, stellte ich fest, dass ich ein Element mit der Eigenschaft Font in Div Element ablegte.

Nach dem Löschen dieses Elements mit der Eigenschaft "Schriftart" wurde die Ausrichtung aller DIV gestört. Um dies zu beheben, setze ich die Font-Eigenschaft auf alle DIV-Elemente, die mit dem Element übereinstimmen, das darin abgelegt wird.

Im folgenden Beispiel wurde das abgelegte Element der Klasse ".dldCuboidButton" mit der Schriftgröße definiert: 30 px.

Also habe ich den verbleibenden Klassen, dh .cuboidRecycle, .liCollect, .dldCollect, die von DIV-Elementen verwendet werden, dieselbe Eigenschaft hinzugefügt. Auf diese Weise folgen alle DIV-Elemente denselben Messungen vor und nach dem Ablegen des Elements.

.cuboidRecycle {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.liCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}

.dldCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#009933;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.dldCuboidButton {
    background-color:  #7c6436;
    color: white; /* White text */
    font-size: 30px; /* Set a font-size */
    border-radius: 8px;
    margin-top: 1px;
  }

Hier ist das Beispiel von HTML, das dynamisch mit dem obigen CSS erstellt wurde.

$("div#tabs").append(
  "<div id='" + newTabId + "'>#" + uniqueId + 
  "<input type=hidden id=hdn_tmsource_" + uniqueId + "  value='" + divTmpfest + "'>" + 
  "<input type=hidden id=leCuboidInfo_" + uniqueId + " value=''>" + 
  "<div id='" + divRecycleCuboid + "' class=cuboidRecycle ondrop='removeDraggedCuboids(event, ui)'  ondragover='allowDrop(event)'><font size='1' color='red'> Trash bin </font></div>" +
  "<div id='" + divDropLeCuboid  + "' class=liCollect ondrop='dropForLinkExport(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Manifest Cuboid here</font></div>" +
  "<div id='" + divDropDwldCuboid  + "' class=dldCollect ondrop='dropForTMEntry(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Cuboids here..</font></div>" +
  "</div>" 
);
Rahul Varadkar
quelle