Rozmiar obrazu CSS, jak wypełnić, a nie rozciągnąć?

415

Mam obraz i chcę ustawić określoną szerokość i wysokość (w pikselach)

Ale jeśli ustawię szerokość i wysokość za pomocą css ( width:150px; height:100px), obraz zostanie rozciągnięty i może być brzydki.

Jak wypełniać obrazy do określonego rozmiaru za pomocą CSS, a nie rozciągać go?

Przykład wypełnienia i rozciągnięcia obrazu:

Oryginalny obraz:

Oryginalny

Rozciągnięty obraz:

Rozciągnięty

Wypełniony obraz:

Wypełniony

Pamiętaj, że w powyższym przykładzie wypełnionego obrazu: najpierw rozmiar obrazu jest zmieniany na 150x255 (zachowany współczynnik kształtu), a następnie przycinany do rozmiaru 150x100.

Mahdi Ghiasi
źródło
Spróbuj po prostu ustawić widthi heightnależy odpowiednio dostosować
NewInTheBusiness
3
To rozciąga obraz. zobacz to: jsfiddle.net/D7E3E
Mahdi Ghiasi
Część obrazu nie zmienia rozmiaru!
Ali Ben Messaoud
3
Chris Coyier ma również kilka dobrych rozwiązań: css-tricks.com/perfect-full-page-background-image
ambiguousmouse
1
BARDZO WAŻNE: jest to niezwykle zła praktyka dla celów SEO. Jeśli używasz go jako obrazu tła, to działa dobrze, ale jeśli chcesz, aby obraz został znaleziony przez Google, NIE Zindeksuje się, jeśli jest to tylko obraz tła.
Alex Banman,

Odpowiedzi:

395

Jeśli chcesz użyć obrazu jako tła CSS, istnieje eleganckie rozwiązanie. Po prostu użyj coverlub containwe background-sizewłaściwości CSS3.

.container {
  width: 150px;
  height: 100px;
  background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: 50% 50%;
}
<div class="container"></div>

Podczas gdy coverotrzymasz skalowany obraz, containda ci skalowany obraz. Oba zachowają proporcje pikseli.

http://jsfiddle.net/uTHqs/ (przy użyciu okładki)

http://jsfiddle.net/HZ2FT/ (przy użyciu zawierają)

Takie podejście ma tę zaletę, że jest przyjazne dla wyświetlaczy Retina zgodnie z krótkim przewodnikiem Thomasa Fuchsa.

Warto wspomnieć, że obsługa przeglądarki dla obu atrybutów wyklucza IE6-8.

Marcelo De Polli
źródło
1
Ponieważ można zmienić rozmiar obrazu wyłącznie w CSS, pozwala to na użycie dużego obrazu, a następnie przeskalowanie go zgodnie z gęstością pikseli każdego urządzenia za pomocą zapytań o media.
Marcelo De Polli
1
Czy możesz wyjaśnić, dlaczego w tym przypadku pozycja tła wydaje się wskazywać pozycję środka obrazu, a nie jego lewy górny róg? Czy jest to konsekwencja rozmiaru tła: okładka?
matteo
1
mój obejmuje tylko cały DIV powiększając obraz. Nie widzę końca krzywej.
SearchForKnowledge
3
Do czego służy background-repeat: no-repeat;? Jeśli obraz zakrywa swój pojemnik, i tak się nie powtórzy.
lurkit
3
„położenie w tle” można również ustawić na „środek centrum”. np .: .container {... background-position: centrum centrum; }
Leo Ribeiro,
556

Możesz użyć właściwości css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Zobacz przykład tutaj

Dla IE istnieje polifill: https://github.com/anselmh/object-fit

afonsoduarte
źródło
11
Ciekawe, że można to zrobić również za pomocą imgtagów (nie tylko background-imagemetoda opisana w odpowiedzi powyżej). Dziękuję :)
Mahdi Ghiasi
44
Rozważając to jako opcję, należy pamiętać, że object-fit nie jest obsługiwana w wielu przeglądarkach .
joshreesjones
2
Niestety background-sizerzadko jest realnym rozwiązaniem w moich projektach. Jest mniej prawdopodobne, że otrzymasz jakąkolwiek korzyść z SEO i nie możesz podać tagu ALT, podpisu itp. Towarzyszącego obrazowi, w którym możesz chcieć zapewnić dodatkowy kontekst dla czytników ekranu.
Markus,
3
To jest fajne, ale nie ma obsługi IE. Żadne z wypełniaczy już nie działają.
Jake,
3
Po prostu używa object-fit: cover;to. Wielkie dzięki
Luka
67

Wzmocnienie na powyższym Odpowiedź @afonsoduarte ( NOT Przyjęty jeden) .
w przypadku korzystania z bootstrap


Istnieją trzy różnice:

  1. Zapewnienie width:100%stylu.
    Jest to przydatne, jeśli używasz bootstrap i chcesz, aby obraz rozciągał się na całą dostępną szerokość.

  2. Określenie heightwłaściwości jest opcjonalne. Możesz ją usunąć / zachować w razie potrzeby

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
  3. Nawiasem mówiąc, nie ma potrzeby podawania atrybutów heighti elementu, ponieważ zostaną one przesłonięte przez styl. więc wystarczy napisać coś takiego.widthimage

    <img class="cover" src="url to img ..."  />
Hakan Fıstık
źródło
1
Dokładnie tego szukałem.
Francis Lanthier
1
Potrzebujesz buziaka!
Qin Wang
dopasowanie obiektów nie działa z IE?
bgcode
1
jest 2020, myślę, że to dobry czas, aby porzucić IE
Hakan Fıstık
56

Jedynym prawdziwym sposobem jest umieszczenie wokół obrazu pojemnika i użycie overflow:hidden:

HTML

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

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

CSS sprawia problemy, gdy chcesz robić to, co chcesz i wyśrodkowować obraz, w jquery można szybko naprawić:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/

Dominic Green
źródło
1
Dzięki. działało, ale przycina obraz od góry . (patrz to: jsfiddle.net/x86Q7 ) Czy nie ma możliwości przycięcia obrazu z centrum ?
Mahdi Ghiasi,
1
@MahdiGhiasi: Zmień górne i lewe właściwości w .container img css !!
Ali Ben Messaoud
Mogę ustawić margin-topobraz na przykład 50px(patrz: jsfiddle.net/x86Q7/1 ), ale jak przyciąć go z prawdziwego centrum ? (Bez jQuery?)
Mahdi Ghiasi
2
Ahh przepraszam, nie widziałem twojego komentarza, ale dodałem jquery tylko incase :)
Dominic Green
1
Świetne rozwiązanie! Dla mnie pionowe wypełnienie było ważniejsze niż poziome, więc po prostu musiałem zmienić „szerokość: 100%” na „wysokość: 100%” dla klasy „.container img”. Dziękuję Ci!
deebs,
26

Rozwiązanie CSS bez JS i bez obrazu tła:

Metoda 1 „margin auto” (IE8 + - NIE FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Metoda 2 „transformacja” (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

Metodę 2 można wykorzystać do wyśrodkowania obrazu w pojemniku o stałej szerokości / wysokości. Oba mogą się przepełnić - a jeśli obraz jest mniejszy niż pojemnik, nadal będzie wyśrodkowany.

http://jsfiddle.net/5xjr05dt/3/

Metoda 3 „podwójne opakowanie” (IE8 + - NIE FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Metoda 4 „podwójne opakowanie ORAZ podwójny obraz” (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • Metoda 1 ma nieco lepsze wsparcie - musisz ustawić szerokość LUB wysokość obrazu!
  • Z prefiksami metoda 2 ma również przyzwoite wsparcie (od wersji 9 w górę) - Metoda 2 nie obsługuje Opery mini!
  • Metoda 3 wykorzystuje dwa owijarki - może przepełnić szerokość ORAZ wysokość.
  • Metoda 4 wykorzystuje podwójny obraz (jeden jako symbol zastępczy), co zapewnia dodatkowe obciążenie przepustowości, ale jeszcze lepszą obsługę przeglądarki.

Wydaje się, że metody 1 i 3 nie działają z Firefoksem

JT Houtenbos
źródło
To jedyny, który faktycznie działa (minus rozwiązania js). Dzięki!
Jake,
Ogranicza się to do przepełnienia wysokości lub szerokości, ale jest ciekawym rozwiązaniem.
Jake
1
@Jake - Możliwe jest przepełnienie szerokości ORAZ wysokości metodą 2 powyżej - zobacz moją zaktualizowaną odpowiedź z dodatkowym skrzypkiem.
JT Houtenbos
Tak. To zdecydowanie świetna odpowiedź. Oszukam się jeszcze trochę. To było trochę dziwne dla obrazu szerszego niż wyższy, który musiał być responsywny, ale jest wiele aplikacji do tego.
Jake
1
@Jake - Cool - Znalazłem trzecią metodę centrowania w poziomie. Rozszerzyłem tę metodę, aby obsługiwała również centrowanie pionowe. Opublikuję mój dodatek jako trzecią metodę powyżej. Wydaje się, że jest to dowód na IE7 + (być może nawet niższy). Oto oryginalna odpowiedź: stackoverflow.com/questions/3300660/…
JT Houtenbos,
10

Innym rozwiązaniem jest umieszczenie obrazu w pojemniku o pożądanej szerokości i wysokości. Korzystając z tej metody, nie musisz ustawiać obrazu jako obrazu tła elementu.

Następnie możesz to zrobić za pomocą imgznacznika i po prostu ustawić maksymalną szerokość i maksymalną wysokość elementu.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

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

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

Teraz, gdy zmienisz rozmiar kontenera, obraz automatycznie powiększy się tak bardzo, jak to możliwe, bez wychodzenia poza granice i zniekształcania.

Jeśli chcesz wyśrodkować obraz w pionie i poziomie, możesz zmienić css kontenera na:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Oto JS Fiddle http://jsfiddle.net/9kUYC/2/

Earl3s
źródło
To nie to samo co okładka w CSS, gdzie jeden z uzyskanych wymiarów jest zawsze powyżej 100% (lub równy w przypadku krawędzi)
Miroshko
Nie, to rozwiązanie zapewnia, że ​​nigdy nie zostanie rozciągnięte powyżej 100%, o to właśnie chodziło w tej części pytania. Nie chcieli, aby obraz był zniekształcony lub wyrastał poza oryginalne wymiary.
Earls
3
Pytanie brzmiało „Jak wypełnić” przykład wypełnionego obrazu, który jest oczywiście przycięty.
Miroshko,
Ale co, jeśli potrzebujesz, aby obraz był responsywny? Określenie określonej szerokości i wysokości nie zadziała 😕
Ricardo Zea
2
Właśnie tego potrzebowałem. Dzięki!
Nico Rodsevich
5

Opierając się na odpowiedzi @Dominic Green za pomocą jQuery, oto rozwiązanie, które powinno działać dla obrazów, które są albo szersze niż są wysokie, albo wyższe niż są szerokie.

http://jsfiddle.net/grZLR/4/

Prawdopodobnie istnieje bardziej elegancki sposób obsługi JavaScript, ale to działa.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();
ramdog
źródło
5
  • Nie używa tła css
  • Tylko 1 div, aby go przyciąć
  • Przeskalowano do minimalnej szerokości, aby zachować właściwy współczynnik kształtu
  • Kadrowanie od środka (w pionie i poziomie, możesz to dostosować za pomocą góry, lewej i transformacji)

Zachowaj ostrożność, jeśli używasz motywu lub czegoś innego, często deklarują img maksymalną szerokość na 100%. Nie musisz nic robić. Przetestuj to :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}
dmegatool
źródło
To jest odpowiedź szukałem.
Marcos Buarque,
To właśnie chciałem robić przez długi czas, dziękuję;)
Szef COTIGA
4

Pomogłem zbudować wtyczkę jQuery o nazwie Fillmore , która obsługuje background-size: coverprzeglądarki, które ją obsługują, i ma pewien podkład dla tych, którzy tego nie robią. Spójrz!

Aidan Feldman
źródło
4

Myślę, że na tę odpowiedź jest już późno. W każdym razie mam nadzieję, że pomoże to komuś w przyszłości. Napotkałem problem z ustawieniem kart pod kątem. Wyświetlane są karty dla szeregu zdarzeń. Jeśli szerokość obrazu zdarzenia jest duża dla karty, obraz powinien zostać pokazany przez przycięcie z dwóch stron i wysokość 100%. Jeśli wysokość obrazu jest długa, dolna część obrazu jest przycinana, a szerokość wynosi 100%. Oto moje czyste rozwiązanie CSS:

wprowadź opis zdjęcia tutaj

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}
Nodirabegimxonoyim
źródło
nie mogę pojąć, jak to działa, ale działa. Musisz ustawić rozpiętość absolutnie na górze: 0; po prawej: 0; na dole: 0; po lewej: 0 wewnątrz względnie umieszczonego elementu nadrzędnego, aby go zwymiarować.
Mike
Dziękuję za opinię drogi Mike, cieszę się, że było to pomocne. Czy chcesz, żebym zaktualizował odpowiedź z twoim komentarzem?
Nodirabegimxonoyim
3

Spróbuj czegoś takiego: http://jsfiddle.net/D7E3E/4/

Używanie kontenera z przepełnieniem: ukryty

EDYCJA: @Dominic Green mnie pokonał.

woutr_be
źródło
Dzięki. działało, ale przycina obraz od góry . (patrz to: jsfiddle.net/x86Q7 ) Czy nie ma możliwości przycięcia obrazu z centrum ?
Mahdi Ghiasi,
Może to być dość trudne z CSS, to najlepsze, co mogłem wymyślić z jsfiddle.net/D7E3E/5
woutr_be
Tak, aby poprawnie wyśrodkować, powinieneś użyć jQuery, może być znacznie łatwiejsze.
woutr_be
3

Spowoduje to wypełnienie zdjęć do określonego rozmiaru, bez rozciągania lub przycinania

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

/*Scale down will take the necessary specified space that is 150px x 100px without stretching the image*/
    object-fit:scale-down;
}
Manoj Selvin
źródło
2

Aby dopasować obraz do pełnego ekranu, spróbuj:

powtórzenie w tle: okrągłe;

suyash1798
źródło
0
<div class="container">
     <img src="http://i.stack.imgur.com/2OrtT.jpg"/>
</div>

<style>
.container {
       width: 150px;
       height: 100px;
       overflow: hidden;
}
</style>
użytkownik3181614
źródło