Como "recortar" uma imagem retangular em um quadrado com CSS?

170

Eu sei que é impossível realmente modificar uma imagem com CSS, e é por isso que coloco recortar entre aspas.

O que eu gostaria de fazer é pegar imagens retangulares e usar CSS para fazê-las parecer quadradas sem distorcer a imagem.

Eu basicamente gostaria de transformar isso:

insira a descrição da imagem aqui

Nisso:

insira a descrição da imagem aqui

novicePrgrmr
fonte
4
Essas imagens são imagens de fundo de divs ou é importante para o SEO que elas permaneçam nas tags <img>?
Michael
2
Você já tentou alguma coisa? Isso é bastante simples no CSS3 background-positionou no div wrapper antigo overflow:hiddene na imagem com posicionamento relativo.
Fabrício Matté 01/03
Eles poderiam ser imagens de fundo, com certeza
novicePrgrmr
Veja minha resposta, acho que essa é sua melhor opção geral. Evita elementos de posicionamento.
Michael

Respostas:

78

Supondo que eles não precisem estar em tags 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 }

Edição: Se a div precisa vincular em algum lugar basta ajustar HTML e estilos da seguinte forma:

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 }

Observe que isso também pode ser modificado para responder, por exemplo% larguras e alturas, etc.

Michael
fonte
1
Essa é uma ótima maneira de posicionar E cortar com uma única tag.
Rlemon #
8
Observe também que, ao imprimir, os navegadores de mastro desabilitam as imagens de plano de fundo para que não apareçam.
J08691 # 0113
Ele pode lidar com: estados de foco também. Se a div precisar vincular a algum lugar, adicione uma tag. Quanto à impressão, isso pode ser corrigido com print.css? Corrija-me se eu estiver errado?
Michael
Na verdade, para ser sincero, nesse caso, com uma tag A, a impressão teria uma queda e, em qualquer caso, você desejaria adicionar estilos CSS para corrigir isso de qualquer maneira.
Michael
1
Não importa, eu mudei para height: 460px; width: 100%;e funciona como um encanto
novicePrgrmr
417

Uma solução CSS pura, sem invólucro divou outro código inútil:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}
Vision Hive
fonte
12
Observe que, infelizmente, isso não está funcionando no atm do IE e Edge. Veja aqui para obter mais detalhes sobre isso: stackoverflow.com/a/37792830/1398056
baoutch
2
o que é que não sei a altura queremos torná-la quadrada com largura auto
Aravind Reddy
3
Em junho de 2018, parece que apenas o IE11 (2,71%) não suporta ajuste de objeto, o suficiente para mim.
Ray
1
Em 2019, o suporte é muito bom agora. Apenas 2,3% ainda estão usando o IE 11. Essa solução é tão fácil que não posso deixar de usá-la, porque as outras são uma dor que perdi horas tentando fazê-la funcionar com o código de back-end.
Paul Morris
3
É hora de todos esquecerem o IE
iji 03/02
55
  1. Coloque sua imagem em uma div.
  2. Dê à sua div dimensões quadradas explícitas.
  3. Defina a propriedade CSS overflow na div como hidden ( overflow:hidden).
  4. Coloque sua imaginação dentro da div.
  5. Lucro.

Por exemplo:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>
j08691
fonte
5
Deve-se garantir centralizar ou pelo menos brincar com o posicionamento da imagem dentro. A amostra do OP parece centrada (embora eu apenas mencione isso e não espere que você mude sua resposta: P).
Rlemon #
1
@rlemon - então o OP pode definir a posição da div como relativa e a posição da imagem como absoluta e ajustar os atributos superior e esquerdo.
J08691
6
Estou apenas mencionando isso antes que alguém seja tudo; "Mas está tudo alinhado agora!" -: P
rlemon
1
Sim, seria crucial que ele fique centralizado
novicePrgrmr
32

Usando o tamanho do plano de fundo: 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;
}  

Marcação:

<div class="image-container"></div>
Philip Nuzhnyy
fonte
1
Combinando a capacidade de centralização da resposta da mtronics, ela funciona bem, mesmo no IE9.
Faker 16/02
14

Na verdade, me deparei com esse mesmo problema recentemente e acabei com uma abordagem um pouco diferente (não consegui usar imagens de fundo). No entanto, é necessário um pouco de jQuery para determinar a orientação das imagens (tenho certeza de que você poderia usar JS simples).

Eu escrevi um post sobre isso se você estiver interessado em mais explicações, mas o código é bem simples:

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
fonte
Eu acho que isso é superior à alternativa de plano de fundo do CSS porque as imagens são conteúdo, não "estilo", portanto devem ser mantidas na camada HTML. Também tê-los no CSS, em vez do HTML, afetará o SEO da sua página da web. Obrigado!
Jose Florido
Uma boa idéia para melhorar isso é adicionar $(this).load(function(){...dentro de cada loop, para que o jQuery aguarde um pouco até que a imagem seja carregada e obtenha dimensões reais da imagem.
Jose Florido
14

Se a imagem estiver em um contêiner com uma largura responsiva :

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
fonte
Isso é muito legal. Também é incrivelmente flexível, pois uma vez que a imagem é quadrada, você pode fazer círculos e fazer outras coisas legais.
Rocky Kev
3

Eu tive um problema semelhante e não pude "comprometer" as imagens de plano de fundo. Eu vim com isso.

<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 isto ajude!

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

Zach Botterman
fonte
2

Use CSS: overflow:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}
Diodeus - James MacFarlane
fonte
3
Essas dimensões não são muito quadradas. :-)
isherwood
2
Não, você está certo. Duh. Eu estava apenas levantando a altura existente do tamanho da imagem do OP, como um robô queimado na sexta-feira à tarde.
Diodeus - James MacFarlane
Heh. Eu estou com você lá. :-) #
3100 isherwood
1

Use uma div com dimensões quadradas com a imagem dentro da classe .testimg:

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

.testimg {
    margin-left: -76px

}

ou uma div quadrada com um plano de fundo da imagem.

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

Aqui estão alguns exemplos: http://jsfiddle.net/QqCLC/1/

ATUALIZADO PARA OS CENTROS DE IMAGEM

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

object-fit: cover fará exatamente o que você precisa.

Mas pode não funcionar no IE / Edge. Siga como mostrado abaixo para corrigi-lo com apenas CSS para funcionar em todos os navegadores .

A abordagem adotada foi posicionar a imagem dentro do contêiner com absoluta e, em seguida, colocá-la no centro usando a combinação:

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

Uma vez no centro, dou a imagem,

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

Isso faz com que a imagem obtenha o efeito de Object-fit: cover.


Aqui está uma demonstração da lógica acima.

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

Essa lógica funciona em todos os navegadores.


Imagem original
Imagem original

Cortado verticalmente
Imagem Recortada Verticalmente

Cortado horizontalmente
Imagem cortada horizontalmente


Furqan Rahamath
fonte