Ubah skala gambar agar pas dengan kotak pembatas

117

Apakah ada solusi khusus css untuk menskalakan gambar ke dalam kotak pembatas (menjaga rasio aspek)? Ini berfungsi jika gambar lebih besar dari penampung:

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

Contoh:

Tapi saya ingin memperbesar gambar sampai dimensinya 100% dari container.

Thomas Guillory
sumber
Apakah yang Anda maksud seperti tinggi: 100% dan lebar: 100%? apakah Anda memiliki dimensi yang ingin Anda raih? jika tidak, Anda juga bisa meregangkan gambar dan memaksanya mencapai dimensi tersebut juga.
mikevoermans
@mikevoermans Lihat dua contoh pertama saya: Saya ingin mengatur gambar sampai salah satu dimensinya 100% dan yang lainnya <= 100%
Thomas Guillory
@jacktheripper Melestarikan rasio aspek tentu saja ...
Thomas Guillory
@gryzzly Contoh berbicara sendiri! Jika mereka melihat contoh, itu jelas.
Thomas Guillory
@Artimuz Saya sangat tidak setuju. Tiga dari jawaban atas pertanyaan Anda (termasuk saya) menunjukkan bahwa itu TIDAK jelas.
Khan

Jawaban:

94

Catatan: Meskipun ini adalah jawaban yang diterima, jawaban di bawah ini lebih akurat dan saat ini didukung di semua browser jika Anda memiliki opsi untuk menggunakan gambar latar belakang.

Tidak, tidak ada satu-satunya cara CSS untuk melakukan ini di kedua arah. Anda bisa menambahkan

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

Untuk elemen agar selalu memiliki lebar 100% dan secara otomatis menskalakan tinggi ke rasio aspek, atau kebalikannya:

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

untuk selalu menskalakan ke tinggi maksimum dan lebar relatif. Untuk melakukan keduanya, Anda perlu menentukan apakah rasio aspek lebih tinggi atau lebih rendah dari penampungnya, dan CSS tidak dapat melakukan ini.

Alasannya adalah CSS tidak tahu seperti apa halaman tersebut. Ini menetapkan aturan sebelumnya, tetapi hanya setelah itu elemen-elemen itu dirender dan Anda tahu persis ukuran dan rasio apa yang Anda hadapi. Satu-satunya cara untuk mendeteksinya adalah dengan JavaScript.


Meskipun Anda tidak mencari solusi JS, saya akan tetap menambahkannya jika seseorang mungkin membutuhkannya. Cara termudah untuk menangani ini dengan JavaScript adalah menambahkan kelas berdasarkan perbedaan rasio. Jika rasio lebar-tinggi kotak lebih besar dari gambar, tambahkan kelas "fillwidth", jika tidak tambahkan kelas "fillheight".

Stephan Muller
sumber
7
Sebenarnya ada solusi: mengatur ukuran latar belakang CSS3 agar memuat. Lihat jawaban saya.
Thomas Guillory
Anda benar sekali. Meskipun sudah satu setengah tahun kemudian, saya mengedit posting saya.
Stephan Muller
4
Saya berpendapat bahwa ini adalah jawaban yang benar untuk pertanyaan yang diajukan, yaitu apa itu CSS untuk tag img. Ini relevan karena secara semantik tag img adalah konten, gambar sebagai latar belakang div tidak. Sementara beberapa keadaan membuat ini tidak praktis (jika Anda tidak tahu rasio gambar vs. wadah), bagi yang lain itu tepat. Terima kasih.
duncanwilcox
173

Berkat CSS3, ada solusinya!

Solusinya adalah dengan menempatkan gambar sebagai background-imagedan kemudian mengatur background-sizeke contain.

HTML

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

CSS

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

Uji di sini: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Kompatibilitas penuh dengan browser terbaru: http://caniuse.com/background-img-opts

Untuk menyelaraskan div di tengah, Anda dapat menggunakan variasi ini:

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}
Thomas Guillory
sumber
1
Bagus, meskipun jawaban saya tidak salah (Anda bertanya tentang img secara khusus) ini adalah solusi yang bagus dan saya seharusnya memikirkannya. Satu-satunya masalah adalah bahwa IE 8 masih sangat banyak digunakan sehingga saya tidak ingin mengandalkan ini dulu, tapi tetap bagus.
Stephan Muller
6
Setel ke "cover" jika Anda tidak ingin letterboxing: background-size: mengandung;
arxpoetica
3
Perlu dicatat bahwa Anda dapat menyuntikkan URL gambar dengan HTML: <div class=image style="background-image: url('/images/foo.jpg');"></div>. Semua gaya lainnya harus diterapkan dengan CSS.
Andrey Mikhaylov - lolmaus
14
Menurut saya ini pendekatan yang buruk. Dengan mengubahnya menjadi gambar latar belakang, Anda menghapus makna semantik gambar di HTML.
animuson
14
@animuson: Itu masih membantu saya karena saya menggunakan HTML / CSS untuk laporan tercetak, dan tidak bisa memberikan penjelasan tentang semantik :)
Christian Wattengård
37

Inilah solusi hackish yang saya temukan:

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

Ini akan memperbesar gambar sepuluh kali lipat, tetapi membatasinya hingga 10% dari ukuran akhirnya - sehingga membatasinya ke container.

Berbeda dengan background-imagesolusinya, ini juga akan bekerja dengan <video>elemen.

Contoh interaktif:

Vladimir Panteleev
sumber
1
Saya suka solusi ini. Tidak hanya itu benar-benar menjawab pertanyaan (saya tahu, pemikiran yang luar biasa), ini bekerja dengan baik di semua browser modern tanpa harus menggunakan Javascript!
ndm13
2
Saya ingin sekali melihat biola itu. Dalam pengujian saya menempatkan img dalam wadah 400x400, img baru saja terpotong di sudut
cyberwombat
3
Jawaban bagus! @Yashua Anda perlu menambahkan transform-origin: top leftuntuk menghentikan pemotongan. / Zombie
XwipeoutX
Cemerlang. Satu-satunya kekhawatiran saya adalah kemungkinan hilangnya kualitas gambar di browser dengan kode yang buruk, tetapi secara teori seharusnya berfungsi dengan baik!
Codemonkey
Menarik, tetapi tidak berfungsi di Chrome. Menghasilkan baris gambar yang dipotong.
MattK
23

Hari ini, katakan saja object-fit: contain. Dukungan adalah segalanya kecuali IE: http://caniuse.com/#feat=object-fit

Glenn Maynard
sumber
3
IE hanya memiliki sekitar 16% pangsa pasar sekarang pada saat penulisan ini (09/12/2016 10:56 pagi) dan terus menyusut, jadi ini jawaban terbaik untuk saya: D
Zhang
8
Jangan edit jawaban orang lain untuk memperbaiki hal-hal selain kesalahan ketik atau tautan rusak. Saya tidak akan mengatakan sesuatu yang kekanak-kanakan seperti "Ada polyfill untuk browser sampah" dalam jawaban SO, dan saya tidak menghargai jawaban saya yang diedit agar terlihat seperti yang saya katakan. jika Anda ingin menggunakan kata-kata Anda, tuliskan dalam jawaban Anda sendiri.
Glenn Maynard
Saya akan mengatakan, bahwa bukan IE masalahnya, tetapi Edge. Menurut caniuse object-fitmasih dalam pengembangan untuk itu.
BairDev
Ini seharusnya menjadi salah satu jawaban pilihan teratas tahun 2017 dan seterusnya ... Menurut tautan caniuse di atas, 90% dari semua pengguna di seluruh dunia sekarang menggunakan browser yang mendukung ini
fgblomqvist
Saya baru saja memposting jawaban yang berfungsi dengan dan tanpa object-fit: stackoverflow.com/a/46456673/474031
gabrielmaldi
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;*/
}
Deke
sumber
5

Anda dapat melakukannya dengan CSS murni dan dukungan browser lengkap, baik untuk gambar dengan panjang vertikal maupun horizontal secara bersamaan.

Berikut cuplikan yang berfungsi di Chrome, Firefox, dan Safari (keduanya menggunakan object-fit: scale-down, dan tanpa menggunakannya):

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>

gabrielmaldi.dll
sumber
2

Solusi lain tanpa gambar latar belakang dan tanpa memerlukan wadah (meskipun ukuran maksimal kotak pembatas harus diketahui):

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


Jika penggunaan wadah diperlukan, maka lebar-maksimal dan tinggi-maksimal dapat diatur ke 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;
}

Untuk ini, Anda akan memiliki sesuatu seperti:

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

Contoh ini untuk meregangkan gambar secara proporsional agar sesuai dengan seluruh jendela. Sebuah improvisasi ke kode yang benar di atas adalah menambahkan$( 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();
});

Ada dua kondisi if. Yang pertama terus memeriksa apakah tinggi gambar kurang dari div dan menerapkan .fillheightkelas sementara yang berikutnya memeriksa lebar dan menerapkan .fillwidthkelas. Dalam kedua kasus, kelas lain dihapus menggunakan.removeClass()

Ini CSS nya

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

Anda dapat mengganti 100vhdengan 100%jika Anda ingin meregangkan gambar dengan dalam sebuah div. Contoh ini untuk meregangkan gambar secara proporsional agar sesuai dengan seluruh jendela.

Tn. JCRP
sumber
OP secara khusus meminta pendekatan hanya css.
Colt McCormack
0

Apakah Anda ingin meningkatkan skala tetapi tidak ke bawah?

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

Namun, ini tidak mengunci rasio aspek.

ericosg
sumber
5
Cobalah untuk sedikit lebih menjelaskan ekspektasi Anda sebelum memilih jawaban seseorang. Terutama ketika mereka telah menjawab pertanyaan Anda sebelum Anda menjawab pertanyaan Anda dengan mengedit.
Khan
2
Selain itu, cobalah untuk lebih sopan. Tidak ada yang akan membantu Anda jika Anda berbicara seperti itu.
Misha Reyzlin
@Artimuz Maaf jika saya salah membimbing Anda, tetapi bagi saya tidak jelas bahwa Anda ingin mempertahankan rasio aspek, itulah mengapa saya mengomentarinya secara khusus. Selain itu, Anda akan melihat bahwa saya menempelkan cuplikan kode Anda dari contoh. Saya percaya menjaga tinggi: otomatis; akan melakukannya untuk Anda jika Anda menentukan lebar.
ericosg
0

Saya telah menggunakan tabel untuk memusatkan gambar di dalam kotak. Itu menjaga rasio aspek dan menskalakan gambar dengan cara yang benar-benar ada di dalam kotak. Jika gambar lebih kecil dari kotak, maka gambar akan ditampilkan seperti di tengah. Kode di bawah ini menggunakan kotak lebar 40px dan tinggi 40px. (Tidak begitu yakin seberapa baik kerjanya karena saya menghapusnya dari kode lain yang lebih kompleks dan menyederhanakannya sedikit)

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>
Antti
sumber
0

Cara terbersih dan termudah untuk melakukan ini:

Pertama beberapa 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>

Ini seharusnya berhasil!

Robert Eetheart
sumber
0

Ini membantu saya:

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

Kemudian pada elemen (Anda dapat menggunakan javascript atau kueri media untuk menambahkan daya tanggap):

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

Semoga ini membantu!

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

Saya mengedit jawaban saya untuk menjelaskan lebih lanjut soluton saya karena saya mendapat suara negatif.

Dengan gaya yang diatur seperti yang ditunjukkan di atas dalam css, sekarang div html berikut akan menunjukkan gambar selalu pas dengan lebar dan akan menyesuaikan rasio tinggi lebar ke lebar. Dengan demikian gambar akan diskalakan agar sesuai dengan kotak pembatas seperti yang ditanyakan dalam pertanyaan.

<div class="boundingbox"><img src="image.jpg"/></div>
zeeawan
sumber
Jawaban ini hanya berfungsi jika kotak lebih tinggi daripada lebarnya.
XwipeoutX