Dziecko z maksymalnym wzrostem: 100% przepełnia rodzica


139

Próbuję zrozumieć, co wydaje mi się nieoczekiwane:

Mam element o maksymalnej wysokości 100% w kontenerze, który również używa maksymalnej wysokości, ale nieoczekiwanie dziecko przepełnia rodzica:

Przypadek testowy: 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%; 
}

Jest to jednak naprawione, jeśli rodzicowi zostanie podana wyraźna wysokość:

Przypadek testowy: http://jsfiddle.net/bq4Wu/17/

.container {  
    height: 200px;
}

Czy ktoś wie, dlaczego dziecko nie uszanowałoby maksymalnego wzrostu rodzica w pierwszym przykładzie? Dlaczego wymagana jest wyraźna wysokość?

Odpowiedzi:


209

Kiedy określasz procent dla max-heightdziecka, jest to procent rzeczywistego wzrostu rodzica, a nie rodzica max-height, co jest dziwne . To samo dotyczy max-width.

Tak więc, jeśli nie określisz jawnej wysokości rodzica, nie ma wysokości bazowej, na podstawie której dziecko ma max-heightbyć obliczane, więc max-heightoblicza się none, pozwalając dziecku być tak wysokim, jak to możliwe. Jedynym innym ograniczeniem działającym teraz na dziecko jest max-widthjego rodzica, a ponieważ sam obraz jest wyższy niż szeroki, przepełnia on wysokość pojemnika w dół, aby zachować jego proporcje, a jednocześnie być możliwie jak największy.

Kiedy zrobić określić wyraźny wysokość dla rodzica, dziecko wie, że musi być co najwyżej 100% tej wyraźnej wysokości. Pozwala to na ograniczenie go do wysokości rodzica (przy jednoczesnym zachowaniu proporcji).


4
Jest to przydatne wyjaśnienie, szczególnie w połączeniu z wkładem mojego przyjaciela: „max-height: 100% (child) of max-height: 100% (rodzic) = 0 - to dlatego Twoje dziecko nie honoruje swojej wartości nadrzędnej”.
iamkeir,

8
Nie jestem pewien, którą odpowiedź przyjąć - ta odpowiada „dlaczego”.
iamkeir,

Odpowiedziałem tylko „dlaczego”, ponieważ nie jestem pewien, jaki jest twój cel, ponieważ nie zostało to wyraźnie wymienione. Może jeśli to rozwiniesz, mogę odpowiedzieć.
BoltClock

Zaakceptowałem to, ponieważ odpowiada na moje rzeczywiste pytanie, dziękuję. Uwaga: odpowiedź @ Daniela poniżej oferuje poprawkę.
iamkeir,

W moim przypadku display: flex; flex-direction: columnrozwiązałem problem i dodałem pasek przewijania, który chciałem.
xdevs23

73

Trochę się bawiłem. Na większym obrazie w przeglądarce Firefox uzyskałem dobry wynik, używając wartości właściwości dziedziczenia. Czy to ci pomoże?

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

img {
    max-height: inherit;
    max-width: inherit;
}

Nie jestem pewien, którą odpowiedź zaakceptować - ta odpowiada „poprawka”.
iamkeir,

Zaakceptowano @BoltClock za odpowiedź, ale dziękuję za zaoferowanie poprawki.
iamkeir,

1
Oprócz @BoltClock moja odpowiedź brzmi dokładnie tak, jak mówi. CSS po prostu mówi komputerowi, jak obsłużyć element, ale po obliczeniach ograniczy wszystkie wartości do podstawowych wartości potrzebnych do renderowania, takich jak wysokość, szerokość, kolor, współrzędne, ... Właściwość inherit nakazuje img weź „obliczoną” wartość rodzica. Otrzymujesz więc obliczone wartości wysokości i szerokości we właściwościach css max-height i max-width.
Daniel

2
To nie działa, gdy max:height: 100%zamiast stałej wysokości: jsfiddle.net/umbreak/n6czk9xt/1
Montero

2
Nie mogę zadeklarować szerokości i wysokości jako stałych, ponieważ mój układ jest responsywny dispaly: flex;. Otworzyłem nowy wątek: Otworzyłem nowy wątek: stackoverflow.com/questions/29732391/… Jednak w gorszym przypadku mogłem użyć Jquery do pobrania rzeczywistej szerokości i wysokości img i ustawienia ich w div obrazu nadrzędnego.
Didac Montero

7

Znalazłem rozwiązanie tutaj: http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/

Sztuczka jest możliwa, ponieważ istnieje relacja między WIDTH a PADDING-BOTTOM elementu. Więc:

rodzic:

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

child ( usuń wszystkie css związane z szerokością , czyli szerokość: 100%):

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

5

Możesz użyć właściwości dopasowania do obiektu

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

Jak sugerowano tutaj

Pełne wyjaśnienie tej właściwości autorstwa Chrisa Millsa w Dev.Opera

I jeszcze lepszy w Sztukach CSS

Jest obsługiwany w

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

Właśnie sprawdziłem, że vivaldi i chrom też to wspierają (bez niespodzianki)

Obecnie nie jest obsługiwany w IE, ale ... kogo to obchodzi ? Ponadto iOS obsługuje dopasowanie obiektów, ale nie położenie obiektu, ale wkrótce będzie.


Dobra alternatywa! Wyobrażam sobie, że flex-box może również potencjalnie pomóc, jeśli w porządku degradacja w IE jest akceptowalna.
iamkeir

3

Oto rozwiązanie dla niedawno otwartego pytania oznaczonego jako duplikat tego pytania. <img>Tag przekroczenia max-wysokość macierzystego <div>.

Zepsuty: Fiddle

Praca: Fiddle

W tym przypadku odpowiedzią było dodanie display:flexdo 2 <div>tagów nadrzędnych


3

Zamiast iść z maksymalną wysokością: 100% / 100%, alternatywnym podejściem do wypełnienia całej przestrzeni byłoby użycie ustawienia position: absolutegóra / dół / lewo / prawo na 0.

Innymi słowy, kod HTML wyglądałby następująco:

<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 {
}

Możesz zobaczyć przykład na żywo w Codesandbox - Overflow within CSS Flex / Grid


2

Być może ktoś inny wyjaśni przyczyny Twojego problemu, ale możesz go rozwiązać, określając wysokość pojemnika, a następnie ustawiając wysokość obrazu na 100%. Ważne jest, aby widthobraz znajdował się przed 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>

Jeśli chcą, aby kontener był mniejszy, jeśli obraz jest mniejszy niż 200x200, to tak, musi to być zrobione z minimalną wysokością / maksymalną wysokością.
cimmanon

2

Najbliżej tego mogę uzyskać ten przykład:

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

lub

.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%; 
}

Głównym problemem jest to, że wysokość przyjmuje procent wysokości kontenera, więc szuka jawnie ustawionej wysokości w kontenerze nadrzędnym, a nie jego maksymalnej wysokości.

Jedynym sposobem obejścia tego do pewnego stopnia, jaki widzę, są skrzypce powyżej, w których można ukryć przepełnienie, ale wtedy wypełnienie nadal działa jako widoczna przestrzeń, w którą może wpływać obraz, więc zamiast tego działa zastąpienie jednolitą ramką (a następnie dodanie ramki border-box, aby uzyskać 200 pikseli, jeśli taka jest potrzebna szerokość)

Nie jestem pewien, czy to pasuje do tego, do czego go potrzebujesz, ale wydaje mi się, że najlepsze, co mogę.


Niestety kadrowanie obrazu nie jest idealne. Jednak dzięki za wkład.
iamkeir,

1

Dobrym rozwiązaniem jest nie używanie wysokości na rodzica i używanie go tylko na dziecku z View Port :

Przykład skrzypiec: 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;
}

1

Kontenery będą już na ogół ładnie opakowywać zawartość. Na odwrót często nie działa tak dobrze: dzieci nie ładnie wypełniają swoich przodków. Zatem ustaw wartości szerokości / wysokości na elemencie najbardziej wewnętrznym, a nie najbardziej zewnętrznym, i pozwól elementom zewnętrznym zawijać swoją zawartość.

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

img {
    display: block;
    max-height: 200px;
    max-width: 200px;
}

Niezłe ujęcie, podoba mi się to.
iamkeir

0

Twój pojemnik nie ma wysokości.

Dodaj wysokość: 200px;

do kontenerów css, a kotek zostanie w środku.


Dzięki za wkład, ale zidentyfikowałem to w PO.
iamkeir,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.