Skaluj obraz, aby pasował do obwiedni


117

Czy istnieje rozwiązanie tylko CSS umożliwiające skalowanie obrazu do ramki ograniczającej (zachowując współczynnik proporcji)? Działa to, jeśli obraz jest większy niż kontener:

img {
  max-width: 100%;
  max-height: 100%;
}

Przykład:

Ale chcę przeskalować obraz, aż wymiar będzie stanowił 100% kontenera.


Czy masz na myśli wysokość: 100% i szerokość: 100%? czy masz pożądany wymiar, do którego chcesz dotrzeć? w przeciwnym razie możesz również rozciągnąć obraz i zmusić go do osiągnięcia tych wymiarów.
— mikevoermans

@mikevoermans Spójrz na moje dwa pierwsze przykłady: chcę rozciągnąć obraz, aż jeden z wymiarów osiągnie 100%, a drugi <= 100%
— Thomas Guillory

@jacktheripper Oczywiście zachowując proporcje ...
— Thomas Guillory

@gryzzly Przykłady mówią same za siebie! Gdyby spojrzeli na przykłady, było to oczywiste.
— Thomas Guillory,

@Artimuz Zupełnie się nie zgadzam. Trzy odpowiedzi na Twoje pytania (w tym moje) sugerują, że NIE było to oczywiste.
— Khan

Odpowiedzi:


94

Uwaga: mimo że jest to akceptowana odpowiedź, poniższa odpowiedź jest dokładniejsza i jest obecnie obsługiwana we wszystkich przeglądarkach, jeśli masz możliwość korzystania z obrazu tła.

Nie, nie ma jedynego sposobu CSS, aby to zrobić w obu kierunkach. Możesz dodać

.fillwidth {
    min-width: 100%;
    height: auto;
}

Aby element zawsze miał 100% szerokości i automatycznie skalował wysokość do współczynnika proporcji lub odwrotnie:

.fillheight {
    min-height: 100%; 
    width: auto;
}

aby zawsze skalować do maksymalnej wysokości i względnej szerokości. Aby zrobić jedno i drugie, musisz określić, czy współczynnik proporcji jest wyższy, czy niższy niż jego kontener, a CSS nie może tego zrobić.

Powodem jest to, że CSS nie wie, jak wygląda strona. Z góry ustala zasady, ale dopiero potem renderuje się elementy i wiesz dokładnie, z jakimi rozmiarami i proporcjami masz do czynienia. Jedynym sposobem na wykrycie tego jest JavaScript.


Chociaż nie szukasz rozwiązania JS, i tak dodam, jeśli ktoś może go potrzebować. Najłatwiejszym sposobem radzenia sobie z tym za pomocą JavaScript jest dodanie klasy na podstawie różnicy w stosunku. Jeśli stosunek szerokości do wysokości pudełka jest większy niż obrazu, dodaj klasę „fillwidth”, w przeciwnym razie dodaj klasę „fillheight”.


7
Właściwie jest rozwiązanie: ustawienie rozmiaru tła CSS3 na zawiera. Zobacz moją odpowiedź.
— Thomas Guillory

Masz całkowitą rację. Mimo że minęło półtora roku, zredagowałem swój post.
— Stephan Muller

4
Zakładam, że jest to poprawna odpowiedź na zadane pytanie, czyli jaki jest kod CSS dla tagu img. Jest to istotne, ponieważ semantycznie tag img jest treścią, a obraz jako tło elementu div nie. Podczas gdy niektóre okoliczności sprawiają, że jest to niepraktyczne (jeśli nie znasz stosunku obrazu do kontenera), w innych jest to w sam raz. Dzięki.
— duncanwilcox

173

Dzięki CSS3 jest rozwiązanie!

Rozwiązaniem jest umieścić obraz jako background-image, a następnie ustawić background-sizesię contain.

HTML

<div class='bounding-box'>
</div>

CSS

.bounding-box {
  background-image: url(...);
  background-repeat: no-repeat;
  background-size: contain;
}

Przetestuj tutaj: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Pełna zgodność z najnowszymi przeglądarkami: http://caniuse.com/background-img-opts

Aby wyrównać element div do środka, możesz użyć tej odmiany:

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}

1
Niezłe, chociaż moja odpowiedź nie jest błędna (pytałeś konkretnie o img), to jest świetne rozwiązanie i powinienem był o tym pomyśleć. Jedynym problemem jest to, że IE 8 jest nadal tak szeroko stosowany, że nie chciałbym jeszcze na nim polegać, ale mimo to niezły haczyk.
— Stephan Muller,

6
Ustaw go na „okładka”, jeśli nie chcesz używać czarnych pasków: background-size: include;
— arxpoetica

3
Należy zauważyć, że można wprowadzić adres URL obrazu z HTML: <div class=image style="background-image: url('/images/foo.jpg');"></div>. Wszystkie inne style należy stosować za pomocą CSS.
— Andrey Mikhaylov - lolmaus

14
Powiedziałbym, że to straszne podejście. Zmieniając go na obraz tła, usuwasz semantyczne znaczenie obrazu w kodzie HTML.
— animuson

14
@animuson: To nadal mi pomogło, ponieważ używam HTML / CSS do drukowanych raportów i nie mogłem dać
— zdziwienia na

37

Oto hakerskie rozwiązanie, które odkryłem:

#image {
    max-width: 10%;
    max-height: 10%;
    transform: scale(10);
}

Spowoduje to dziesięciokrotne powiększenie obrazu, ale ograniczy go do 10% ostatecznego rozmiaru - w ten sposób ograniczając go do pojemnika.

W przeciwieństwie do background-imagerozwiązania sprawdzi się to również z <video>elementami.

Interaktywny przykład:


1
Uwielbiam to rozwiązanie. Nie tylko faktycznie odpowiada na pytanie (wiem, co za myśl), ale działa pięknie we wszystkich nowoczesnych przeglądarkach bez konieczności uciekania się do Javascript!
— ndm13

2
Chciałbym zobaczyć coś takiego. W moim teście złożenia img w pojemniku IMG 400x400 po prostu staje przyciętymi w narożniku
— cyberwombat

3
Niezła odpowiedź! @Yashua Musisz dodać, transform-origin: top leftaby zatrzymać kadrowanie. / Zombie
— XwipeoutX

Znakomity. Moim jedynym zmartwieniem byłaby możliwa utrata jakości obrazu w źle zakodowanej przeglądarce, ale teoretycznie powinno działać dobrze!
— Codemonkey

Ciekawe, ale nie działa w Chrome. Daje przycięty wiersz obrazu.
— MattK,

23

Dziś wystarczy powiedzieć object-fit: include. Wsparcie to wszystko oprócz IE: http://caniuse.com/#feat=object-fit


3
IE ma obecnie tylko około 16% udziału w rynku w momencie pisania tego (12.09.2016 10:56) i nadal maleje, więc jest to dla mnie najlepsza odpowiedź: D
— Zhang

8
Nie edytuj odpowiedzi innych osób, aby naprawić rzeczy inne niż literówki lub uszkodzone linki. Nie powiedziałbym czegoś dziecinnego w rodzaju „Jest polifill dla przeglądarek bzdur” w odpowiedzi TAK i nie podoba mi się, że moja odpowiedź została zredagowana tak, aby wyglądała tak, jak to powiedziałem. jeśli chcesz użyć swoich słów, umieść je we własnej odpowiedzi.
— Glenn Maynard

Powiedziałbym, że to nie IE jest problemem, ale Edge. Według Caniuse object-fitjest nadal w fazie rozwoju.
— BairDev

To powinna być jedna z najczęściej wybieranych odpowiedzi w 2017 r. I dalej ... Zgodnie z powyższym linkiem caniuse, 90% wszystkich użytkowników na całym świecie korzysta teraz z przeglądarki, która to obsługuje
— fgblomqvist

Właśnie opublikowałem odpowiedź, która działa object-fit
— zi

8

html:

    <div class="container">
      <img class="flowerImg" src="flower.jpg">
    </div>

css:

.container{
  width: 100px;
  height: 100px;
}


.flowerImg{
  width: 100px;
  height: 100px;
  object-fit: cover;
  /*object-fit: contain;
  object-fit: scale-down;
  object-position: -10% 0;
  object-fit: none;
  object-fit: fill;*/
}

5

Możesz to osiągnąć dzięki czystemu CSS i pełnej obsłudze przeglądarek, zarówno dla obrazów w pionie, jak i w poziomie w tym samym czasie.

Oto fragment, który działa w przeglądarkach Chrome, Firefox i Safari (zarówno przy użyciu object-fit: scale-down, jak i bez niego):

figure {
  margin: 0;
}

.container {
  display: table-cell;
  vertical-align: middle;
  width: 80px;
  height: 80px;
  border: 1px solid #aaa;
}

.container_image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  margin-left: auto;
  margin-right: auto;
}

.container2_image2 {
  width: 80px;
  height: 80px;
  object-fit: scale-down;
  border: 1px solid #aaa;
}
Without `object-fit: scale-down`:

<br>
<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

<br> Using `object-fit: scale-down`:

<br>
<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>


2

Inne rozwiązanie bez obrazu tła i bez potrzeby stosowania kontenera (chociaż należy znać maksymalne rozmiary ramki ograniczającej):

img{
  max-height: 100px;
  max-width: 100px;
  width: auto;    /* These two are added only for clarity, */
  height: auto;   /* as the default is auto anyway */
}


Jeśli wymagane jest użycie kontenera, wówczas maksymalna szerokość i maksymalna wysokość mogą być ustawione na 100%:

img {
    max-height: 100%;
    max-width: 100%;
    width: auto; /* These two are added only for clarity, */
    height: auto; /* as the default is auto anyway */
}

div.container {
    width: 100px;
    height: 100px;
}

Do tego miałbyś coś takiego:

<table>
    <tr>
        <td>Lorem</td>
        <td>Ipsum<br />dolor</td>
        <td>
            <div class="container"><img src="image5.png" /></div>
        </td>
    </tr>
</table>

1

Ten przykład przedstawia proporcjonalne rozciągnięcie obrazu w celu dopasowania do całego okna. Improwizacją do powyższego poprawnego kodu jest dodanie$( window ).resize(function(){});

function stretchImg(){
    $('div').each(function() {
      ($(this).height() > $(this).find('img').height()) 
        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
        : '';
      ($(this).width() > $(this).find('img').width()) 
        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
        : '';
    });
}
stretchImg();

$( window ).resize(function() {
    strechImg();
});

Są dwa warunki warunkowe. Pierwsza z nich sprawdza, czy wysokość obrazu jest mniejsza niż div i stosuje .fillheightklasę, podczas gdy następna sprawdza szerokość i stosuje .fillwidthklasę. W obu przypadkach druga klasa jest usuwana za pomocą.removeClass()

Oto CSS

.fillwidth { 
   width: 100%;
   max-width: none;
   height: auto; 
}
.fillheight { 
   height: 100vh;
   max-width: none;
   width: auto; 
}

Możesz zamienić 100vhna, 100%jeśli chcesz rozciągnąć obraz w div. Ten przykład przedstawia proporcjonalne rozciągnięcie obrazu w celu dopasowania do całego okna.


OP specjalnie poprosił o podejście tylko do CSS.
— Colt McCormack

0

Czy chcesz skalować w górę, ale nie w dół?

div {
    border: solid 1px green;
    width: 60px;
    height: 70px;
}

div img {
    width: 100%;
    height: 100%;
    min-height: 500px;
    min-width: 500px;
    outline: solid 1px red;
}

Nie powoduje to jednak blokady współczynnika kształtu.


5
Postaraj się trochę bardziej wyrazić swoje oczekiwania przed odrzuceniem czyjejś odpowiedzi. Zwłaszcza, gdy odpowiedzieli na Twoje pytanie, zanim wyjaśnisz pytanie, wprowadzając zmiany.
— Khan

2
Postaraj się też być bardziej uprzejmy. Nikt ci nie pomoże, jeśli będziesz mówić w ten sposób.
— Misha Reyzlin

@Artimuz Przepraszam, jeśli cię nie poprowadziłem, ale wydawało mi się niejasne, że chcesz zachować proporcje, dlatego właśnie to skomentowałem. Zauważysz również, że wkleiłem fragment Twojego kodu z przykładów. Uważam, że utrzymanie wysokości: auto; zrobi to za Ciebie, jeśli określisz szerokość.
— ericosg

0

Użyłem tabeli do wyśrodkowania obrazu wewnątrz pudełka. Zachowuje proporcje i skaluje obraz w sposób całkowicie wewnątrz pudełka. Jeśli obraz jest mniejszy niż ramka, jest wyświetlany tak, jak jest w środku. Poniższy kod używa pola o szerokości 40 pikseli i wysokości 40 pikseli. (Nie jestem pewien, jak dobrze to działa, ponieważ usunąłem go z innego, bardziej złożonego kodu i trochę uprościłem)

CSS:

.SmallThumbnailContainer
{
    display: inline-block; position: relative;
    float: left;    
    width: 40px;
    height: 40px;
    border: 1px solid #ccc;
    margin: 0px; padding: 0px;
}
.SmallThumbnailContainer { width: 40px; margin: 0px 10px 0px 0px; } 
.SmallThumbnailContainer tr { height: 40px; text-align: center; }
.SmallThumbnailContainer tr td { vertical-align: middle; position: relative; width: 40px;  }
.SmallThumbnailContainer tr td img { overflow: hidden; max-height: 40px; max-width: 40px; vertical-align: middle; margin: -1px -1px 1px -1px; }

HTML:

<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
    <tr><td>
        <img src="thumbnail.jpg" alt="alternative text"/>
    </td></tr>
    </table>

0

Najczystszy i najprostszy sposób na zrobienie tego:

Najpierw trochę CSS:

div.image-wrapper {
    height: 230px; /* Suggestive number; pick your own height as desired */
    position: relative;
    overflow: hidden; /* This will do the magic */
    width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
}
img {
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    height: auto;
}

HTML:

<div class="image-wrapper">
  <img src="yourSource.jpg">
</div>

To powinno załatwić sprawę!


0

Pomogło mi to:

.img-class {
  width: <img width>;
  height: <img height>;
  content: url('/path/to/img.png');
}

Następnie na elemencie (możesz użyć javascript lub zapytań o media, aby dodać responsywność):

<div class='img-class' style='transform: scale(X);'></div>

Mam nadzieję że to pomoże!


-3
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Edytuję swoją odpowiedź, aby dokładniej wyjaśnić moje rozwiązanie, ponieważ mam głos negatywny.

Po ustawieniu stylów, jak pokazano powyżej w css, teraz następujący element HTML HTML będzie pokazywał obraz zawsze dopasowany do szerokości i dostosuje wysokość do szerokości. W ten sposób obraz zostanie przeskalowany, aby dopasować go do obwiedni zadanej w pytaniu.

<div class="boundingbox"><img src="image.jpg"/></div>

Ta odpowiedź działa tylko wtedy, gdy pudełko jest wyższe niż szerokie.
— XwipeoutX
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.