Come "ritagliare" un'immagine rettangolare in un quadrato con CSS?


170

So che è impossibile modificare effettivamente un'immagine con CSS, motivo per cui ho messo il ritaglio tra virgolette.

Quello che mi piacerebbe fare è prendere immagini rettangolari e usare i CSS per farle apparire quadrate senza distorcere affatto l'immagine.

Fondamentalmente mi piacerebbe girare questo:

inserisci qui la descrizione dell'immagine

In questo:

inserisci qui la descrizione dell'immagine


4
Queste immagini sono immagini di sfondo di div o è importante che SEO rimangano nei tag <img>?
Michael

2
Hai già provato qualcosa? Questo è piuttosto semplice con CSS3 background-positiono il vecchio div wrapper con overflow:hiddene l'immagine con relativo posizionamento.
Fabrício Matté,

Potrebbero essere sicuramente immagini di sfondo
principiantePrgrmr

Vedi la mia risposta, penso che questa sia l'opzione migliore in assoluto. Evita gli elementi di posizionamento.
Michael

Risposte:


78

Supponendo che non debbano essere nei 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: Se il div ha bisogno di collegarsi da qualche parte basta regolare HTML e stili in questo modo:

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 }

Nota che questo potrebbe anche essere modificato per essere reattivo, ad esempio% larghezze e altezze ecc.


1
questo è un bel modo per posizionare E ritagliare con un singolo tag.
rlemon

8
Si noti inoltre che durante la stampa, i browser mast disabilitano le immagini di sfondo in modo che non vengano visualizzate.
j08691

Può gestire: anche gli stati al passaggio del mouse. Se il div ha bisogno di collegarsi da qualche parte, basta aggiungere un tag. Per quanto riguarda la stampa, che può essere risolto con print.css? Correggimi se sbaglio?
Michael

In realtà, a dire il vero, in questo caso, con un tag A la stampa avrebbe un ritorno, e in ogni caso, si vorrebbe aggiungere stili CSS per risolvere questo problema per la stampa comunque.
Michael

1
Non importa, l'ho cambiato in height: 460px; width: 100%;e funziona come un incantesimo
novizioPrgrmr

417

Una soluzione CSS pura senza wrapper divo altro codice inutile:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}

12
Si noti che questo purtroppo non funziona su IE e Edge atm. Vedi qui per maggiori dettagli su che: stackoverflow.com/a/37792830/1398056
baoutch

2
cos'è che non conosciamo l'altezza che vogliamo per renderla quadrata con larghezza automatica
Aravind Reddy

3
A partire da giugno 2018, sembra che solo IE11 (2,71%) non supporti l'adattamento agli oggetti, abbastanza buono per me.
Ray,

1
Nel 2019 il supporto ora è abbastanza buono. Solo il 2,3% sta ancora usando IE 11. Questa soluzione è così semplice che non posso fare a meno di usarla perché gli altri sono così dolorosi che ho perso ore a cercare di farlo funzionare con il codice di backend.
Paul Morris,

3
È tempo di dimenticare tutti IE
iji

55
  1. Posiziona la tua immagine in un div.
  2. Dai al tuo div dimensioni quadrate esplicite.
  3. Impostare la proprietà di overflow CSS sul div su hidden ( overflow:hidden).
  4. Metti la tua immagine dentro il div.
  5. Profitto.

Per esempio:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>

5
Deve assicurarsi di centrare o almeno giocare con il posizionamento dell'immagine all'interno. L'esempio OP sembra centrato (anche se ho appena menzionato questo e non mi aspetto che tu cambi la tua risposta: P).
rlemon

1
@rlemon - quindi l'OP potrebbe impostare la posizione del div su relativa e la posizione dell'immagine su assoluta, e modificare gli attributi superiore e sinistro.
j08691

6
Lo sto solo menzionando prima che qualcuno sia tutto; "Ma adesso è tutto allineato a sinistra!" -: P
rmonmon

1
Sì, sarebbe cruciale che sia centrato
novizioPrgrmr

32

Utilizzando la dimensione dello sfondo: copertina - 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>

1
Combinando la capacità di centraggio della risposta di mtronics, funziona bene, anche su IE9.
Faker,

14

Recentemente mi sono imbattuto in questo stesso problema e ho finito con un approccio leggermente diverso (non sono stato in grado di utilizzare immagini di sfondo). Richiede un po 'di jQuery per determinare l'orientamento delle immagini (sono sicuro che potresti usare JS semplice invece).

Ho scritto un post sul blog se sei interessato a maggiori spiegazioni ma il codice è piuttosto semplice:

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

});

Penso che questo sia superiore all'alternativa di sfondo CSS perché le immagini sono contenuti, non "stile", quindi dovrebbero essere mantenute sul livello HTML. Anche averli sul CSS anziché sull'HTML avrà un effetto sul SEO della tua pagina web. Grazie!
Jose Florido,

Una buona idea per migliorare questo è quella di aggiungere $(this).load(function(){...all'interno di ogni ciclo, quindi jQuery attende un po 'fino a quando l'immagine non viene caricata e ottiene dimensioni reali dell'immagine.
Jose Florido,

14

Se l'immagine si trova in un contenitore con una larghezza reattiva :

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

Questo è davvero carino È anche incredibilmente flessibile, poiché una volta che l'immagine è quadrata, puoi quindi renderla cerchiata e fare altre cose interessanti.
Rocky Kev,

3

Ho avuto un problema simile e non ho potuto "scendere a compromessi" con le immagini di sfondo. Ho pensato a questo.

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

Spero che questo ti aiuti!

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



1

Utilizzare un div con dimensioni quadrate con l'immagine all'interno con la classe .testimg:

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

.testimg {
    margin-left: -76px

}

o un div quadrato con uno sfondo dell'immagine.

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

Ecco alcuni esempi: http://jsfiddle.net/QqCLC/1/

AGGIORNATO COSÌ I CENTRI DI IMMAGINE

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


0

object-fit: cover farà esattamente ciò di cui hai bisogno.

Ma potrebbe non funzionare su IE / Edge. Seguire come mostrato di seguito per risolverlo con solo CSS per funzionare su tutti i browser .

L'approccio che ho seguito è stato di posizionare l'immagine all'interno del contenitore con assoluta e quindi posizionarla al centro usando la combinazione:

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

Una volta che è al centro, io do all'immagine,

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

Questo fa sì che l'immagine ottenga l'effetto di Object-fit: cover.


Ecco una dimostrazione della logica sopra.

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

Questa logica funziona in tutti i browser.


Immagine originale
Immagine originale

Ritagliata verticalmente
Immagine ritagliata verticalmente

Ritagliata orizzontalmente
Immagine ritagliata orizzontalmente


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.