Kind mit maximaler Größe: 100% überlaufen Eltern

139

Ich versuche zu verstehen, was mir unerwartet erscheint:

Ich habe ein Element mit einer maximalen Höhe von 100% in einem Container, das ebenfalls eine maximale Höhe verwendet, aber unerwartet überläuft das Kind das übergeordnete Element:

Testfall: http://jsfiddle.net/bq4Wu/16/

.container {  
    background: blue; 
    padding: 10px; 
    max-height: 200px; 
    max-width: 200px; 
}

img { 
    display: block;
    max-height: 100%; 
    max-width: 100%; 
}

Dies ist jedoch behoben, wenn dem übergeordneten Element eine explizite Höhe zugewiesen wird:

Testfall: http://jsfiddle.net/bq4Wu/17/

.container {  
    height: 200px;
}

Weiß jemand, warum das Kind im ersten Beispiel die maximale Größe seines Elternteils nicht einhalten würde? Warum ist eine explizite Höhe erforderlich?

iamkeir
quelle

Antworten:

209

Wenn Sie einen Prozentsatz für max-heightein Kind angeben max-height, ist dies seltsamerweise ein Prozentsatz der tatsächlichen Größe des Elternteils, nicht der des Elternteils . Gleiches gilt für max-width.

Wenn Sie also keine explizite Größe für das übergeordnete Element angeben, gibt es keine Basishöhe , aus der das Kind berechnet max-heightwerden kann. Berechnen Sie dies so , dass das Kind so groß wie möglich ist. Die einzige andere Einschränkung, die jetzt auf das Kind wirkt, ist die des Elternteils. Da das Bild selbst größer als breit ist, läuft es über die Höhe des Containers nach unten, um sein Seitenverhältnis beizubehalten und insgesamt noch so groß wie möglich zu sein.max-heightnonemax-width

Wenn Sie tun , für die Eltern eine explizite Höhe angeben, dann weiß das Kind es höchstens 100% dieser expliziten Höhe sein muss. Dadurch kann es auf die Größe des Elternteils beschränkt werden (wobei das Seitenverhältnis beibehalten wird).

BoltClock
quelle
4
Dies ist eine nützliche Erklärung, insbesondere gemischt mit der Eingabe meines Freundes: "Maximale Größe: 100% (Kind) der maximalen Größe: 100% (Eltern) = 0 - aus diesem Grund hält Ihr Kind seinen Elternwert nicht ein".
Iamkeir
8
Ich bin mir nicht sicher, welche Antwort ich akzeptieren soll - diese beantwortet das "Warum".
Iamkeir
Ich habe nur das "Warum" beantwortet, weil ich nicht sicher bin, was Ihr Ziel ist, da es nicht ausdrücklich erwähnt wird. Vielleicht kann ich darauf antworten, wenn Sie darauf näher eingehen.
BoltClock
Akzeptierte dies, da es meine eigentliche Frage beantwortet, danke. Bitte beachten Sie, dass die Antwort von @ Daniel unten eine Lösung bietet.
Iamkeir
In meinem Fall display: flex; flex-direction: columnlöste dies das Problem und fügte die gewünschte Bildlaufleiste hinzu.
Xdevs23
73

Ich habe ein bisschen rumgespielt. Bei einem größeren Bild in Firefox habe ich mit der Verwendung des ererbten Eigenschaftswerts ein gutes Ergebnis erzielt. Hilft dir das?

.container {
    background: blue;
    padding: 10px;
    max-height: 100px;
    max-width: 100px;
    text-align:center;
}

img {
    max-height: inherit;
    max-width: inherit;
}
Daniel
quelle
Ich bin mir nicht sicher, welche Antwort ich akzeptieren soll - diese beantwortet die 'Lösung'.
Iamkeir
Akzeptiert @BoltClock für die Beantwortung des Warum, aber danke, dass Sie einen Fix angeboten haben.
Iamkeir
1
Zusätzlich zu @BoltClock ist meine Antwort genau das, was er sagt. CSS teilt dem Computer nur mit, wie mit einem Element umgegangen werden soll. Nach Berechnungen werden jedoch alle Werte auf die für das Rendern erforderlichen Grundwerte wie Höhe, Breite, Farbe, Koordinaten usw. begrenzt. Die Eigenschaft "inherit" teilt dem img mit Nehmen Sie den "berechneten" Wert des übergeordneten Elements. So erhalten Sie die berechneten Werte für Höhe und Breite in Ihren CSS-Eigenschaften für maximale Höhe und maximale Breite.
Daniel
2
Dies funktioniert nicht, wenn max:height: 100%anstelle einer festen Höhe: jsfiddle.net/umbreak/n6czk9xt/1
Didac Montero
2
Ich kann Breite und Höhe nicht als fest deklarieren, da mein Layout reagiert dispaly: flex;. Ich habe einen neuen Thread geöffnet: Ich habe einen neuen Thread geöffnet: stackoverflow.com/questions/29732391/… Im schlimmsten Fall könnte ich jedoch Jquery verwenden, um die tatsächliche Breite und Höhe des Bilds abzurufen und sie im div des übergeordneten Bilds festzulegen.
Didac Montero
7

Ich habe hier eine Lösung gefunden: http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/

Der Trick ist möglich, weil eine Beziehung zwischen WIDTH und PADDING-BOTTOM eines Elements besteht. So:

Elternteil:

container {
  height: 0;
  padding-bottom: 66%; /* for a 4:3 container size */
  }

Kind ( entfernen Sie alle CSS in Bezug auf Breite , dh Breite: 100%):

img {
  max-height: 100%;
  max-width: 100%;
  position: absolute;     
  display:block;
  margin:0 auto; /* center */
  left:0;        /* center */
  right:0;       /* center */
  }
Niente1
quelle
5

Sie können die Eigenschaft object-fit verwenden

.cover {
    object-fit: cover;
    width: 150px;
    height: 100px;
}

Wie hier vorgeschlagen

Eine vollständige Erklärung dieser Eigenschaft von Chris Mills in Dev.Opera

Und eine noch bessere in CSS-Tricks

Es wird unterstützt in

  • Chrome 31+
  • Safari 7.1+
  • Firefox 36+
  • Opera 26+
  • Android 4.4.4+
  • iOS 8+

Ich habe gerade überprüft, ob Vivaldi und Chrom es auch unterstützen (keine Überraschung hier)

Es wird derzeit im IE nicht unterstützt, aber ... wen interessiert das ? Außerdem unterstützt iOS die Objektanpassung, jedoch nicht die Objektposition, wird dies jedoch bald tun.

Luis Sieira
quelle
Schöne Alternative! Ich stelle mir vor, dass Flex-Box möglicherweise auch hilfreich sein könnte, wenn eine ordnungsgemäße Verschlechterung des IE akzeptabel ist.
Iamkeir
3

Hier ist eine Lösung für eine kürzlich geöffnete Frage, die als Duplikat dieser Frage markiert ist . Das <img>Tag überschritt die maximale Höhe des Elternteils <div>.

Gebrochen: Geige

Arbeiten: Geige

In diesem Fall war das Hinzufügen display:flexzu den 2 übergeordneten <div>Tags die Antwort

CrazyPaste
quelle
3

Anstatt mit der maximalen Höhe von 100% / 100% zu arbeiten, würde ein alternativer Ansatz zum Ausfüllen des gesamten Raums darin bestehen, position: absoluteoben / unten / links / rechts auf 0 zu setzen.

Mit anderen Worten würde der HTML-Code wie folgt aussehen:

<div class="flex-content">
  <div class="scrollable-content-wrapper">
    <div class="scrollable-content">
      1, 2, 3
    </div>
   </div>
</div>
.flex-content {
  flex-grow: 1;
  position: relative;
  width: 100%;
  height: 100%;
}

.scrollable-content-wrapper {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow: auto;
}

.scrollable-content {
}

Sie können ein Live-Beispiel unter Codesandbox - Überlauf in CSS Flex / Grid sehen

Tianzhen Lin
quelle
2

Vielleicht kann jemand anderes die Gründe für Ihr Problem erklären, aber Sie können es lösen, indem Sie die Höhe des Containers angeben und dann die Höhe des Bildes auf 100% einstellen. Es ist wichtig, dass widthdas Bild vor dem angezeigt wird height.

<html>
    <head>
        <style>
            .container {  
                background: blue; 
                padding: 10px;
                height: 100%;
                max-height: 200px; 
                max-width: 300px; 
            }

            .container img {
                width: 100%;
                height: 100%
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="http://placekitten.com/400/500" />
        </div>
    </body>
</html>
Kevin Brydon
quelle
Wenn der Container kleiner werden soll, wenn das Bild kleiner als 200 x 200 ist, muss dies mit minimaler / maximaler Höhe erfolgen.
Cimmanon
2

Das nächste, was ich erreichen kann, ist dieses Beispiel:

http://jsfiddle.net/YRFJQ/1/

oder

.container {  
  background: blue; 
  border: 10px solid blue; 
  max-height: 200px; 
  max-width: 200px; 
  overflow:hidden;
  box-sizing:border-box;
}

img { 
  display: block;
  max-height: 100%; 
  max-width: 100%; 
}

Das Hauptproblem besteht darin, dass die Höhe den Prozentsatz der Containerhöhe annimmt. Daher wird im übergeordneten Container nach einer explizit festgelegten Höhe gesucht, nicht nach der maximalen Höhe.

Der einzige Weg, um dies bis zu einem gewissen Grad zu umgehen, ist die Geige oben, in der Sie den Überlauf verbergen können, aber dann fungiert die Polsterung immer noch als sichtbarer Raum, in den das Bild fließen kann, und daher funktioniert das Ersetzen durch einen festen Rand stattdessen (und dann) Hinzufügen eines Rahmens, um 200px zu erreichen, wenn dies die Breite ist, die Sie benötigen)

Ich bin mir nicht sicher, ob dies zu dem passt, wofür Sie es brauchen, aber das Beste, was ich erreichen kann.

Ashleynolan
quelle
Leider ist das Zuschneiden des Bildes nicht ideal. Vielen Dank für Ihre Eingabe.
Iamkeir
1

Eine gute Lösung besteht darin, die Höhe nicht für das übergeordnete Element und nur für das untergeordnete Element mit Ansichtsfenster zu verwenden :

Geigenbeispiel: https://jsfiddle.net/voan3v13/1/

body, html {
  width: 100%;
  height: 100%;
}
.parent {
  width: 400px;
  background: green;
}

.child {
  max-height: 40vh;
  background: blue;
  overflow-y: scroll;
}
Tibbus
quelle
1

Container verpacken ihren Inhalt in der Regel bereits gut. Umgekehrt funktioniert es oft nicht so gut: Kinder füllen ihre Vorfahren nicht gut. Stellen Sie also Ihre Werte für Breite / Höhe auf das innerste Element und nicht auf das äußerste Element ein und lassen Sie die äußeren Elemente ihren Inhalt einschließen.

.container {
    background: blue;
    padding: 10px;
}

img {
    display: block;
    max-height: 200px;
    max-width: 200px;
}
Dave Cousineau
quelle
Schön, ich mag das.
Iamkeir
0

Ihr Container hat keine Höhe.

Höhe hinzufügen: 200px;

zu den Containern CSS und das Kätzchen bleibt drinnen.

Raffael
quelle
Vielen Dank für die Eingabe, aber ich habe dies im OP identifiziert.
Iamkeir