191 votes

Comment recadrer et centrer automatiquement une image

Étant donné une image arbitraire, je veux recadrer un carré du centre de l'image et l'afficher dans un carré donné.

Cette question est similaire à celle-ci : CSS affiche une image redimensionnée et recadrée mais comme je ne connais pas la taille de l'image, je ne peux pas utiliser les marges définies.

1 votes

L'élément doit-il être une balise image, ou peut-il être un div avec une propriété background-image ?

0 votes

Tant que je peux définir l'image par le biais de mon système de création de modèles, cela n'a pas d'importance. C'est plutôt laid, mais je suppose que les styles en ligne fonctionneront.

372voto

Russ Ferri Points 1643

La solution consiste à utiliser une image d'arrière-plan centrée dans un élément dont les dimensions correspondent à celles de l'image rognée.


Exemple de base

(voir en action)

Balisage

<div class="center-cropped" 
     style="background-image: url('path/to/image.jpg');">
</div>​

CSS

.center-cropped {
    width: 100px;  // change to desired width.
    height: 100px; // change to desired height.
    background-position: center center;
    background-repeat: no-repeat;
}​

Exemple avec img étiquette

Cette version conserve le img afin de ne pas perdre la possibilité de glisser ou de faire un clic droit pour enregistrer l'image. Credit to Parker Bennett pour l'astuce de l'opacité.

(voir en action)

Balisage

<div class="center-cropped" 
     style="background-image: url('path/to/image.jpg');">
    <img src="path/to/image.jpg" />
</div>

CSS

.center-cropped {
    width: 100px;  // change to desired width.
    height: 100px; // change to desired height.
    background-position: center center;
    background-repeat: no-repeat;
    overflow: hidden;
}

/* Set the image to fill its parent and make transparent */
.center-cropped img {
   min-height: 100%;
   min-width: 100%;

   /* IE 8 */
   -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
   /* IE 5-7 */
   filter: alpha(opacity=0);
   /* modern browsers */
   opacity: 0;
}

0 votes

TomSawyer Oui, l'utilisation de background-image n'est pas idéale. S'il est important d'avoir une balise img pour le référencement, les lecteurs d'écran ou autre, vous pouvez en inclure une et la masquer visuellement. jsfiddle.net/WN2kT

54 votes

Vous pouvez utiliser background-size: cover; pour que l'image rétrécisse ou remplisse la division de manière appropriée tout en conservant le rapport d'aspect original.

0 votes

N'oubliez pas le background-repeat : no-repeat ; si votre image peut être plus petite (en hauteur) que la hauteur de votre div.

90voto

gluecksmelodie Points 861

Je cherchais une solution purement CSS utilisant img (pas à la manière d'une image d'arrière-plan).

J'ai trouvé cette brillante façon d'atteindre le but sur recadrer les vignettes avec css :

.thumbnail {
  position: relative;
  width: 200px;
  height: 200px;
  overflow: hidden;
}
.thumbnail img {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 100%;
  width: auto;
  -webkit-transform: translate(-50%,-50%);
      -ms-transform: translate(-50%,-50%);
          transform: translate(-50%,-50%);
}
.thumbnail img.portrait {
  width: 100%;
  height: auto;
}

Elle est similaire à la réponse de @Nathan Redblur, mais elle permet également de réaliser des portraits.

Ça marche comme un charme pour moi. La seule chose que vous devez savoir sur l'image est s'il s'agit d'un portrait ou d'un paysage, afin de définir l'indicateur d'image. .portrait donc j'ai dû utiliser un peu de Javascript pour cette partie.

3 votes

Sachez simplement que les transformations CSS ne sont disponibles qu'à partir de la version 9 d'IE.

6 votes

Cela devrait être la réponse.

1 votes

L'OP a dit "image arbitraire", il ne pouvait donc pas savoir d'emblée si l'image était plus haute que large.

69voto

Roych Points 523

Essayez ceci : Définissez les dimensions de votre image et utilisez cette ligne dans votre CSS :

object-fit: cover;

3 votes

Pas très bien soutenu : caniuse.com/#feat=objet-fit EDIT : en fait, comme d'habitude, seuls les navigateurs MS échouent à ce niveau... cela représente tout de même une bonne partie de l'utilisation :/.

1 votes

Cela fait exactement ce dont j'ai besoin :)

1 votes

Les seuls navigateurs largement utilisés qui ne prennent pas en charge cette fonctionnalité sont Internet Explorer 11 et Edge. En fonction de votre public, la prise en charge actuelle se situe probablement autour de 85-90%, ce qui pourrait rendre cette solution viable pour certains scénarios.

24voto

Nathan Redblur Points 394

Exemple avec img mais sans background-image

Cette solution permet de conserver le img afin de ne pas perdre la possibilité de faire glisser ou de cliquer avec le bouton droit de la souris pour enregistrer l'image, mais sans background-image Il suffit de centrer et de recadrer avec css.

Le rapport d'aspect est maintenu, sauf pour les images très hautes. (voir le lien)

(voir en action)

Balisage

<div class="center-cropped">
    <img src="http://placehold.it/200x150" alt="" />
</div>

CSS

div.center-cropped {
  width: 100px;
  height: 100px;
  overflow:hidden;
}
div.center-cropped img {
  height: 100%;
  min-width: 100%;
  left: 50%;
  position: relative;
  transform: translateX(-50%);
}

0 votes

Essayez celui-ci... si l'image est plus petite que le conteneur, elle sera centrée, sinon elle sera recadrée. jsfiddle.net/3ts4rm24/1

0 votes

Pourquoi utilisez-vous left: 50% con transform: translateX(-50%) ?

0 votes

left est une position liée au conteneur translate est liée à l'élément si votre conteneur est de 100px, et votre image de 20px, left mettra l'image entre la position 50px-70px. Pour remédier à cela, nous rétablissons la taille de l'image avec translateX(-50%) et votre image sera alors entre 40px-60px. Ej : si votre conteneur est de 100px, left: 50% de ce conteneur rightMiddle = conteneur/2 - élément/2

9voto

pferdefleisch Points 1951

J'ai créé une directive angularjs en utilisant les réponses de @Russ et @Alex

Cela pourrait être intéressant en 2014 et au-delà :P

html

<div ng-app="croppy">
  <cropped-image src="http://placehold.it/200x200" width="100" height="100"></cropped-image>
</div>

js

angular.module('croppy', [])
  .directive('croppedImage', function () {
      return {
          restrict: "E",
          replace: true,
          template: "<div class='center-cropped'></div>",
          link: function(scope, element, attrs) {
              var width = attrs.width;
              var height = attrs.height;
              element.css('width', width + "px");
              element.css('height', height + "px");
              element.css('backgroundPosition', 'center center');
              element.css('backgroundRepeat', 'no-repeat');
              element.css('backgroundImage', "url('" + attrs.src + "')");
          }
      }
  });

lien vers le violon

4 votes

Salut les downvoters. Veuillez laisser un commentaire pour que je puisse mettre à jour ma réponse s'il y a une erreur. Je n'aime pas donner de fausses informations. A la vôtre.

0 votes

Pas un downvoter, mais ce n'est pas une question Angular et votre réponse n'est pas pertinente. @pferdefleisch

1 votes

@mburn c'est logique. Cela fait 3 ans et cela semble probablement un peu déplacé ou odieux maintenant. Je le laisse cependant en place parce que les votes positifs sur mon commentaire me disent qu'au moins quelques personnes peuvent le trouver utile (ou ils n'aiment pas les votes négatifs sans commentaires).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X