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.

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).


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.


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%.


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')";

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;
}

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;"/>

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;
}

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 .


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.


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;
}

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.


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">


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


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%); 
}

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

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;
}

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.


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">


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;
      }
    }

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.


-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;
}

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
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.