¿Cómo "recortar" una imagen rectangular en un cuadrado con CSS?


170

Sé que es imposible modificar realmente una imagen con CSS, por eso pongo recortar entre comillas.

Lo que me gustaría hacer es tomar imágenes rectangulares y usar CSS para que parezcan cuadradas sin distorsionar la imagen.

Básicamente me gustaría convertir esto:

ingrese la descripción de la imagen aquí

Dentro de esto:

ingrese la descripción de la imagen aquí


44
¿Estas imágenes son imágenes de fondo de divs o es importante para SEO que permanezcan en etiquetas <img>?
Michael

2
¿Ya probaste algo? Esto es bastante simple, ya sea con CSS3 background-positiono con el antiguo contenedor contenedor con una overflow:hiddenimagen con posicionamiento relativo.
Fabrício Matté

Seguramente podrían ser imágenes de fondo
novicePrgrmr

Vea mi respuesta, creo que esta es su mejor opción en general. Evita elementos de posicionamiento.
Michael

Respuestas:


78

Asumiendo que no tienen que estar en las etiquetas 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 }

EDITAR: si el div necesita vincularse en algún lugar, simplemente ajuste HTML y Estilos de la siguiente manera:

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 }

Tenga en cuenta que esto también podría modificarse para que responda, por ejemplo,% de anchuras y alturas, etc.


1
Esta es una buena manera de posicionar Y recortar con una sola etiqueta.
rlemon

8
Tenga en cuenta también que al imprimir, los navegadores de mástil desactivan las imágenes de fondo para que no aparezcan.
j08691

Puede manejar: estados de desplazamiento también. Si el div necesita vincularse en algún lugar, simplemente agregue una etiqueta. En cuanto a la impresión, ¿eso se puede arreglar con print.css? ¿Corrígeme si me equivoco?
Michael

En realidad, para ser honesto, en este caso, con una etiqueta A, la impresión tendría un retroceso y, en cualquier caso, querría agregar estilos CSS para corregir esto de todos modos.
Michael

1
No importa, lo cambié height: 460px; width: 100%;y funciona de
maravilla

418

Una solución CSS pura sin envoltorio divu otro código inútil:

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

12
Tenga en cuenta que desafortunadamente esto no funciona en IE y Edge atm. Consulte aquí para obtener más detalles al respecto: stackoverflow.com/a/37792830/1398056
baoutch

2
¿Qué es lo que no sabemos la altura que queremos que sea cuadrado con ancho automático?
Aravind Reddy

3
A partir de junio de 2018, parece que solo IE11 (2.71%) no admite el ajuste de objetos, lo suficientemente bueno para mí.
Ray

1
En 2019, el soporte es bastante bueno ahora. Solo el 2.3% todavía usa IE 11. Esta solución es tan fácil que no puedo evitar usarla porque las otras son una molestia. He desperdiciado horas tratando de que funcione con el código de back-end.
Paul Morris

3
Es hora de olvidarse de IE
iji

55
  1. Coloca tu imagen en un div.
  2. Dale a tu div dimensiones cuadradas explícitas.
  3. Establezca la propiedad de desbordamiento CSS en el div en hidden ( overflow:hidden).
  4. Pon tu imaginación dentro del div.
  5. Lucro.

Por ejemplo:

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

55
Debe asegurarse de centrar o al menos jugar con el posicionamiento de la imagen dentro. La muestra OP parece centrada (aunque solo menciono esto y no espero que cambie su respuesta en absoluto: P).
rlemon

1
@rlemon: entonces el OP podría establecer la posición del div en relativa y la posición de la imagen en absoluta, y ajustar los atributos superior e izquierdo.
j08691

66
Solo lo menciono antes de que alguien lo sea todo; "¡Pero ahora todo está alineado!" -: P
rlemon

1
Sí, sería crucial que esté centrado
novicePrgrmr

32

Usando background-size: cover - 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;
}  

Margen:

<div class="image-container"></div>

1
Combinando la capacidad de centrado de la respuesta de mtronics, funciona bien, incluso en IE9.
Falsificador

14

En realidad, me encontré con este mismo problema recientemente y terminé con un enfoque ligeramente diferente (no pude usar imágenes de fondo). Sin embargo, requiere un poco de jQuery para determinar la orientación de las imágenes (sin embargo, estoy seguro de que podría usar JS simple).

Escribí una publicación de blog al respecto si está interesado en más explicaciones, pero el código es bastante simple:

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

});

Creo que esto es superior a la alternativa de fondo CSS porque las imágenes son contenido, no "estilo", por lo que deben mantenerse en la capa HTML. También tenerlos en el CSS en lugar del HTML tendrá un efecto en el SEO de su página web. ¡Gracias!
Jose Florido

Una buena idea para mejorar esto es agregar $(this).load(function(){...dentro de cada bucle, por lo que jQuery espera un poco hasta que la imagen se carga y obtiene dimensiones de imagen reales.
Jose Florido

14

Si la imagen está en un contenedor con un ancho de respuesta :

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

Esto es realmente lindo También es increíblemente flexible, ya que una vez que la imagen está cuadrada, puedes hacerla circular y hacer otras cosas geniales.
Rocky Kev

3

Tuve un problema similar y no pude "comprometerme" con las imágenes de fondo. Se me ocurrió esto.

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

¡Espero que esto ayude!

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



1

Utilice un div con dimensiones cuadradas con la imagen dentro con la clase .testimg:

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

.testimg {
    margin-left: -76px

}

o un div cuadrado con un fondo de la imagen.

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

Aquí hay algunos ejemplos: http://jsfiddle.net/QqCLC/1/

ACTUALIZADO PARA LOS CENTROS DE IMAGEN

.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 Hará exactamente lo que necesita.

Pero podría no funcionar en IE / Edge. Siga como se muestra a continuación para solucionarlo solo con CSS para que funcione en todos los navegadores .

El enfoque que tomé fue colocar la imagen dentro del contenedor con absoluta y luego colocarla justo en el centro usando la combinación:

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

Una vez que está en el centro, le doy a la imagen,

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

Esto hace que la imagen obtenga el efecto de Object-fit: cover.


Aquí hay una demostración de la lógica anterior.

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

Esta lógica funciona en todos los navegadores.


Imagen original
Imagen original

Recortada verticalmente
Imagen recortada verticalmente

Recortada horizontalmente
Imagen recortada horizontalmente


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.