Jak rozciągnąć obraz, aby wypełnić <div>, zachowując jego proporcje?

201

Muszę sprawić, aby obraz rozciągał się do maksymalnego możliwego rozmiaru bez przepełnienia go <div>lub przekrzywienia obrazu.

Nie mogę przewidzieć proporcji obrazu, więc nie ma sposobu, aby wiedzieć, czy użyć:

<img src="url" style="width: 100%;">

lub

<img src="url" style="height: 100%;">

Nie mogę użyć obu (tj. Style = "szerokość: 100%; wysokość: 100%;"), ponieważ spowoduje to rozciągnięcie obrazu w celu dopasowania <div>.

Rozmiar <div>ma ustawiony procent ekranu, co również jest nieprzewidywalne.

Giffyguy
źródło
2
Jeśli potrzebujesz obrazu, aby wypełnić wysokość lub szerokość do odpowiednich wymiarów div, mogę tylko pomyśleć o użyciu javascript. Czy to jest coś, co chcesz odkryć?
okw

Odpowiedzi:

189

Aktualizacja 2016:

Nowoczesna przeglądarka zachowuje się znacznie lepiej. Wszystko, co musisz zrobić, to ustawić szerokość obrazu na 100% ( wersja demonstracyjna )

.container img {
   width: 100%;
}

Ponieważ nie znasz współczynnika proporcji, będziesz musiał użyć skryptów. Oto jak zrobiłbym to z jQuery ( demo ):

CSS

.container {
    width: 40%;
    height: 40%;
    background: #444;
    margin: 0 auto;
}
.container img.wide {
    max-width: 100%;
    max-height: 100%;
    height: auto;
}
.container img.tall {
    max-height: 100%;
    max-width: 100%;
    width: auto;
}​

HTML

<div class="container">
 <img src="http://i48.tinypic.com/wrltuc.jpg" />
</div>
<br />
<br />
<div class="container">
 <img src="http://i47.tinypic.com/i1bek8.jpg" />
</div>

Scenariusz

$(window).load(function(){
 $('.container').find('img').each(function(){
  var imgClass = (this.width/this.height > 1) ? 'wide' : 'tall';
  $(this).addClass(imgClass);
 })
})
Mottie
źródło
Czy użytkownik może zobaczyć obraz przed zmianą rozmiaru? Ktoś to przetestował?
RayLoveless,
Rozwiązanie jest prawie właściwe, wystarczy odwrócić wysokość i szerokość w css: jeśli obraz jest „wysoki”, wówczas szerokość powinna wynosić 100%, a nie wysokość (która będzie większa i przepełniona). Odwrotnie dla szerokich zdjęć.
mbritto
@mbritto: Masz rację, musiałem zmienić css na max-width / height i dodałem demo
Mottie
@Mottie jest sposób na dopasowanie obrazu o rozmiarze 930 px szerokości do pojemnika 960 px bez utraty jakości obrazu
Vivek Dragon
15
Dlaczego jest to akceptowana odpowiedź. Pytanie dotyczy tego, że obrazy są zbyt małe do umieszczenia w pojemniku. tzn. w jaki sposób można przeskalować obraz, aby wypełnić szerokość lub wysokość pojemnika, bez zwiększania proporcji obrazu. Ponadto w wersji demo usunięcie właściwości width:autolub height:autonie wpływa na wyświetlanie obrazów. W rzeczywistości ze wszystkich właściwości, które stosuje się do obrazu, max-width: 100%ma tylko jakikolwiek efekt i wpływa tylko na obraz pejzażowy. Ale co najważniejsze, twoja odpowiedź nie pomaga rozciągnąć małego obrazu, aby wypełnić większy pojemnik.
matty
78

Jest to o wiele łatwiejszy sposób, aby to zrobić tylko CSSi HTML:

HTML:

<div class="fill"></div>

CSS:

.fill {
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-image: url('path/to/image.jpg');
}

Spowoduje to umieszczenie obrazu jako tła i rozciągnięcie go do divrozmiaru bez zniekształceń.

Ryan
źródło
czy jest to możliwe przy nieokreślonej liczbie zdjęć?
TrtG
background-size: cover;to prawdziwa magia tutaj i to CSS3, ale ma rozsądną obsługę przeglądarki w najnowszych wersjach (patrz: w3schools.com/cssref/css3_pr_background-size.asp )
Jon Kloske
1
Warto umieścić URL obrazu w <div style="background-image: url('path/to/image.jpg');" class="fill"></div>
kodzie
background-size: cover nie zachowuje współczynnika proporcji, przycinane są części obrazu, które nie są proporcjonalne do elementu. Zobacz tutaj
Alex_Zhong
@Alex_Zhong, źle zrozumiałeś proporcje obrazu. Współczynnik proporcji oznacza, że ​​obraz nie jest rozciągany w żadnym kierunku (więc idealne koło nie stałoby się owalem ani w szerokości, ani w wysokości). Kadrowanie może być niezbędną częścią zachowania współczynnika kształtu (tak jak w przypadku użycia PO).
Jeremy Moritz
70

Nie jest to idealne rozwiązanie, ale ten CSS może pomóc. Zoom jest tym, co sprawia, że ​​ten kod działa, a współczynnik powinien teoretycznie być nieskończony, aby działał idealnie dla małych obrazów - ale 2, 4 lub 8 działa w większości przypadków dobrze.

#myImage {
    zoom: 2;  //increase if you have very small images

    display: block;
    margin: auto;

    height: auto;
    max-height: 100%;

    width: auto;
    max-width: 100%;
}
Prouda
źródło
1
Chciałbym, żeby to działało w Firefoksie. Dlaczego nie ma zoommiłości z Firefoksa !?
matty
1
Firefox nadal nie został zoomzaimplementowany, ale tutaj jest link do błędu w przyszłości: bugzilla.mozilla.org/show_bug.cgi?id=390936
Adam Taylor
31

Jeśli możesz, użyj obrazów tła i ustaw background-size: cover. Sprawi to, że tło obejmie cały element.

CSS

div {
  background-image: url(path/to/your/image.png);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}

Jeśli nie możesz użyć wbudowanych obrazów, istnieje kilka opcji. Po pierwsze jest

dopasowanie obiektowe

Ta właściwość działa na obrazy, filmy i inne obiekty podobne do background-size: cover.

CSS

img {
  object-fit: cover;
}

Niestety obsługa przeglądarki nie jest tak dobra, że ​​IE do wersji 11 w ogóle jej nie obsługuje. Następna opcja używa jQuery

CSS + jQuery

HTML

<div>
  <img src="image.png" class="cover-image">
</div>

CSS

div {
  height: 8em;
  width: 15em;
}

Niestandardowa wtyczka jQuery

(function ($) {
  $.fn.coverImage = function(contain) {
    this.each(function() {
      var $this = $(this),
        src = $this.get(0).src,
        $wrapper = $this.parent();

      if (contain) {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/contain no-repeat'
        });
      } else {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/cover no-repeat'
        });
      }

      $this.remove();
    });

    return this;
  };
})(jQuery);

Użyj wtyczki w ten sposób

jQuery('.cover-image').coverImage();

Weźmie obraz, ustawi go jako obraz tła na elemencie opakowania obrazu i usunie imgznacznik z dokumentu. Wreszcie możesz użyć

Czysty CSS

Możesz użyć tego jako rezerwowego. Obraz zostanie przeskalowany w górę, aby przykryć jego pojemnik, ale nie będzie go zmniejszać.

CSS

div {
  height: 8em;
  width: 15em;
  overflow: hidden;
}

div img {
  min-height: 100%;
  min-width: 100%;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  display: block;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Mam nadzieję, że to może komuś pomóc, szczęśliwego kodowania!

Daniels
źródło
Szukałem czystego rozwiązania CSS, aby obrazy wypełniały dany pojemnik bez użycia obrazu tła i rozmiaru tła, a kod CSS działa tutaj doskonale dla> = IE9 i nowoczesnych przeglądarek. Demo CodePen tutaj
FLOQ Design
W Pure CSS usunąłem min-i zmieniłem się width: 100%; height: 100%;i działałem! niesamowite rozwiązanie! +1 dzięki!
Guilherme Nascimento
1
background-size: containjest również przydatny, jeśli nie chcesz, aby żaden obraz został przycięty.
Ponkadoodle,
Możesz dodać zoom:0.001do rozwiązania Pure CSS, aby zmniejszyć.
Ivor Zhou,
12

Aktualizacja 2019.

Możesz teraz użyć object-fitwłaściwości css, która akceptuje następujące wartości:fill | contain | cover | none | scale-down

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

Na przykład możesz mieć kontener, w którym znajduje się obraz.

<div class="container">
    <img src="" class="container_img" />
</div>

.container {
    height: 50px;
    width: 50%;

.container_img {
    height: 100%;
    width: 100%;
    object-fit: cover;
Ed Stennett
źródło
7

Jest to niemożliwe tylko w przypadku HTML i CSS, a przynajmniej niezwykle egzotyczne i skomplikowane. Jeśli chcesz wrzucić trochę javascript, oto rozwiązanie wykorzystujące jQuery:

$(function() {
    $(window).resize(function() {
        var $i = $('img#image_to_resize');
        var $c = $img.parent();
        var i_ar = $i.width() / $i.height(), c_ar = $c.width() / $c.height();            
        $i.width(i_ar > c_ar ? $c.width() : $c.height() * (i_ar));
    });
    $(window).resize();
});

Spowoduje to zmianę rozmiaru obrazu, aby zawsze mieścił się w elemencie nadrzędnym, niezależnie od jego rozmiaru. Po powiązaniu ze $(window).resize()zdarzeniem, gdy użytkownik zmieni rozmiar okna, obraz się dostosuje.

To nie próbuje wyśrodkować obrazu w kontenerze, byłoby to możliwe, ale myślę, że nie o to ci chodzi.

Tatu Ulmanen
źródło
4
Zakładam $ img.parent (); powinno być naprawdę $ i.parent ();
Jimbo Jonny
5

Ustaw szerokość i wysokość zewnętrznego containerdiv. Następnie użyj stylizacji poniżej na img:

.container img{
    width:100%;
    height:auto;
    max-height:100%;
}

Pomoże to zachować proporcje obrazu

Chintan Bhatt
źródło
6
nie wypełni div.
Sven van den Boogaart
5

Jeśli chcesz ustawić maksymalną szerokość lub wysokość (aby nie była bardzo duża), zachowując proporcje obrazów, możesz to zrobić:

img{
   object-fit: contain;
   max-height: 70px;
}
Bohao LI
źródło
4

Natknąłem się na to pytanie, szukając podobnego problemu. Tworzę stronę internetową z responsywnym projektem, a szerokość elementów umieszczonych na stronie jest ustawiona na procent szerokości ekranu. Wysokość jest ustawiana za pomocą wartości vw.

Ponieważ dodałem posty z PHP i zapleczem bazy danych, czysty CSS nie wchodziło w rachubę. Uważam jednak, że rozwiązanie jQuery / javascript jest trochę kłopotliwe, więc wpadłem na fajne (przynajmniej tak uważam) rozwiązanie.

HTML (lub php)

div.imgfill {
  float: left;
  position: relative;
  background-repeat: no-repeat;
  background-position: 50%  50%;
  background-size: cover;
  width: 33.333%;
  height: 18vw;
  border: 1px solid black; /*frame of the image*/
  margin: -1px;
}
<div class="imgfill" style="background-image:url(source/image.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image2.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image3.jpg);">
  This might be some info
</div>

Używając style = "" możliwe jest, że PHP dynamicznie aktualizuje moją stronę, a styl CSS wraz ze stylem = "" kończy się na idealnie zakrytym obrazie, skalowanym tak, aby obejmował dynamiczny tag div.

Christian Jensen
źródło
4

Aby ten obraz rozciągnął się do maksymalnego możliwego rozmiaru bez przepełnienia go lub przekrzywienia obrazu.

Zastosować...

img {
  object-fit: cover;
  height: -webkit-fill-available;
}

style na obrazie.

fasolka szparagowa
źródło
3

Za pomocą tej metody możesz wypełnić swój div obrazem o różnym stosunku div i image.

jQuery:

$(window).load(function(){
   $('body').find(.fillme).each(function(){
      var fillmeval = $(this).width()/$(this).height();
      var imgval = $this.children('img').width()/$this.children('img').height();
      var imgClass;
      if(imgval > fillmeval){
          imgClass = "stretchy";
      }else{
          imgClass = "stretchx";
      }
      $(this).children('img').addClass(imgClass);
   });
});

HTML:

<div class="fillme">
   <img src="../images/myimg.jpg" />
</div>

CSS:

.fillme{
  overflow:hidden;
}
.fillme img.stretchx{
  height:auto;
  width:100%;
}
.fillme img.stretchy{
  height:100%;
  width:auto;
}
użytkownik1994142
źródło
3

To załatwiło sprawę

div img {
    width: 100%;
    min-height: 500px;
    width: 100vw;
    height: 100vh;
    object-fit: cover;
}
Developer_D
źródło
2

jeśli pracujesz z tagiem IMG, jest to łatwe.

Ja to zrobiłem:

<style>
        #pic{
            height: 400px;
            width: 400px;
        }
        #pic img{
            height: 225px;               
            position: relative;
            margin: 0 auto;
        }
</style>

<div id="pic"><img src="images/menu.png"></div>

$(document).ready(function(){
            $('#pic img').attr({ 'style':'height:25%; display:none; left:100px; top:100px;' })
)}

ale nie znalazłem sposobu, aby to działało z #pic {background: url (img / menu.png)} Enyone? Dzięki

aleXela
źródło
dokonałem zmiany i znalazłem odpowiedź na mój problem! nie, to komuś pomoże. background-image: url (images / menu.png); powtarzanie w tle: brak powtarzania; pozycja: absolutna; rozmiar tła: 300 pikseli; wysokość: 100%; szerokość: 100%; i możesz zmienić wartość rozmiaru tła za pomocą javascript lub jquery (.attr ({'style': 'background-size: 150px auto; left: 50px; top: 50px;'}))
aleXela
2

Miałem podobny problem. Rozwiązałem to za pomocą CSS .

Zasadniczo Object-fit: coverpomaga osiągnąć zadanie utrzymania proporcji podczas pozycjonowania obrazu wewnątrz div.

Ale problem Object-fit: covernie działał w IE i zajmował 100% szerokości i 100% wysokości, a proporcje obrazu były zniekształcone. Innymi słowy, efekt powiększania obrazu nie istniał, co widziałem w chromie.

Podjąłem podejście polegające na umieszczeniu obrazu w pojemniku z wartością bezwzględną, a następnie umieszczeniu go dokładnie na środku za pomocą kombinacji:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Gdy znajdzie się w centrum, daję obrazowi,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

Dzięki temu obraz uzyskuje efekt Object-fit: cover.


Oto demonstracja powyższej logiki.

https://jsfiddle.net/furqan_694/s3xLe1gp/

Ta logika działa we wszystkich przeglądarkach.

Furqan Rahamath
źródło
1

HTML:

<style>
#foo, #bar{
    width: 50px; /* use any width or height */
    height: 50px;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
}
</style>

<div id="foo" style="background-image: url('path/to/image1.png');">
<div id="bar" style="background-image: url('path/to/image2.png');">

JSFiddle

... A jeśli chcesz ustawić lub zmienić obraz (na przykładzie #foo):

jQuery:

$("#foo").css("background-image", "url('path/to/image.png')");

JavaScript:

document.getElementById("foo").style.backgroundImage = "url('path/to/image.png')";
Patch92
źródło
1

Wiele znalezionych tutaj rozwiązań ma pewne ograniczenia: niektóre nie działają w IE (dopasowanie obiektowe) lub starszych przeglądarkach, inne rozwiązania nie skalują obrazów (tylko je zmniejszają), wiele rozwiązań nie obsługuje zmiany rozmiaru okna i wiele z nich jest nie ogólne, albo oczekuj stałej rozdzielczości lub układu (pionowa lub pozioma)

Jeśli używanie javascript i jquery nie stanowi problemu, mam to rozwiązanie oparte na kodzie @Tatu Ulmanen. Rozwiązałem niektóre problemy i dodałem kod na wypadek, gdyby obraz został załadowany dynamicznie i niedostępny na początku. Zasadniczo chodzi o to, aby mieć dwie różne reguły css i stosować je w razie potrzeby: jedną, gdy ograniczeniem jest wysokość, więc musimy pokazywać czarne pasy po bokach, a drugą zasadę css, gdy ograniczeniem jest szerokość, więc musimy pokaż czarne paski u góry / u dołu.

function applyResizeCSS(){
    var $i = $('img#imageToResize');
    var $c = $i.parent();
    var i_ar = Oriwidth / Oriheight, c_ar = $c.width() / $c.height();  
    if(i_ar > c_ar){
        $i.css( "width","100%");
        $i.css( "height","auto");          
    }else{
        $i.css( "height","100%");
        $i.css( "width","auto");
    }
}   
var Oriwidth,Oriheight;
$(function() {
    $(window).resize(function() {
        applyResizeCSS();
    });

    $("#slide").load(function(){
        Oriwidth  = this.width,
        Oriheight = this.height; 
        applyResizeCSS();
    }); 

    $(window).resize();
}); 

W przypadku elementu HTML takiego jak:

<img src="images/loading.gif" name="imageToResize" id="imageToResize"/> 
jolumg
źródło