Comment recadrer et centrer automatiquement une image


159

Étant donné toute image arbitraire, je souhaite recadrer un carré à partir 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 je ne connais pas la taille de l'image, je ne peux donc pas utiliser les marges définies.


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

tant que je peux définir l'image via mon système de modèles, cela n'a pas d'importance. un peu moche, mais je suppose que les styles en ligne fonctionneront.
Jonathan Ong

Réponses:


320

Une solution consiste à utiliser une image de fond centrée dans un élément dimensionné aux dimensions rognées.


Exemple de base

.center-cropped {
  width: 100px;
  height: 100px;
  background-position: center center;
  background-repeat: no-repeat;
}
<div class="center-cropped" 
     style="background-image: url('http://placehold.it/200x200');">
</div>


Exemple avec imgtag

Cette version conserve la imgbalise afin que nous ne perdions pas la possibilité de faire glisser ou de cliquer avec le bouton droit pour enregistrer l'image. Nous remercions Parker Bennett pour le tour d'opacité.

.center-cropped {
  width: 100px;
  height: 100px;
  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;
}
<div class="center-cropped" 
     style="background-image: url('http://placehold.it/200x200');">
  <img src="http://placehold.it/200x200" />
</div>


object-fit/-position

Voir les navigateurs pris en charge .

La spécification Images CSS3 définit les propriétés object-fitet object-positionqui, ensemble, permettent un meilleur contrôle sur l'échelle et la position du contenu d'image d'un imgélément. Avec ceux-ci, il sera possible d'obtenir l'effet souhaité:

.center-cropped {
  object-fit: none; /* Do not scale the image */
  object-position: center; /* Center the image within the element */
  height: 100px;
  width: 100px;
}
<img class="center-cropped" src="http://placehold.it/200x200" />


45
Vous pouvez utiliser background-size: cover;pour réduire l'image ou remplir la division de manière appropriée tout en conservant le rapport hauteur / largeur d'origine.
Nick

7
Lorsque vous utilisez background-image, vous devez ajouter background-size: cover pour dimensionner correctement l'image recadrée: Voir jsfiddle.net/bw6ct
Kris Erickson

2
On m'a dit que de nos jours, Google connaît les images transparentes et cachées, donc imgles attributs de altfourmi titleseront perdus pour votre référencement.
Victor Sergienko

6
dans webkit, vous pouvez également utiliser object-fit: cover;directement sur la balise img qui semble un peu plus sémantique.
Ben

2
J'ai utilisé object-fit: cover pour obtenir l'effet désiré de ne pas perdre le rapport hauteur / largeur, de couvrir le carré et de recadrer si nécessaire
Daniel Handojo

79

Je cherchais une solution CSS pure utilisant des imgbalises (pas la manière de l'image de fond).

J'ai trouvé ce moyen génial d'atteindre l'objectif sur les vignettes de recadrage 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;
}

C'est similaire à la réponse de @Nathan Redblur, mais cela permet également des images de portrait.

Fonctionne comme un charme pour moi. La seule chose que vous devez savoir sur l'image est de savoir si elle est portrait ou paysage afin de définir la .portraitclasse, j'ai donc dû utiliser un peu de Javascript pour cette partie.


3
Sachez simplement que les transformations CSS ne sont disponibles que dans IE 9 et supérieur.
Simon East

5
Cela devrait être la réponse.
Wes Modes

OP a dit "image arbitraire", donc je ne saurais pas à l'avance si l'image était plus haute que large.
opyate

11
Si vous mettez min-height: 100%; min-width: 100%; au lieu de hauteur: 100%; largeur: auto; vous n'avez pas besoin de la classe img.portrait.
user570605

1
meilleure solution combinée à la suggestion @ user570605
albanx

45

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

object-fit: cover;

3
pas très bien supporté: caniuse.com/#feat=object-fit EDIT: en fait, comme d'habitude, seuls les navigateurs MS échouent à cela ... cela représente cependant une bonne partie de l'utilisation: /
Brian H.

1
Cela fait exactement ce dont j'ai besoin :)
hcarreras

1
Les seuls navigateurs largement utilisés qui ne prennent pas en charge cela sont Internet Explorer 11 et Edge. En fonction de votre public, le soutien actuel se situe probablement autour de 85 à 90%, ce qui pourrait le rendre viable pour certains scénarios.
Husky

Roi! solution géniale !!
itzhar

1
il y a un bon tutoriel à ce sujet: medium.com/@chrisnager
Pietro La Grotta

23

Exemple avec imgtag mais sansbackground-image

Cette solution conserve la imgbalise 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-imagesimplement centrer et recadrer avec css.

Maintenez le rapport hauteur / largeur correct sauf dans les images très hautes. (vérifiez le lien)

(vue 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%);
}

Essayez celui-ci ... si l'image est plus petite que le conteneur, elle sera centrée
KnF

8

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

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 violon


3
Hiya downvoters. Veuillez laisser un commentaire afin que je puisse mettre à jour ma réponse en cas d'erreur. Je n'aime pas donner de fausses informations. À votre santé.
mraaroncruz

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

1
@mburn qui a du sens. Cela fait 3 ans et cela semble probablement un peu déplacé ou désagréable maintenant. Je vais toutefois le laisser en place car les votes positifs sur mon commentaire me disent qu'au moins quelques personnes peuvent le trouver utile (ou ils n'aiment tout simplement pas les votes négatifs sans commentaires).
mraaroncruz

2

Essaye ça:

#yourElementId
{
    background: url(yourImageLocation.jpg) no-repeat center center;
    width: 100px;
    height: 100px;
}

Gardez à l'esprit que widthet heightne fonctionnera que si votre élément DOM a une disposition (un élément affiché en bloc, comme un divou un img). Si ce n'est pas le cas (un span, par exemple), ajoutez display: block;aux règles CSS. Si vous n'avez pas accès aux fichiers CSS, déposez les styles en ligne dans l'élément.


dans la plupart des cas, ce CSS est utilisé à plusieurs reprises avec différentes images. par conséquent, il est inévitable de définir l'image d'arrière-plan en ligne.
Raptor

0

Il existe une autre façon de recadrer l'image centrée:

.thumbnail{position: relative; overflow: hidden; width: 320px; height: 640px;}
.thumbnail img{
    position: absolute; top: -999px; bottom: -999px; left: -999px; right: -999px;
    width: auto !important; height: 100% !important; margin: auto;
}
.thumbnail img.vertical{width: 100% !important; height: auto !important;}

La seule chose dont vous aurez besoin est d'ajouter la classe "verticale" aux images verticales, vous pouvez le faire avec ce code:

jQuery(function($) {
    $('img').one('load', function () {
        var $img = $(this);
        var tempImage1 = new Image();
        tempImage1.src = $img.attr('src');
        tempImage1.onload = function() {
            var ratio = tempImage1.width / tempImage1.height;
            if(!isNaN(ratio) && ratio < 1) $img.addClass('vertical');
        }
    }).each(function () {
        if (this.complete) $(this).load();
    });
});

Remarque: "! Important" est utilisé pour remplacer les attributs largeur / hauteur possibles sur la balise img.

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.