Bagaimana cara "memotong" gambar persegi panjang menjadi persegi dengan CSS?

170

Saya tahu bahwa tidak mungkin untuk benar-benar mengubah gambar dengan CSS, itulah sebabnya saya memberi tanda kutip.

Yang ingin saya lakukan adalah mengambil gambar persegi panjang dan menggunakan CSS untuk membuatnya tampak persegi tanpa mengubah gambar sama sekali.

Saya pada dasarnya ingin mengubah ini:

masukkan deskripsi gambar di sini

Ke dalam ini:

masukkan deskripsi gambar di sini

novicePrgrmr
sumber
4
Apakah gambar-gambar ini adalah gambar latar belakang divs atau penting bagi SEO agar mereka tetap berada di tag <img>?
Michael
2
Apakah Anda sudah mencoba sesuatu? Ini agak sederhana dengan CSS3 background-positionatau pembungkus lama div overflow:hiddendan gambar dengan posisi relatif.
Fabrício Matté
Mereka pasti gambar latar belakang
novicePrgrmr
Lihat jawaban saya, saya pikir ini adalah opsi terbaik keseluruhan Anda. Ini menghindari elemen posisi.
Michael

Jawaban:

78

Dengan asumsi mereka tidak harus berada di tag IMG ...

HTML:

<div class="thumb1">
</div>

CSS:

.thumb1 { 
  background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
  width: 250px;
  height: 250px;
}

.thumb1:hover { YOUR HOVER STYLES HERE }

EDIT: Jika div perlu menautkan suatu tempat, sesuaikan saja HTML dan Styles seperti ini:

HTML:

<div class="thumb1">
<a href="#">Link</a>
</div>

CSS:

.thumb1 { 
  background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
  width: 250px;
  height: 250px;
}

.thumb1 a {
  display: block;
  width: 250px;
  height: 250px;
}

.thumb1 a:hover { YOUR HOVER STYLES HERE }

Catatan ini juga dapat dimodifikasi agar responsif, misalnya% lebar dan tinggi dll.

Michael
sumber
1
ini cara yang bagus untuk memposisikan DAN memotong dengan satu tag.
rlemon
8
Perhatikan juga bahwa saat mencetak, browser tiang menonaktifkan gambar latar belakang sehingga tidak akan muncul.
j08691
Itu dapat menangani: hover menyatakan juga. Jika div perlu terhubung di suatu tempat, tambahkan saja tag. Sedangkan untuk cetak, itu bisa diperbaiki dengan print.css? Perbaiki saya jika saya salah?
Michael
Sebenarnya, jujur ​​saja, dalam hal ini, dengan tag A cetakan akan mundur, dan dalam hal apa pun, Anda ingin menambahkan gaya CSS untuk memperbaikinya untuk dicetak.
Michael
1
Nevermind, saya mengubahnya height: 460px; width: 100%;dan berfungsi seperti pesona
novicePrgrmr
417

Solusi CSS murni tanpa pembungkus divatau kode tidak berguna lainnya:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}
Visi Sarang
sumber
12
Perhatikan bahwa ini sayangnya tidak berfungsi pada IE dan Edge atm. Lihat di sini untuk detail lebih lanjut tentang itu: stackoverflow.com/a/37792830/1398056
baoutch
2
apa yang kita tidak tahu ketinggian yang kita inginkan untuk membuatnya persegi dengan lebar otomatis
Aravind Reddy
3
Pada Juni 2018, tampaknya hanya IE11 (2,71%) tidak mendukung objek-fit, cukup baik untuk saya.
Ray
1
Pada tahun 2019 dukungan cukup bagus sekarang. Hanya 2,3% masih menggunakan IE 11. Solusi ini sangat mudah saya tidak bisa membantu tetapi menggunakannya karena yang lain sangat menyebalkan. Saya menghabiskan waktu berjam-jam untuk membuatnya bekerja dengan kode backend.
Paul Morris
3
Sudah waktunya untuk semua melupakan IE
iji
55
  1. Tempatkan gambar Anda dalam div.
  2. Berikan dimensi persegi eksplisit div Anda.
  3. Atur properti CSS overflow pada div ke hidden ( overflow:hidden).
  4. Masukkan imajinasi Anda di dalam div.
  5. Keuntungan.

Sebagai contoh:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>
j08691
sumber
5
Harus memastikan ke tengah atau setidaknya bermain dengan posisi gambar di dalam. Sampel OP terlihat berpusat (walaupun saya hanya menyebutkan ini dan tidak mengharapkan Anda untuk mengubah jawaban Anda sama sekali: P).
rlemon
1
@rlemon - maka OP dapat mengatur posisi div menjadi relatif dan posisi gambar menjadi absolut, dan mengubah atribut atas dan kiri.
j08691
6
Saya hanya menyebutkannya di depan seseorang; "Tapi sekarang semuanya sudah selaras!" -: P
rlemon
1
Ya itu akan menjadi penting bahwa itu berpusat
novicePrgrmr
32

Menggunakan ukuran latar belakang: penutup - http://codepen.io/anon/pen/RNyKzB

CSS:

.image-container {
  background-image: url('http://i.stack.imgur.com/GA6bB.png');
  background-size:cover;
  background-repeat:no-repeat;
  width:250px;
  height:250px;
}  

Markup:

<div class="image-container"></div>
Philip Nuzhnyy
sumber
1
Menggabungkan kemampuan keterpusatan jawaban mtronics, ia bekerja dengan baik, bahkan pada IE9.
Faker
14

Saya benar-benar menemukan masalah yang sama baru-baru ini dan berakhir dengan pendekatan yang sedikit berbeda (saya tidak dapat menggunakan gambar latar belakang). Memang membutuhkan sedikit jQuery meskipun untuk menentukan orientasi gambar (saya yakin Anda bisa menggunakan JS biasa saja).

Saya menulis posting blog tentang itu jika Anda tertarik pada penjelasan lebih lanjut tetapi kode ini cukup sederhana:

HTML:

<ul class="cropped-images">
  <li><img src="http://fredparke.com/sites/default/files/cat-portrait.jpg" /></li>
  <li><img src="http://fredparke.com/sites/default/files/cat-landscape.jpg" /></li>
</ul>

CSS:

li {
  width: 150px; // Or whatever you want.
  height: 150px; // Or whatever you want.
  overflow: hidden;
  margin: 10px;
  display: inline-block;
  vertical-align: top;
}
li img {
  max-width: 100%;
  height: auto;
  width: auto;
}
li img.landscape {
  max-width: none;
  max-height: 100%;
}

jQuery:

$( document ).ready(function() {

    $('.cropped-images img').each(function() {
      if ($(this).width() > $(this).height()) {
        $(this).addClass('landscape');        
      }
    });

});
FreddyBushBoy
sumber
Saya pikir ini lebih unggul daripada alternatif latar belakang CSS karena gambar adalah konten, bukan "gaya", sehingga mereka harus disimpan pada lapisan HTML. Juga memiliki mereka di CSS dan bukan HTML akan berdampak pada SEO halaman web Anda. Terima kasih!
Jose Florido
Ide yang bagus untuk meningkatkan ini adalah menambahkan $(this).load(function(){...di dalam setiap loop, jadi jQuery menunggu sedikit hingga gambar dimuat dan mendapatkan dimensi gambar nyata.
Jose Florido
14

Jika gambar dalam wadah dengan lebar responsif :

HTML

<div class="img-container">
  <img src="" alt="">
</div>

CSS

.img-container {
  position: relative;

  &::after {
    content: "";
    display: block;
    padding-bottom: 100%;
  }

  img {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}
JKL
sumber
Ini sangat bagus. Ini juga sangat fleksibel, karena setelah gambar dikuadratkan, Anda dapat membuatnya dilingkari dan melakukan hal-hal keren lainnya.
Rocky Kev
3

Saya memiliki masalah serupa dan tidak dapat "berkompromi" dengan gambar latar belakang. Saya datang dengan ini.

<div class="container">
    <img src="http://lorempixel.com/800x600/nature">
</div>

.container {
    position: relative;
    width: 25%; /* whatever width you want. I was implementing this in a 4 tile grid pattern. I used javascript to set height equal to width */
    border: 2px solid #fff; /* just to separate the images */
    overflow: hidden; /* "crop" the image */
    background: #000; /* incase the image is wider than tall/taller than wide */
}

.container img {
    position: absolute;
    display: block;
    height: 100%; /* all images at least fill the height */
    top: 50%; /* top, left, transform trick to vertically and horizontally center image */
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}

//assuming you're using jQuery
var h = $('.container').outerWidth();
$('.container').css({height: h + 'px'});

Semoga ini membantu!

Contoh: https://jsfiddle.net/cfbuwxmr/1/

Zach Botterman
sumber
2

Gunakan CSS: overflow:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}
Diodeus - James MacFarlane
sumber
3
Dimensi itu tidak terlalu persegi. :-)
isherwood
2
Tidak, kamu benar. Duh. Saya baru saja mengangkat ketinggian yang ada dari ukuran gambar OP, seperti robot yang terbakar habis pada sore hari.
Diodeus - James MacFarlane
Heh. Aku bersamamu di sana. :-)
isherwood
1

Baik gunakan div dengan dimensi persegi dengan gambar di dalam dengan kelas .testimg:

.test {
width: 307px;
height: 307px;
overflow:hidden
}

.testimg {
    margin-left: -76px

}

atau div persegi dengan latar belakang gambar.

.test2 {
width: 307px;
height: 307px;
    background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}

Berikut beberapa contoh: http://jsfiddle.net/QqCLC/1/

DIPERBARUI OLEH PUSAT GAMBAR

.test {
  width: 307px;
  height: 307px;
  overflow: hidden
}

.testimg {
  margin-left: -76px
}

.test2 {
  width: 307px;
  height: 307px;
  background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
<div class="test"><img src="http://i.stack.imgur.com/GA6bB.png" width="460" height="307" class="testimg" /></div>

<div class="test2"></div>

tech292
sumber
0

object-fit: cover akan melakukan apa yang Anda butuhkan.

Tapi itu mungkin tidak berfungsi di IE / Edge. Ikuti seperti yang ditunjukkan di bawah ini untuk memperbaikinya dengan hanya CSS untuk bekerja di semua browser .

Pendekatan yang saya ambil adalah memposisikan gambar di dalam wadah dengan absolut dan kemudian meletakkannya tepat di tengah menggunakan kombinasi:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Setelah itu di tengah, saya berikan pada gambar,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

Ini membuat gambar mendapatkan efek dari Object-fit: cover.


Berikut ini adalah demonstrasi dari logika di atas.

https://jsfiddle.net/furqan_694/s3xLe1gp/

Logika ini berfungsi di semua browser.


Gambar asli
Gambar asli

Dipotong Secara Vertikal
Gambar yang Dipotong Secara Vertikal

Dipotong Secara horizontal
Gambar yang Dipotong Secara Horizontal


Furqan Rahamath
sumber