Jak wypełnić element DIV obrazem, zachowując jego proporcje?

120

Znalazłem ten wątek - Jak rozciągnąć obraz, aby wypełnić <div>, zachowując jednocześnie jego proporcje? - nie do końca tego chcę.

Mam element div o określonym rozmiarze i znajdujący się w nim obraz. Chcę zawsze wypełniać element div obrazem, niezależnie od tego, czy obraz jest poziomy czy pionowy. I nie ma znaczenia, czy obraz jest obcięty (sam element div ma ukryty przepełnienie).

Więc jeśli obraz jest portretem, chcę, widthżeby był 100%i height:autożeby pozostał proporcjonalny. Jeśli obraz jest poziomy, chcę heightbyć 100%i width to beauto`. Brzmi skomplikowanie, prawda?

<div class="container">
   <img src="some-image.jpg" alt="Could be portrait or landscape"/>
</div>

Ponieważ nie wiem, jak to zrobić, po prostu stworzyłem szybki obraz tego, co mam na myśli. Nie potrafię tego właściwie opisać.

wprowadź opis obrazu tutaj

Więc chyba nie ja pierwszy o to pytam. Jednak nie mogłem znaleźć rozwiązania tego problemu. Może jest na to jakiś nowy sposób CSS3 - myślę o flex-boxie. Dowolny pomysł? Może to nawet łatwiejsze niż się spodziewam?

matowe
źródło
Dlaczego chcesz używać css3, skoro nadal możesz to łatwo zrobić za pomocą javascript? Idź z js
matey
1
Nie przetestowano, ale możesz spróbować ustawić min-wysokość i min-szerokość na 100%? To powinno przynajmniej wypełnić pole i zachować proporcje
chrisbulmer

Odpowiedzi:

150

Jeśli dobrze rozumiem, czego chcesz, możesz pozostawić atrybuty szerokości i wysokości poza obrazem, aby zachować proporcje i użyć Flexbox, aby wyśrodkować za Ciebie.

.fill {
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden
}
.fill img {
    flex-shrink: 0;
    min-width: 100%;
    min-height: 100%
}
<div class="fill">
    <img src="https://lorempizza.com/320/240" alt="" />
</div>

JSFiddle tutaj

Testowałem to pomyślnie w IE9, Chrome 31 i Opera 18. Ale żadna inna przeglądarka nie została przetestowana. Jak zawsze musisz wziąć pod uwagę swoje szczególne wymagania dotyczące wsparcia.

Isius
źródło
W IE9 obraz nie jest wyśrodkowany w pionie ani w poziomie za pomocą tej metody, jest wyrównany do góry i do lewej. i59.tinypic.com/ouo77s.png
Mike Kormendy
1
Ten problem występuje na iPadzie, wygląda na to, że safari rozciąga obraz do 100% jego wysokości, ale nie zachowuje właściwości min-width.
Sean
14
Wydaje się, że małe obrazy są skalowane w celu wypełnienia, ale nie w celu dopasowania. Przynajmniej kiedy używam dużego obrazu, pokazuje on tylko niewielką jego część.
Johncl
12
Aby duży obraz został przeskalowany w celu dopasowania, użyłem następującego obrazu:.fill img { min-height:100%; min-width: 100%; object-fit: cover; }
Peter G
super bohatera! : D
Garis M Suero
47

Jest trochę za późno, ale właśnie miałem ten sam problem i ostatecznie rozwiązałem go za pomocą innego postu stackoverflow ( https://stackoverflow.com/a/29103071 ).

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

Mam nadzieję, że to nadal komuś pomoże.

Ps: działa również razem z właściwościami css max-height , max-width , min-width i min-height . Jest to szczególnie przydatne przy użyciu jednostek długości, takich jak 100% lub 100 vh / 100 vw, do wypełnienia kontenera lub całego okna przeglądarki.

Hermilton
źródło
czy to jest rozwiązanie crossbrowser?
Candlejack
1
Object-fit: okładka; działa świetnie! Informacje o przeglądarce (nie działa w IE): css-tricks.com/almanac/properties/o/object-fit Rozwiązanie awaryjne dla IE: medium.com/@primozcigler/ ... MS pracuje nad wdrożeniem: developer.microsoft.com / pl-us / microsoft-edge / platform / status /…
Kaah
Myślę, że dodanie object-positionreguły do ​​tej klasy będzie tutaj pomocne. Tylko uwaga na marginesie.
Taha Paksu
8

Stare pytanie, ale zasługuje na aktualizację, ponieważ teraz jest na to sposób.

Poprawną odpowiedzią opartą na CSS jest użycie object-fit: cover, które działa jak background-size: cover. Pozycjonowaniem zajmie sięobject-position atrybut, który domyślnie jest centrowaniem.

Ale nie ma dla niego wsparcia w żadnej przeglądarce IE / Edge lub Android <4.4.4. Nie object-positionjest również obsługiwany przez Safari, iOS ani OSX. Polyfills istnieją, obrazy dopasowania obiektów wydają się dawać najlepsze wsparcie.

Aby uzyskać więcej informacji na temat działania tej właściwości, zobacz artykuł o Sztukach CSS, który zawieraobject-fit wyjaśnienia i prezentację.

całościowo
źródło
8

To powinno wystarczyć:

img {    
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
}
maksim1
źródło
U mnie działa całkiem nieźle, w moim przypadku wystarczyło dodać pozycję: bezwzględną i górną: 0, a także trochę z-index
byroncorrales
7

Wszystkie poniższe odpowiedzi mają stałą szerokość i wysokość, co powoduje, że rozwiązanie „nie reaguje”.

Aby osiągnąć wynik, ale zachować responsywność obrazu, użyłem następujących:

  1. Wewnątrz pojemnika umieść przezroczysty obraz GIF o pożądanych proporcjach
  2. Podaj tag obrazu w tle css z obrazem, który chcesz zmienić i przyciąć

HTML:

<div class="container">
    <img style="background-image: url("https://i.imgur.com/XOmNCwY.jpg");" src="img/blank.gif">
</div> 


.container img{
   width: 100%;
   height: auto;
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center;
}​
Artur Klassen
źródło
Użyłem obrazu tła dla całej mojej witryny portfolio projektów, aby uzyskać rozmiar tła: okładka. Teraz moje SEO obrazu jest pomieszane, ponieważ obrazy tła nie są rozpoznawane przez Google. Żałuję, że nie zakodowałem tego w inny sposób.
Alex Banman
5

Możesz to osiągnąć za pomocą właściwości css flex. Zobacz poniższy kod

.img-container {
  border: 2px solid red;
  justify-content: center;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  
}
.img-container .img-to-fit {
  flex: 1;
  height: 100%;
}
<div class="img-container">
  <img class="img-to-fit" src="https://images.pexels.com/photos/8633/nature-tree-green-pine.jpg" />
</div>

Sandeep K Nair
źródło
1
Działa to TYLKO po usunięciu właściwości szerokości i wysokości, o których mowa w niektórych innych odpowiedziach.
Chiwda
3

Rozważ użycie background-size: cover(IE9 +) w połączeniu z background-image. W przypadku IE8- istnieje wypełnienie .

Marat Tanalin
źródło
Czy to nie wymaga adresu URL w tle? Czy możesz rozwinąć więcej? Czy to zadziała z <img src = "" /> zgodnie z pytaniem?
harsimranb
@harsimranb Oczywiście background-sizema to sens tylko w przypadku background-imageokreślonych również (odpowiednio zaktualizowałem moją odpowiedź). Nie dotyczy IMGelementów.
Marat Tanalin
To najlepsza odpowiedź. Jest prosty i ma dobrą obsługę przeglądarki. Wszystkie inne rozwiązania są albo bardzo złożone, albo nie działają w IE (9).
JoostS
1

Spróbuj tego:

img {
  position: relative;
  left: 50%;
  min-width: 100%;
  min-height: 100%;
  transform: translateX(-50%);
}

Mam nadzieję że to pomoże

Landerqvist
źródło
1

Aby to osiągnąć, możesz użyć div. bez tagu img :) mam nadzieję, że to pomoże.

.img{
	width:100px;
	height:100px;
	background-image:url('http://www.mandalas.com/mandala/htdocs/images/Lrg_image_Pages/Flowers/Large_Orange_Lotus_8.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
.img1{
	width:100px;
	height:100px;
	background-image:url('https://images.freeimages.com/images/large-previews/9a4/large-pumpkin-1387927.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
<div class="img">	
</div>
<div class="img1">	
</div>

Sivasakthivel Kalaiarasu
źródło
1

Jedynym sposobem, w jaki osiągnąłem opisany scenariusz „najlepszego przypadku”, było umieszczenie obrazu jako tła:

<div class="container"></div>
.container {
    width: 150px;
    height: 100px;
    background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-position: 50% 50%;
}​
David Schumann
źródło
1

Oto odpowiedź z obsługą IE, object-fitaby nie stracić współczynnika

Używając prostego fragmentu kodu JS, aby wykryć, czy object-fitjest obsługiwany, a następnie zamień imgnasvg

//for browsers which doesn't support object-fit (you can use babel to transpile to ES5)

if ('objectFit' in document.documentElement.style === false) {
  document.addEventListener('DOMContentLoaded', () => {
    Array.prototype.forEach.call(document.querySelectorAll('img[data-object-fit]'), image => {
      (image.runtimeStyle || image.style).background = `url("${image.src}") no-repeat 50%/${image.currentStyle ? image.currentStyle['object-fit'] : image.getAttribute('data-object-fit')}`
      image.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='${image.width}' height='${image.height}'%3E%3C/svg%3E`
    })
  })
}
img {
  display: inline-flex;
  width: 175px;
  height: 175px;
  margin-right: 10px;
  border: 1px solid red
}

/*for browsers which support object fit */

[data-object-fit='cover'] {
  object-fit: cover
}

[data-object-fit='contain'] {
  object-fit: contain
}
<img data-object-fit='cover' src='//picsum.photos/1200/600' />
<img data-object-fit='contain' src='//picsum.photos/1200/600' />
<img src='//picsum.photos/1200/600' />


Uwaga: istnieje również kilka object-fitwypełniaczy, które będą object-fitdziałać.

Oto kilka przykładów:

dippas
źródło
0

Oto mój przykład roboczy. Użyłem sztuczki polegającej na ustawieniu obrazu jako tła kontenera div z tłem-size: cover i background-position: center center

Umieściłem obraz o szerokości: 100% i kryciu: 0, dzięki czemu jest niewidoczny. Zwróć uwagę, że pokazuję swój obraz tylko dlatego, że szczególnie interesuje mnie wywołanie zdarzenia kliknięcia dziecka.

Zwróć uwagę, że chociaż używam kątowego, jest to całkowicie nieistotne.

<div class="foto-item" ng-style="{'background-image':'url('+foto.path+')'}">
    <img class="materialboxed" ng-class="foto.picid" ng-src="{{foto.path}}" style="opacity: 0;filter: alpha(opacity=0);" width="100%" onclick="$('.materialboxed')/>
 </div>
<style>
.foto-item {
height: 75% !important;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow:hidden;
background-size: cover;
background-position: center center;
}
</style>

Wynik jest taki, który zdefiniujesz jako optymalny we wszystkich przypadkach

Noel Carcases
źródło
0

Wartości CSS object-fit: coveri object-position: left centerwłaściwości rozwiązują teraz ten problem.

Inżynieria wsteczna
źródło
0

.image-wrapper{
    width: 100px;
    height: 100px;
    border: 1px solid #ddd;
}
.image-wrapper img {
    object-fit: contain;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}
<div class="image-wrapper">
  <img src="">
</div>

Yaseen
źródło
-3

Po prostu popraw wysokość obrazu i podaj szerokość = auto

img{
    height: 95vh;
    width: auto;
}
Sarthak
źródło