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


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.


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

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>

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>

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

});

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

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/



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>


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


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.