CSS wymusza zmianę rozmiaru obrazu i zachowanie proporcji

577

Pracuję z obrazami i natknąłem się na problem ze współczynnikami kształtu.

<img src="big_image.jpg" width="900" height="600" alt="" />

Jak widać heighti widthsą już określone. Dodałem regułę CSS dla obrazów:

img {
  max-width:500px;
}

Ale dla big_image.jpg, otrzymuję width=500i height=600. Jak mogę zmienić rozmiar zdjęć, zachowując jednocześnie ich proporcje.

Moonvader
źródło

Odpowiedzi:

773

img {
  display: block;
  max-width:230px;
  max-height:95px;
  width: auto;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

Spowoduje to zmniejszenie obrazu, jeśli jest zbyt duży dla określonego obszaru (jako minus, nie powiększy obrazu).

setec
źródło
11
Czy istnieje wersja tego, która powiększy obrazy, aby pasowały również do ich pojemnika? Próbowałem maksymalnej szerokości / maksymalnej wysokości jako liczb z szerokością / wysokością jako auto, ale jak powiedziałem setec, to nie powiększy obrazu. Próbowałem również użyć minimalnej szerokości / minimalnej wysokości. Po prostu nie mogę poprawnie ustawić kombinacji. Chcę po prostu, aby cokolwiek obraz musiałem umieścić w tym pojemniku, wyświetli się w maksymalnym możliwym rozmiarze bez zmiany proporcji niezależnie od tego, czy wymaga to zmniejszenia, czy powiększenia obrazu, aby to osiągnąć.
Dee2000
7
Wydaje się, że wyświetla się: blok nie jest już potrzebny.
actimel
3
Pamiętaj, że pytanie dotyczyło <img>samej szerokości i wysokości i myślę, że oznacza to, że musisz użyć, !importantaby obejść informacje o szerokości / wysokości znacznika.
Alexis Wilke
18
@AlexisWilke Reguły CSS zastępują atrybuty HTML. !importantnie jest potrzebne.
Jargs
5
Używanie go w Chrome, nie działa dla mnie, nawet z! Ważne
Ray
266

Bardzo mocno zmagałem się z tym problemem i ostatecznie doszedłem do tego prostego rozwiązania:

object-fit: cover;
width: 100%;
height: 250px;

Możesz dopasować szerokość i wysokość do swoich potrzeb, a właściwość dopasowania obiektu wykona dla Ciebie przycięcie.

Twoje zdrowie.

Théo T. Carranza
źródło
44
object-fitjest fantastyczny, świetna wskazówka! Istnieją pewne biblioteki bibliotek wypełniających, jeśli ktoś zastanawia się nad zgodnością z IE.
miękko,
7
Piękny pamiętać, to nie działa w IE choć
guival
1
Nie działa na aplikacjach SAMSUNG Signage Display WebApps.
Mär
3
Najlepsze dostępne rozwiązanie
Cynthia Sanchez,
10
Możesz także użyć object-fit: containi określić szerokość lub wysokość!
Broper,
236

Poniższe rozwiązania umożliwią powiększanie i zmniejszanie obrazu , w zależności od szerokości ramki nadrzędnej.

Wszystkie obrazy mają kontener nadrzędny o stałej szerokości wyłącznie do celów demonstracyjnych . W produkcji będzie to szerokość pudełka nadrzędnego.

Najlepsza praktyka (2018):

To rozwiązanie informuje przeglądarkę o renderowaniu obrazu z maksymalną dostępną szerokością i dostosowaniem wysokości jako wartości procentowej tej szerokości.

.parent {
  width: 100px;
}

img {
  display: block;
  width: 100%;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
  <img width="400" height="400" src="https://placehold.it/400x400">
</div>

Bardziej zaawansowane rozwiązanie:

Dzięki bardziej zaawansowanemu rozwiązaniu możesz przyciąć obraz niezależnie od jego wielkości i dodać kolor tła, aby zrekompensować przycięcie.

.parent {
  width: 100px;
}

.container {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  overflow: hidden;
  padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}

.container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
  <div class="container">
    <img width="640" height="220" src="https://placehold.it/640x220">
  </div>
</div>

W przypadku linii wypełniającej należy obliczyć proporcje obrazu, na przykład:

640px (w) = 100%
220px (h) = ?

640/220 = 2.909
100/2.909 = 34.37%

Zatem górne wypełnienie = 34,37%.

Aternus
źródło
1
Działa, ale w większości zastosowań powinna mieć maksymalną szerokość: 100% zamiast szerokości.
Dudeist
Nie wydaje mi się, że !importantjest to potrzebne.
Flimm
1
Z elementem nadrzędnym ustawionym na 100px. Jak to zadziała?
Remi
@Remi do celów demonstracyjnych. Na początku odpowiedzi dodałem wyjaśnienie.
Aternus,
@Flimm był wcześniej używany do problemów ze zgodnością, w 2016 roku nie jest to już potrzebne.
Aternus,
64

Właściwość background-size to np.> = 9, ale jeśli nie masz nic przeciwko, możesz użyć div za pomocą background-imagei ustawić background-size: contain:

div.image{
    background-image: url("your/url/here");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

Teraz możesz po prostu ustawić rozmiar div na cokolwiek zechcesz, a obraz nie tylko zachowa proporcje, ale zostanie również scentralizowany w pionie i poziomie w div. Tylko nie zapomnij ustawić rozmiarów na css, ponieważ divs nie mają atrybutu width / height na samym tagu.

Podejście to różni się od odpowiedzi setecs, dzięki temu obszar obrazu będzie stały i zdefiniowany przez ciebie (pozostawiając puste przestrzenie w poziomie lub w pionie w zależności od rozmiaru div i proporcji obrazu), podczas gdy odpowiedź setecs da ci pole, które dokładnie rozmiar przeskalowanego obrazu (bez pustych spacji).

Edycja: Zgodnie z dokumentacją wielkości tła MDN można symulować właściwość wielkości tła w IE8 przy użyciu zastrzeżonej deklaracji filtra:

Chociaż program Internet Explorer 8 nie obsługuje właściwości rozmiaru tła, możliwe jest emulowanie niektórych jego funkcji za pomocą niestandardowej funkcji -ms-filter:

-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
Hoffmann
źródło
2
wreszcie jedyne rozwiązanie CSS, które pozwala zmaksymalizować obraz przy zachowaniu jego proporcji, dziękuję. Na szczęście IE przed 9 jest coraz bardziej nieważny.
humanityANDpeace
2
Świetne rozwiązanie, dzięki! Pamiętaj też, że możesz zastąpić „zawiera” przez „osłonę”, jeśli chcesz całkowicie wypełnić div i przyciąć dodatkowe piksele, które nie pasują do proporcji
mbritto,
To powinna być poprawna odpowiedź. Uwielbiam to rozwiązanie. Utrzymuje twoje proporcje i jest łatwy do zrozumienia.
skolind
1
Chociaż jest to poprawna programowo odpowiedź, jeśli obraz „liczy się” w ten sposób, nie masz atrybutów img, więc zabijasz SEO.
fat_mike
Świetny! Było to jedyne z tych rozwiązań, które działało zarówno dla zdjęć portretowych i krajobrazowych, jak również dla kontenerów portretowych i krajobrazowych obrazu (np. Różniących się w zależności od rozmiaru okna) we wszystkich 4 kombinacjach, a także dodatkowo w IE11, co wydawało się dość wymóg. Dziękuję Ci!
cupiqi09
53

Bardzo podobne do niektórych odpowiedzi tutaj, ale w moim przypadku miałem obrazy, które czasami były wyższe, a czasem większe.

Ten styl działał jak urok, aby upewnić się, że wszystkie obrazy zajmują całą dostępną przestrzeń, zachowują współczynnik, a nie tną:

.img {
   object-fit: contain;
   max-width: 100%;
   max-height: 100%;
   width: auto;
   height: auto;
}
Moisés
źródło
object-fitdziała dla mnie, czy działa we wszystkich przeglądarkach?
Murtuza Zabuawala
Czy .imgklasa jest nadrzędna czy na obrazie? Czy możesz zrobić jsfiddle z przykładem zarówno portretów, jak i krajobrazów?
Projekt Adrian
19

Usuń właściwość „wysokość”.

<img src="big_image.jpg" width="900" alt=""/>

Określając oba, zmieniasz proporcje obrazu. Tylko ustawienie jednego spowoduje zmianę rozmiaru, ale zachowanie proporcji.

Opcjonalnie, aby ograniczyć przewymiarowanie:

<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
el Dude
źródło
nie mogę tego zrobić dla wszystkich zdjęć - wiele zdjęć jest już umieszczonych w wielu plikach HTML
Moonvader,
2
Ok. spróbuj img {max-width: 500px; wysokość: auto; max-height: 600px;}
el Dude
1
Przydatne informacje, takie jak ten komentarz, należy dodać do postu. W ten sposób możemy natychmiast zobaczyć, co wymyśliłeś.
Bram Vanroy
2
Minusem pominięcia heightatrybutu w imgznaczniku jest to, że przeglądarka nie może obliczyć, ile miejsca zajmie obraz przed pobraniem obrazu. Spowoduje to spowolnienie renderowania strony i może prowadzić do „przeskakiwania”.
Flimm
11

Po prostu dodaj to do swojego css, automatycznie się zmniejszy i rozszerzy z zachowaniem oryginalnego stosunku.

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Mark Bax
źródło
2
Jest to ta sama odpowiedź, co odpowiedź setec , z wyjątkiem użycia 100%zamiast określonej wartości w pikselach.
Flimm
5
display: block;jest niepotrzebne.
Flimm
Jest to idealne i działa z obrazami o dowolnej wielkości i proporcjach
Le Droid
8

Nie ma standardowy sposób, aby zachować proporcje obrazów z width, heighti max-widthokreślono razem.

Jesteśmy więc zmuszeni albo określić widthi heightzapobiec „przeskokom” strony podczas ładowania obrazów, albo użyć max-widthi nie określać wymiarów obrazów.

Podanie tylko width(bez height) zwykle nie ma większego sensu, ale możesz spróbować zastąpić heightatrybut HTML, dodając regułę IMG {height: auto; }do arkusza stylów.

Zobacz także powiązany błąd przeglądarki Firefox 392261 .

Marat Tanalin
źródło
dziękuję, działa w nowoczesnych wersjach IE, Opera, FF i Chrome. Potrzebuję trochę czasu, aby przetestować go w innych przeglądarkach.
moonvader,
7
Nie używaj !importantw CSS. To hack, który w końcu wróci, by cię prześladować.
Automatico
1
Nawet !importanttu nie potrzebujesz .
Flimm
8

Oto rozwiązanie:

img {
   width: 100%;
   height: auto;
   object-fit: cover;
}

Dzięki temu obraz zawsze będzie obejmował cały element nadrzędny (skalowanie w dół i w górę) i zachowa ten sam współczynnik kształtu.

Thomas Carlton
źródło
5

Ustaw klasę CSS tagu kontenera obrazu na image-class:

<div class="image-full"></div>

i dodaj to do swojego arkusza stylów CSS.

.image-full {
    background: url(...some image...) no-repeat;
    background-size: cover;
    background-position: center center;
}
Aleksandar Toplek
źródło
5

Aby zachować responsywny obraz przy jednoczesnym wymuszaniu określonego obrazu, możesz wykonać następujące czynności:

HTML:

<div class="ratio2-1">
   <img src="../image.png" alt="image">
</div>

I SCSS:

.ratio2-1 {
  overflow: hidden;
  position: relative;

  &:before {
    content: '';
    display: block;
    padding-top: 50%; // ratio 2:1
  }

  img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
  }
}

Można tego użyć do wymuszenia określonego współczynnika proporcji, niezależnie od rozmiaru obrazu przesyłanego przez autorów.

Dzięki @Kseso na http://codepen.io/Kseso/pen/bfdhg . Sprawdź ten adres URL, aby uzyskać więcej współczynników i działający przykład.

Remi
źródło
Podoba mi się to, ponieważ działa z okręgami / border-radius. Ale niestety, przycina obraz i nie radzi sobie tak dobrze z tworzeniem ramki dla obrazu w div, o ile próbowałem.
Jake
4

Aby wymusić dopasowanie obrazu do dokładnego rozmiaru, nie trzeba pisać zbyt wielu kodów. To takie proste

img{
    width: 200px;
    height: auto;
    object-fit: contain; /* Fit logo in the image size */
        -o-object-fit: contain; /* Fit logo fro opera browser */
    object-position: top; /* Set logo position */
        -o-object-position: top; /* Logo position for opera browser */
    }
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">

aislamfaisal
źródło
4

https://jsfiddle.net/sot2qgj6/3/

Oto odpowiedź, jeśli chcesz umieścić obraz ze stałym procentem szerokości , ale nie ze stałym pikselem szerokości .

Przyda się to w przypadku różnych rozmiarów ekranu .

Sztuczki są

  1. Za pomocą padding-topustawić wysokość od szerokości.
  2. Używanie position: absolutedo umieszczania obrazu w polu wypełnienia.
  3. Używając, max-height and max-widthaby upewnić się, że obraz nie będzie nad elementem nadrzędnym.
  4. za pomocą, display:block and margin: autoaby wyśrodkować obraz.

Skomentowałem także większość sztuczek w skrzypcach.


Znajduję też inne sposoby, aby to osiągnąć. W html nie będzie prawdziwego obrazu, więc osobiście wybieram najlepszą odpowiedź, gdy potrzebuję elementu „img” w html.

prosty css za pomocą tła http://jsfiddle.net/4660s79h/2/

obraz w tle ze słowem na górze http://jsfiddle.net/4660s79h/1/

koncepcja użycia pozycji absolutnej pochodzi stąd http://www.w3schools.com/howto/howto_css_aspect_ratio.asp

Choco Li
źródło
Nie działa to, jeśli „pierwotne pytanie zawiera„ wysokość i szerokość ”. Są chwile, kiedy chcesz wymusić szerokość i wysokość, a następnie powiększyć / zmniejszyć obraz zgodnie ze współczynnikiem kształtu.
Projekt Adrian
3

Możesz użyć tego:

img { 
    width: 500px; 
    height: 600px; 
    object-fit: contain; 
    position: relative; 
    top: 50%; 
    transform: translateY(-50%); 
}
użytkownik3334941
źródło
2

Możesz utworzyć div w ten sposób:

<div class="image" style="background-image:url('/to/your/image')"></div>

I użyj tego css, aby go stylizować:

height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover
Chun Yang
źródło
Spowoduje to rozciągnięcie div do 100% szerokości jego rodzica, ale nie utrzyma proporcji obrazu.
David Ball
Próbowałeś? Mam to działa jsfiddle.net/zuysj22w . Czy możesz pokazać swoją sprawę? @DavidBall
Chun Yang
Jest to podobne rozwiązanie do odpowiedzi Hoffmanna .
Flimm
2

Sugeruję, aby w ramach responsywnego podejścia najlepszą praktyką byłoby użycie jednostek Viewport i atrybutów min / max w następujący sposób:

img{
  display: block;
  width: 12vw;
  height:12vw;
  max-width:100%;
  min-width:100px;
  min-height:100px;
  object-fit:contain;
}
nodws
źródło
1

Spowoduje to zmniejszenie obrazu, jeśli jest zbyt duży dla określonego obszaru (jako minus, nie powiększy obrazu).

Rozwiązanie setec jest dobre dla „Shrink to Fit” w trybie automatycznym. Ale aby optymalnie ROZSZERZAĆ, aby zmieściło się w trybie „automatycznym”, musisz najpierw ustawić otrzymany obraz w temp id. Sprawdź, czy można go rozszerzyć na wysokość czy szerokość (w zależności od proporcji v / s proporcji twój blok wyświetlacza),

$(".temp_image").attr("src","str.jpg" ).load(function() { 
    // callback to get actual size of received image 

    // define to expand image in Height 
    if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
        $(".image").css('height', max_height_of_box);
        $(".image").css('width',' auto');
    } else { 
        // define to expand image in Width
        $(".image").css('width' ,max_width_of_box);
        $(".image").css('height','auto');
    }
    //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
    $(".image").attr("src","str.jpg");
});

To podejście jest przydatne, gdy otrzymane obrazy są mniejsze niż pole wyświetlania. Musisz zapisać je na serwerze w oryginalnym małym rozmiarze, a nie w rozszerzonej wersji, aby wypełnić swoje większe okno wyświetlacza, aby zaoszczędzić na rozmiarze i przepustowości.

Yselection Rajeev Shukla
źródło
Chociaż pytanie nie wyjaśniło tego, myślę, że OP mocno sugerowało, że szuka rozwiązania tylko CSS.
Flimm
0

img {
  max-width: 80px; /* Also works with percentage value like 100% */
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">

<p>Let's say the author of the HTML deliberately wants
  the height to be half the value of the width,
  this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">

Flimm
źródło
0

Co powiesz na użycie pseudoelementu do wyrównania w pionie? Ten mniej kodu dotyczy karuzeli, ale chyba działa na każdym kontenerze o stałym rozmiarze. Zachowa proporcje i wstawi @ szaro-ciemne paski na górze / dole lub w lewo / napisz dla najkrótszego wymiaru. W międzyczasie obraz jest wyśrodkowany poziomo przez wyrównanie tekstu i pionowo przez pseudo element.

    > li {
      float: left;
      overflow: hidden;
      background-color: @gray-dark;
      text-align: center;

      > a img,
      > img {
        display: inline-block;
        max-height: 100%;
        max-width: 100%;
        width: auto;
        height: auto;
        margin: auto;
        text-align: center;
      }

      // Add pseudo element for vertical alignment of inline (img)
      &:before {
        content: "";
        height: 100%;
        display: inline-block;
        vertical-align: middle;
      }
    }
Paul Bormans
źródło
0

Prezentacja pełnoekranowa:

img[data-attribute] {height: 100vh;}

Należy pamiętać, że jeśli wysokość portu widoku jest większa niż obraz, obraz naturalnie pogorszy się w stosunku do różnicy.

Jan
źródło
-1

Myślę, że w końcu jest to najlepsze rozwiązanie, łatwe i proste :

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Wiesz
źródło
1
Czy mógłbyś krótko wyjaśnić, dlaczego to rozwiązanie pomaga? (Wystarczy jedno zdanie.)
Aenadon
Po prostu dlatego, że obraz zachowa proporcje, podczas gdy maksymalna szerokość i maksymalna wysokość zapobiegnie powiększeniu go do kontenera
Uknow