Czy istnieje odpowiednik rozmiaru tła: okładka i zawiera dla elementów obrazu?


240

Mam witrynę z wieloma stronami i różnymi obrazami w tle i wyświetlam je z CSS, takich jak:

body.page-8 {
    background: url("../img/pic.jpg") no-repeat scroll center top #000;
    background-size: cover;
}

Chcę jednak wyświetlać różne obrazy (pełny ekran) na jednej stronie za pomocą <img>elementów i chcę, aby miały one takie same właściwości jak powyższa background-image: cover;właściwość (obrazy nie mogą być wyświetlane z CSS, muszą być wyświetlane z dokumentu HTML).

Zwykle używam:

div.mydiv img {
    width: 100%;
}

Lub:

div.mydiv img {
    width: auto;
}

aby obraz był pełny i elastyczny. Jednak obraz zbyt mocno się kurczy ( width: 100%), gdy ekran staje się zbyt wąski, i pokazuje kolor tła ciała na dolnym ekranie. Druga metoda width: auto;powoduje, że obraz jest tylko w pełnym rozmiarze i nie reaguje na rozmiar ekranu.

Czy istnieje sposób wyświetlania obrazu w ten sam sposób, co background-size: coverrobi?


Świetne pytanie.
wonsuc

Odpowiedzi:


380

Rozwiązanie nr 1 - Właściwość dopasowania obiektu (brak obsługi IE )

Po prostu ustaw object-fit: cover;na obrazie.

body {
  margin: 0;
}
img {
  display: block;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
}
<img src="http://lorempixel.com/1500/1000" />

Zobacz MDN - dotyczący object-fit: cover:

Rozmiar zastępowanej zawartości jest dopasowywany tak, aby zachować jego proporcje podczas wypełniania całego pola zawartości elementu. Jeśli proporcje obiektu nie odpowiadają proporcjom jego ramki, wówczas obiekt zostanie przycięty, aby pasował.

Zobacz także to demo Codepen, które porównuje object-fit: coverzastosowane do obrazu z background-size: coverzastosowanym do obrazu tła


Rozwiązanie nr 2 - Zamień obraz na obraz w tle na css

body {
  margin: 0;
}
img {
  position: fixed;
  width: 0;
  height: 0;
  padding: 50vh 50vw;
  background: url(http://lorempixel.com/1500/1000/city/Dummy-Text) no-repeat;
  background-size: cover;
}
<img src="http://placehold.it/1500x1000" />


3
W momencie tego komentarza dopasowanie obiektowe nie jest jeszcze obsługiwane przez żadną wersję programu Internet Explorer (nawet Edge). Jest to jednak rozważane .
Mike Kormendy

3
dopasowanie obiektów nadal nie jest obsługiwane w IE. Byłbym z dala, jeśli na stronie produkcyjnej i zależy ci na użytkownikach IE.
Travis Michael Heller

2
Możesz także dodać polyfill dla nr 1 dla IE i starego Safari: github.com/bfred-it/object-fit-images
Valera Tumash

1
Ostrożnie z drugim rozwiązaniem. Najlepiej nie polegać na vh w przeglądarkach mobilnych: nicolas-hoizey.com/2015/02/…
sudokai

1
@RoCk można znaleźć takie rzeczy na caniuse: caniuse.com/#search=background-att :) PS Myślę, że wszyscy możemy być pewni, że IE nigdy nie uzyska wsparcia dla tej funkcji, a ponieważ nie ma też wypełniania wielopunktowego, „ ponownie wkręciłem lub utknąłem z hackami JS / CSS, aż MS zdecyduje, że nadszedł czas (wreszcie) „zamordować” IE przez usunięcie go z systemu Windows.
SidOfc,

31

W rzeczywistości istnieje całkiem proste rozwiązanie css, które działa nawet na IE8:

.container {
  position: relative;
  overflow: hidden;
  /* Width and height can be anything. */
  width: 50vw;
  height: 50vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  /* The following values determine the exact image behaviour. */
  /* You can simulate background-size: cover/contain/etc.
     by changing between min/max/standard width/height values.
     These values simulate background-size: cover
  */
  min-width: 100%;
  min-height: 100%;
}
<div class="container">
    <img src="http://placehold.it/200x200" alt="" />
</div>


9
To nie powiela zachowania cover, ale zamiast tego przycina wycentrowaną sekcję z src img. Zobacz jsfiddle.net/sjt71j99/4 - pierwsze zdjęcie to twoja uprawa, następne to rozmiar tła: okładka, tzn. To, czego chcemy, trzecie to oryginalne zdjęcie. Znalazłem, że dla obrazów krajobrazowych zamień minimalną wysokość i minimalną szerokość na maksymalną wysokość: 100%; do pionowego zastosowania maks. szerokość: 100%. Byłoby miło, gdyby istniało jedno rozwiązanie, które sprawdzałoby się zarówno w układzie poziomym, jak i pionowym. Jakieś pomysły? To najlepsze rozwiązanie dla przeglądarek, jakie do tej pory widziałem.
terraling

1
Masz rację, nie robi dokładnie tego samego, próbowałem trochę rzeczy, ale wydaje się, że tak naprawdę nie można uzyskać 100% kopii, działa tak długo, jak obraz jest mniejszy niż pojemnik w jednym wymiarze chociaż.
Simon

@terraling, wiem, że to stary komentarz, ale sprawdź moją odpowiedź . Wykorzystuje transformację do pozycjonowania obrazu w środku.
Thiago Barcala

30

Zakładając, że możesz ustawić element kontenera, który chcesz wypełnić, wydaje się, że działa, ale wydaje się nieco pospieszny. Zasadniczo po prostu używam min/max-width/heightna większym obszarze, a następnie skaluję ten obszar z powrotem do oryginalnych wymiarów.

.container {
  width: 800px;
  height: 300px;
  border: 1px solid black;
  overflow:hidden;
  position:relative;
}
.container.contain img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  max-width: 10%;
  max-height: 10%;
  -webkit-transform:scale(10);
  transform: scale(10);
}
.container.cover img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  min-width: 1000%;
  min-height: 1000%;
  -webkit-transform:scale(0.1);
  transform: scale(0.1);
}
<h1>contain</h1>
  <div class="container contain">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>
  <h1>cover</h1>
  <div class="container cover">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>


1
Zgadzać się w zupełności. Jest to najlepsze z powyższych rozwiązań do ogólnego zastosowania.
Varis Vītols

Wspaniale. Pomogło mi to. Dziękuję
Raman Nikitsenka

14

Znalazłem proste rozwiązanie do emulacji zarówno okładki, jak i zawartości, które jest czystym CSS i działa dla kontenerów o dynamicznych wymiarach, a także nie ogranicza żadnych proporcji obrazu.

Pamiętaj, że jeśli nie potrzebujesz obsługi IE ani Edge'a przed 16, lepiej użyj dopasowania obiektowego.

rozmiar tła: okładka

.img-container {
  position: relative;
  overflow: hidden;
}

.background-image {
  position: absolute;
  min-width: 1000%;
  min-height: 1000%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(0.1);
  z-index: -1;
}
<div class="img-container">
  <img class="background-image" src="https://picsum.photos/1024/768/?random">
  <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

Tutaj stosuje się 1000%, w przypadku gdy naturalny rozmiar obrazu jest większy niż rozmiar, który jest wyświetlany. Na przykład, jeśli obraz ma wymiary 500 x 500, ale kontener ma tylko 200 x 200. Dzięki temu rozwiązaniu obraz zostanie przeskalowany do 2000 x 2000 (ze względu na minimalną szerokość / minimalną wysokość), a następnie przeskalowany do 200 x 200 (z powodu transform: scale(0.1)).

Współczynnik x10 można zastąpić x100 lub x1000, ale zwykle renderowanie obrazu 2000 x 2000 na div 20x20 nie jest idealne. :)

rozmiar tła: zawiera

Zgodnie z tą samą zasadą możesz także użyć go do emulacji background-size: contain:

.img-container {
  position: relative;
  overflow: hidden;
  z-index: 0;
}

.background-image {
  position: absolute;
  max-width: 10%;
  max-height: 10%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(10);
  z-index: -1;
}
<div style="background-color: black">
  <div class="img-container">
    <img class="background-image" src="https://picsum.photos/1024/768/?random">
    <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
</div>


Sztuczka skali jest już podana tutaj https://stackoverflow.com/a/28771894/2827823 , więc nie widzę sensu w publikowaniu jeszcze jednego, i tak jest transformw wielu odpowiedziach
Ason

Jeśli chcesz rozszerzyć wyjaśnienie, zaktualizuj tę odpowiedź, ponieważ nie ma potrzeby używania 2 z tym samym rozwiązaniem
Ason,

1
Dziękuję za komentarz @LGSon. Nie widziałem tej odpowiedzi wcześniej, ale nadal uważam, że moja odpowiedź ma tutaj swoją wartość. Podejście jest prawie takie samo, ale moim zdaniem moje jest prezentowane w nieco czystszy sposób. Wiele innych odpowiedzi tutaj przedstawia to samo rozwiązanie, a wszystkie z nich są niekompletne (z wyjątkiem tego, które podłączyłeś). Więc jeśli moja odpowiedź nie powinna tu być, to nie powinny też być inne.
Thiago Barcala,

1
Zauważyłem, że zmniejsza obraz w przeglądarce mobilnej Chrome na Androida (testowany na LG G3 i Samsung S9), nie testowałem go z Chrome na iOS, Firefox na Androida wyświetlał go poprawnie.
Jecko

10

Nie , nie możesz tego zrozumieć, background-size:cover ale ...

To podejście jest cholernie bliskie: wykorzystuje JavaScript do ustalenia, czy obraz jest poziomy czy pionowy, i odpowiednio stosuje style.

JS

 $('.myImages img').load(function(){
        var height = $(this).height();
        var width = $(this).width();
        console.log('widthandheight:',width,height);
        if(width>height){
            $(this).addClass('wide-img');
        }else{
            $(this).addClass('tall-img');
        }
    });

CSS

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

http://jsfiddle.net/b3PbT/


3

Musiałem emulować background-size: contain, ale nie mogłem użyć z object-fitpowodu braku wsparcia. Moje obrazy miały pojemniki o określonych wymiarach, co w końcu działało dla mnie:

.image-container {
  height: 200px;
  width: 200px;
  overflow: hidden;
  background-color: rebeccapurple;
  border: 1px solid yellow;
  position: relative;
}

.image {
  max-height: 100%;
  max-width: 100%;
  margin: auto;
  position: absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
}
<!-- wide -->
<div class="image-container">
  <img class="image" src="http://placehold.it/300x100">
</div>

<!-- tall -->
<div class="image-container">
  <img class="image" src="http://placehold.it/100x300">
</div>


Możesz użyć min-height: 100%; max-height:100%;i uzyskać równowartość wielkości tła: okładka;
Chris Seufert

min-height: 100%; max-height:100%;nie zachowałaby proporcji, więc nie jest dokładnie równoważna.
Reedyn

2

Spróbuj ustawić zarówno min-height i min-width, ze display:block:

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

( skrzypce )

Pod warunkiem, że elementem zawierającym obraz jest position:relativelub position:absolute, obraz przykryje pojemnik. Jednak nie będzie wyśrodkowany.

Możesz łatwo wyśrodkować obraz, jeśli wiesz, czy przepełni się on w poziomie (ustaw margin-left:-50%), czy w pionie (ustaw margin-top:-50%). Może być możliwe użycie zapytań o media CSS (i trochę matematyki), aby to ustalić.


2

Dzięki CSS możesz symulować object-fit: [cover|contain];. To użycie transformi [max|min]-[width|height]. To nie jest idealne. To nie działa w jednym przypadku: jeśli obraz jest szerszy i krótszy niż pojemnik.

.img-ctr{
  background: red;/*visible only in contain mode*/
  border: 1px solid black;
  height: 300px;
  width: 600px;
  overflow: hidden;
  position: relative;
  display: block;
}
.img{
  display: block;

  /*contain:*/
  /*max-height: 100%;
  max-width: 100%;*/
  /*--*/

  /*cover (not work for images wider and shorter than the container):*/
  min-height: 100%;
  width: 100%;
  /*--*/

  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<p>Large square:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x1000"></span>
</p>
<p>Small square:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x100"></span>
</p>
<p>Large landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/2000x1000"></span>
</p>
<p>Small landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x100"></span>
</p>
<p>Large portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x2000"></span>
</p>
<p>Small portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x200"></span>
</p>
<p>Ultra thin portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x1000"></span>
</p>
<p>Ultra wide landscape (images wider and shorter than the container):
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x200"></span>
</p>


2

Co możesz zrobić, to użyć atrybutu „style”, aby dodać obraz tła do elementu, w ten sposób nadal będziesz wywoływać obraz w HTML, ale nadal będziesz mógł używać zachowania background-size: cover css:

HTML:

    <div class="image-div" style="background-image:url(yourimage.jpg)">
    </div>

CSS:

    .image-div{
    background-size: cover;
    }

W ten sposób dodaję zachowanie rozmiar tła: pokrycie do elementów, które muszę dynamicznie ładować do HTML. Następnie możesz użyć niesamowitych klas css, takich jak background-position: center. Bum


1
Głównie rozdzielenie problemów, ale oto kilka innych: programmers.stackexchange.com/a/271338
Daan

0

W przypadku IE musisz także dołączyć drugą linię - szerokość: 100%;

.mydiv img {
    max-width: 100%;
    width: 100%;
}

0

nie wolno mi „dodawać komentarza”, więc robi to, ale tak naprawdę to, co zrobił Eru Penkman, jest dość trafne, aby uzyskać to jako tło, wszystko, co musisz zrobić, to zmienić

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

DO

.wide-img{
    margin-left:-42%;
    height:100%;
}
.tall-img{
    margin-top:-42%;
    width:100%;
}


0

Wiem, że to stare, jednak wiele rozwiązań, które widzę powyżej, ma problem z tym, że obraz / wideo jest zbyt duży dla kontenera, więc nie działa tak jak okładka wielkości tła. Jednak postanowiłem stworzyć „klasy użytkowe”, aby działały one dla obrazów i filmów. Po prostu nadajesz kontenerowi .media-cover-wrapper, a sam element multimedialny klasę .media-cover

Następnie masz następujące jQuery:

function adjustDimensions(item, minW, minH, maxW, maxH) {
  item.css({
  minWidth: minW,
  minHeight: minH,
  maxWidth: maxW,
  maxHeight: maxH
  });
} // end function adjustDimensions

function mediaCoverBounds() {
  var mediaCover = $('.media-cover');

  mediaCover.each(function() {
   adjustDimensions($(this), '', '', '', '');
   var mediaWrapper = $(this).parent();
   var mediaWrapperWidth = mediaWrapper.width();
   var mediaWrapperHeight = mediaWrapper.height();
   var mediaCoverWidth = $(this).width();
   var mediaCoverHeight = $(this).height();
   var maxCoverWidth;
   var maxCoverHeight;

   if (mediaCoverWidth > mediaWrapperWidth && mediaCoverHeight > mediaWrapperHeight) {

     if (mediaWrapperHeight/mediaWrapperWidth > mediaCoverHeight/mediaCoverWidth) {
       maxCoverWidth = '';
       maxCoverHeight = '100%';
     } else {
       maxCoverWidth = '100%';
       maxCoverHeight = '';
     } // end if

     adjustDimensions($(this), '', '', maxCoverWidth, maxCoverHeight);
   } else {
     adjustDimensions($(this), '100%', '100%', '', '');
   } // end if
 }); // end mediaCover.each
} // end function mediaCoverBounds

Dzwoniąc, pamiętaj o zmianie rozmiaru strony:

mediaCoverBounds();

$(window).on('resize', function(){
  mediaCoverBounds();
});

Następnie następujący CSS:

.media-cover-wrapper {
  position: relative;
  overflow: hidden;
}

.media-cover-wrapper .media-cover {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

Tak, może wymagać jQuery, ale reaguje całkiem dobrze i działa dokładnie tak, jak rozmiar tła: okładka i możesz go użyć na obrazie i / lub wideo, aby uzyskać tę dodatkową wartość SEO.


0

Możemy przyjąć podejście ZOOM. Możemy założyć, że maksymalnie 30% (lub więcej do 100%) może być efektem powiększenia, jeśli wysokość obrazu LUB szerokość obrazu jest mniejsza niż żądana wysokość LUB szerokość. Możemy ukryć resztę niepotrzebnego obszaru z przepełnieniem: ukryty.

.image-container {
  width: 200px;
  height: 150px;
  overflow: hidden;
}
.stage-image-gallery a img {
  max-height: 130%;
  max-width: 130%;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

Spowoduje to dostosowanie obrazów o różnej szerokości LUB wysokości.


-1
background:url('/image/url/') right top scroll; 
background-size: auto 100%; 
min-height:100%;

napotkałem te same dokładne objawy. powyżej pracował dla mnie.

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.