Automatyczna zmiana rozmiaru obrazu w układzie CSS FlexBox i zachowanie współczynnika proporcji?

99

Użyłem układu CSS flex box, który wygląda jak poniżej:

wprowadź opis obrazu tutaj

Jeśli ekran się zmniejszy, zamieni się w to:

wprowadź opis obrazu tutaj

Problem polega na tym, że obrazy nie są zmieniane, zachowując współczynnik proporcji z oryginalnego obrazu.

Czy można użyć czystego CSS i układu flex box, aby umożliwić zmianę rozmiaru obrazów, jeśli ekran się zmniejszy?

Oto mój html:

<div class="content">
  <div class="row"> 
    <div class="cell">
      <img src="http://i.imgur.com/OUla6mK.jpg"/>
    </div>
    <div class="cell">
      <img src="http://i.imgur.com/M16WzMd.jpg"/>
    </div>
  </div>
</div>

mój CSS:

.content {
    background-color: yellow;    
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

    background-color: red;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto; 

    padding: 10px;
    margin: 10px;

    background-color: green;
    border: 1px solid red;
    text-align: center;

}
konfile
źródło

Odpowiedzi:

84

img {max-width:100%;}jest jednym ze sposobów na zrobienie tego. Po prostu dodaj go do swojego kodu CSS.

http://jsfiddle.net/89dtxt6s/

Omega
źródło
3
Czy można to również zrobić dla wymiaru wysokości, jeśli ekran się zmniejszy?
konfile
@confile zależałoby to w dużej mierze od układu kodu, ale możesz spróbować dodać go height:100%;do imgcss.
Omega
height: 100vhzrobi to, nie height: 100%. Stylizacja na wysokość jest zawsze trudna.
gdbj
1
Dlaczego ta odpowiedź jest oznaczona jako prawidłowa? Czy Omega nie zmieniła tego w domyślne zachowanie przeglądarki? jsfiddle.net/89dtxt6s/221
VeeK
73

Przyjechałem tutaj, szukając odpowiedzi na moje zniekształcone obrazy. Nie jestem do końca pewien, czego szuka operacja powyżej, ale stwierdziłem, że dodanie align-items: centergo rozwiąże problem. Czytając dokumenty, sensowne jest zastąpienie tego, jeśli bezpośrednio zginasz obrazy, ponieważ align-items: stretchjest to ustawienie domyślne. Innym rozwiązaniem jest umieszczenie najpierw na obrazach elementu div.

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}
gdbj
źródło
11
„Przyszedłem tutaj, szukając odpowiedzi na moje zniekształcone obrazy”, dotarłem tutaj z tego samego powodu i twoje rozwiązanie pomogło mi (to, co zostało oznaczone jako rzeczywiste rozwiązanie, w ogóle mi nie pomogło)
Wagner da Silva
to też mi pomogło, czy ktoś może wyjaśnić, dlaczego to działa?
Jerry B. nr 1 stażysta
To była dla mnie poprawna odpowiedź. max-width: 100%; nie poprawił wysokości (wysokość była nadal lekko rozciągnięta). W moim przypadku użyłem align-items: flex-start; ponieważ nie chciałem, aby obraz był wyśrodkowany w pionie w kontenerze, ale nadal działał, ponieważ zastępuje domyślne align-items: stretch; Oto lista wszystkich wartości właściwości dla elementów wyrównywania, których można użyć do zastąpienia: w3schools.com/cssref/css3_pr_align-items.asp
Kyle Vassella
Próbowałem wielu rzeczy, ale twoje elementy wyrównywania: środek na rodzicu jest jedynym, który załatwił sprawę.
Micros,
To powinna być akceptowana odpowiedź. Align-content nie działał dla mnie pod względem rozciągania, ale align-items tak, oba mają różne funkcje. To SE wyjaśnia różnicę między nimi: stackoverflow.com/questions/27539262/ ...
John Ernest
44

Możesz wypróbować bardzo nową i prostą funkcję CSS3:

img { 
  object-fit: contain;
}

Zachowuje proporcje obrazu (jak w przypadku sztuczki z tłem-obrazem), aw moim przypadku działało dobrze w tym samym problemie.

Uważaj jednak, nie jest obsługiwany przez IE (zobacz szczegóły pomocy tutaj ).

Lokinou
źródło
4
Proszę pamiętać, że obiekt nadrzędny musi być elastyczny
Lokinou
Wypróbowałem to i działało idealnie w elastycznym div.
Rémy Kaloustian
6

Proponuję przyjrzeć się background-sizeopcjom dostosowania rozmiaru obrazu.

Zamiast umieszczać obraz na stronie, jeśli masz go ustawiony jako obraz tła, możesz ustawić:

background-size: contain

lub

background-size: cover

Opcje te uwzględniają zarówno wysokość, jak i szerokość podczas skalowania obrazu. Będzie to działać w IE9 i wszystkich innych najnowszych przeglądarkach.

user3196436
źródło
3

Na drugim obrazku wygląda na to, że chcesz, aby obraz wypełnił pole, ale utworzony przykład ZACHOWAJE proporcje (zwierzęta wyglądają normalnie, nie są szczupłe ani grube).

Nie mam pojęcia, czy jako przykład wykonałeś obróbkę zdjęć w Photoshopie, czy też drugi to „jak powinno być” (powiedziałeś, że jest, podczas gdy w pierwszym przykładzie powiedziałeś „powinno”)

W każdym razie muszę założyć:

Jeśli „obrazy nie są zmieniane z zachowaniem współczynnika proporcji” i pokazujesz mi obraz, który ZACHOWUJE proporcje pikseli, muszę założyć, że próbujesz osiągnąć proporcje obszaru „przycinania” (wewnętrzna część zielony) WILE z zachowaniem proporcji pikseli. Oznacza to, że chcesz wypełnić komórkę obrazem, powiększając i przycinając obraz.

Jeśli to jest twój problem, kod, który podałeś NIE odzwierciedla "twojego problemu", ale twój przykład początkowy.

Biorąc pod uwagę poprzednie dwa założenia, to, czego potrzebujesz, nie może zostać osiągnięte za pomocą rzeczywistych obrazów, jeśli wysokość ramki jest dynamiczna, ale z obrazami tła. Albo za pomocą „background-size: include” lub tych technik (inteligentne dopełnienia w procentach, które ograniczają kadrowanie lub maksymalne rozmiary w dowolnym miejscu): http://fofwebdesign.co.uk/template/_testing/scale-img/scale- img.htm

Jedynym sposobem, w jaki jest to możliwe w przypadku obrazów, jest to, że ZAPOMNIAMY o twoim drugim iimage, a komórki mają stałą wysokość, a NA PEWNO, sądząc po przykładowych obrazach, wysokość pozostaje taka sama!

Więc jeśli wysokość twojego kontenera się nie zmienia i chcesz, aby twoje obrazy były kwadratowe, wystarczy ustawić maksymalną wysokość obrazów na tę znaną wartość (minus wypełnienia lub obramowania, w zależności od właściwości rozmiaru pola komórki)

Lubię to:

<div class="content">
  <div class="row">    
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-2.jpg"/>
      </div>
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-7.jpg"/>
      </div>
    </div>
</div>

Oraz CSS:

.content {
    background-color: green;
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 10px;
    border: solid 10px red;
    text-align: center;
    height: 300px;
    display: flex;
    align-items: center;
    box-sizing: content-box;
}
img {
    margin: auto;
    width: 100%;
    max-width: 300px;
    max-height:100%
}

http://jsfiddle.net/z25heocL/

Twój kod jest nieprawidłowy (tagi otwierające są zamiast tagów zamykających, więc wyświetlają komórki ZAGNIEŻDŻONE, a nie rodzeństwo, użył ZRZUTU EKRANU twoich obrazów wewnątrz wadliwego kodu, a pole flex nie zawiera komórek, ale oba przykłady w kolumnie ( ustawiłeś "wiersz", ale uszkodzony kod zagnieżdżający jedną komórkę wewnątrz drugiej spowodował powstanie flexu wewnątrz flex, w końcu działając jako KOLUMNY. Nie mam pojęcia, co chciałeś osiągnąć i jak wymyśliłeś ten kod, ale ja ' Zgaduję, czego chcesz, to jest to.

Dodałem display: flex do komórek, więc obraz zostanie wyśrodkowany (myślę, że display: tablemożna by było użyć tutaj również z tymi wszystkimi znacznikami)

sergio
źródło
Wygląda na to, że nie masz najmniejszego pojęcia, w jaki sposób odpowiedziałem na to pytanie. Cały html i css w tym jsfiddle jest tym, co dostarczył pytający (@confile). Po prostu przeczytaj pytanie, a zobaczysz. Moje rozwiązanie to jedna prosta linia css img {max-width: 100%;}, a osoba pytająca zaakceptowała moją odpowiedź ponad rok temu, ponieważ zapewnia ona rozwiązanie, o które pytano. Życzę wszystkiego najlepszego tutaj, proszę spróbować poprawnie przeczytać pytania, a następnie odpowiedzieć na nie w przyszłości, dzięki.
Omega
0

HTML:

<div class="container">
    <div class="box">
        <img src="http://lorempixel.com/1600/1200/" alt="">
    </div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}
Ukr
źródło
0

W ten sposób radziłbym sobie z różnymi obrazami (rozmiarami i proporcjami) w elastycznej siatce.

.images {
  display: flex;
  flex-wrap: wrap;
  margin: -20px;
}

.imagewrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(50% - 20px);
  height: 300px;
  margin: 10px;
}

.image {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */
}
<div class="images">
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1000x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/500x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
</div>

ggzone
źródło
-5

Używam jquery lub vw, aby zachować proporcje

jquery

function setSize() {
    var $h = $('.cell').width();
    $('.your-img-class').height($h);
}
$(setSize);
$( window ).resize(setSize); 

vw

 .cell{
    width:30vw;
    height:30vw;
}
.cell img{
    width:100%;
    height:100%;
}
Erick Boileau
źródło