Comment «recadrer» une image rectangulaire en carré avec CSS?

170

Je sais qu'il est impossible de modifier réellement une image avec CSS, c'est pourquoi je mets le recadrage entre guillemets.

Ce que j'aimerais faire, c'est prendre des images rectangulaires et utiliser CSS pour les faire apparaître carrées sans déformer l'image du tout.

J'aimerais essentiellement tourner ceci:

entrez la description de l'image ici

Dans ceci:

entrez la description de l'image ici

novicePrgrmr
la source
4
Ces images sont-elles des images d'arrière-plan de divs ou est-il important pour le référencement qu'elles restent dans les balises <img>?
Michael
2
Avez-vous encore essayé quelque chose? C'est assez simple avec CSS3 background-positionou l'ancien div wrapper avec overflow:hiddenet image avec un positionnement relatif.
Fabrício Matté
Ils pourraient être des images de fond à coup sûr
novicePrgrmr
Voir ma réponse, je pense que c'est votre meilleure option globale. Il évite le positionnement des éléments.
Michael

Réponses:

78

En supposant qu'ils ne doivent pas nécessairement figurer dans les balises 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: Si le div a besoin de créer un lien quelque part, ajustez simplement le HTML et les styles comme ceci:

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 }

Notez que cela pourrait également être modifié pour être réactif, par exemple% largeurs et hauteurs, etc.

Michael
la source
1
c'est une bonne façon de positionner ET de recadrer avec une seule balise.
rlemon
8
Notez également que lors de l'impression, les navigateurs principaux désactivent les images d'arrière-plan afin qu'elles ne s'affichent pas.
j08691
Il peut également gérer: les états de survol. Si le div doit créer un lien quelque part, ajoutez simplement une balise. Quant à l'impression, cela peut être corrigé avec print.css? Corrige moi si je me trompe?
Michael
En fait, pour être honnête, dans ce cas, avec une balise A, l'impression aurait un repli, et dans tous les cas, vous voudrez quand même ajouter des styles CSS pour résoudre ce problème pour l'impression.
Michael
1
Nevermind, je l'ai changé height: 460px; width: 100%;et cela fonctionne comme un charme
novicePrgrmr
418

Une solution CSS pure sans wrapper divou autre code inutile:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}
Vision Ruche
la source
12
Notez que cela ne fonctionne malheureusement pas sur IE et Edge atm. Voir ici pour plus de détails à ce sujet: stackoverflow.com/a/37792830/1398056
baoutch
2
qu'est-ce que nous ne savons pas à quelle hauteur nous voulons le rendre carré avec une largeur automatique
Aravind Reddy
3
En juin 2018, il semble que seul IE11 (2,71%) ne prend pas en charge l'ajustement aux objets, ce qui me convient.
Ray
1
En 2019, le support est plutôt bon maintenant. Seuls 2,3% utilisent encore IE 11. Cette solution est si simple que je ne peux m'empêcher de l'utiliser car les autres sont tellement pénibles que j'ai perdu des heures à essayer de la faire fonctionner avec le code backend.
Paul Morris
3
Il est temps de tout oublier IE
iji
55
  1. Placez votre image dans un div.
  2. Donnez à votre div des dimensions carrées explicites.
  3. Définissez la propriété de débordement CSS sur le div sur hidden ( overflow:hidden).
  4. Mettez votre imagination à l'intérieur du div.
  5. Profit.

Par exemple:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>
j08691
la source
5
Il faut veiller à centrer ou au moins jouer avec le positionnement de l'image à l'intérieur. L'exemple OP semble centré (même si je viens de mentionner cela et ne vous attendez pas du tout à changer votre réponse: P).
rlemon
1
@rlemon - alors l'OP pourrait définir la position du div sur relative et la position de l'image sur absolue, et modifier les attributs haut et gauche.
j08691
6
Je le mentionne juste avant que quelqu'un ne soit tout; "Mais tout est aligné maintenant!" -: P
rlemon
1
Oui, il serait crucial qu'il soit centré
novicePrgrmr
32

Utilisation de la taille de fond: couverture - 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;
}  

Balisage:

<div class="image-container"></div>
Philip Nuzhnyy
la source
1
Combinant la capacité de centrage de la réponse de mtronics, cela fonctionne bien, même sur IE9.
Faker
14

En fait, je suis tombé sur ce même problème récemment et je me suis retrouvé avec une approche légèrement différente (je ne pouvais pas utiliser d'images de fond). Cela nécessite cependant un petit peu de jQuery pour déterminer l'orientation des images (je suis sûr que vous pouvez utiliser JS à la place).

J'ai écrit un article de blog à ce sujet si vous êtes intéressé par plus d'explications mais le code est assez 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');        
      }
    });

});
FreddyBushBoy
la source
Je pense que cela est supérieur à l'alternative de fond CSS car les images sont du contenu, pas du "style", elles doivent donc être conservées sur la couche HTML. Les avoir également sur le CSS au lieu du HTML aura un effet sur le référencement de votre page Web. Merci!
Jose Florido
Une bonne idée pour améliorer cela est d'ajouter $(this).load(function(){...à l'intérieur de chaque boucle, donc jQuery attend un peu jusqu'à ce que l'image soit chargée et obtienne les dimensions réelles de l'image.
Jose Florido
14

Si l'image se trouve dans un conteneur avec une largeur réactive :

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
la source
C'est vraiment sympa. Il est également incroyablement flexible, car une fois l'image au carré, vous pouvez la faire encercler et faire d'autres choses intéressantes.
Rocky Kev
3

J'ai eu un problème similaire et je ne pouvais pas «faire de compromis» avec les images de fond. Je suis venu avec ça.

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

J'espère que cela t'aides!

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

Zach Botterman
la source
2

Utilisez CSS: overflow:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}
Diodeus - James MacFarlane
la source
3
Ces dimensions ne sont pas très carrées. :-)
isherwood
2
Non, tu as raison. Duh. Je soulevais juste la hauteur existante de la taille de l'image de l'OP, comme un robot brûlé le vendredi après-midi.
Diodeus - James MacFarlane
Il h. Je suis avec toi là-bas. :-)
isherwood
1

Soit utiliser un div avec des dimensions carrées avec l'image à l'intérieur avec la classe .testimg:

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

.testimg {
    margin-left: -76px

}

ou un carré div avec un arrière-plan de l'image.

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

Voici quelques exemples: http://jsfiddle.net/QqCLC/1/

MISE À JOUR POUR LES CENTRES D'IMAGE

.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
la source
0

object-fit: cover fera exactement ce dont vous avez besoin.

Mais cela pourrait ne pas fonctionner sur IE / Edge. Suivez comme indiqué ci-dessous pour le réparer avec juste CSS pour fonctionner sur tous les navigateurs .

L'approche que j'ai adoptée a consisté à positionner l'image à l'intérieur du conteneur avec un absolu , puis à la placer au centre en utilisant la combinaison:

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

Une fois qu'il est au centre, je donne à l'image,

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

Cela donne à l'image l'effet de Object-fit: cover.


Voici une démonstration de la logique ci-dessus.

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

Cette logique fonctionne dans tous les navigateurs.


Image originale
Image originale

Recadrée verticalement
Image recadrée verticalement

Recadrée horizontalement
Image recadrée horizontalement


Furqan Rahamath
la source