Pourcentage de redimensionnement de l'image CSS d'elle-même?

109

J'essaye de redimensionner une image avec un pourcentage d'elle-même. Par exemple, je veux juste réduire l'image de moitié en la redimensionnant à 50%. Mais l'application width: 50%;redimensionnera l'image à 50% de l'élément conteneur (l'élément parent qui peut-être le<body> par exemple).

La question est, puis-je redimensionner l'image avec un pourcentage d'elle-même sans utiliser javascript ou côté serveur? (Je n'ai aucune information directe sur la taille de l'image)

Je suis à peu près sûr que vous ne pouvez pas faire cela, mais je veux juste voir s'il existe une solution intelligente uniquement CSS. Merci!

Min Ming Lo
la source
Il prendra le pourcentage de l'élément contenant si vous utiliseriez width: <number>%. Je ne pense pas qu'il y ait moyen de le faire!
Aniket

Réponses:

111

J'ai 2 méthodes pour vous.

Méthode 1. Démo sur jsFiddle

Cette méthode redimensionne l'image uniquement visuelle, pas ses dimensions réelles dans DOM, et l'état visuel après le redimensionnement centré au milieu de la taille d'origine.

html:

<img class="fake" src="example.png" />

css:

img {
  -webkit-transform: scale(0.5); /* Saf3.1+, Chrome */
     -moz-transform: scale(0.5); /* FF3.5+ */
      -ms-transform: scale(0.5); /* IE9 */
       -o-transform: scale(0.5); /* Opera 10.5+ */
          transform: scale(0.5);
             /* IE6–IE9 */
             filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.9999619230641713, M12=-0.008726535498373935, M21=0.008726535498373935, M22=0.9999619230641713,SizingMethod='auto expand');
}​

Remarque sur la prise en charge du navigateur : les statistiques des navigateurs sont affichées en ligne danscss.

Méthode 2. Démo sur jsFiddle

html:

<div id="wrap">
    <img class="fake" src="example.png" />
    <div id="img_wrap">
        <img class="normal" src="example.png" />
    </div>
</div>

css:

#wrap {
    overflow: hidden;
    position: relative;
    float: left;
}

#wrap img.fake {
    float: left;
    visibility: hidden;
    width: auto;
}

#img_wrap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

#img_wrap img.normal {
    width: 50%;
}​

Remarque: img.normal etimg.fakec'est la même image.
Remarque sur la prise en charge du navigateur: cette méthode fonctionnera dans tous les navigateurs, car tous les navigateurs prennent en chargecss propriétés utilisées dans method.

La méthode fonctionne de cette manière:

  1. #wrap et #wrap img.fake avoir du flux
  2. #wrapa overflow: hiddenpour que ses dimensions soient identiques à l'image intérieure (img.fake )
  3. img.fakeest le seul élément à l'intérieur #wrapsansabsolute positionnement pour ne pas casser la deuxième étape
  4. #img_wrapa un absolutepositionnement à l'intérieur #wrapet s'étend en taille à l'ensemble de l'élément (#wrap )
  5. Le résultat de la quatrième étape est que #img_wrap a les mêmes dimensions que l'image.
  6. En réglant width: 50%sur img.normal, sa taille est 50%de #img_wrap, et donc 50%de la taille de l' image originale.
Vladimir Starkov
la source
Cela ne redimensionne pas l'image à 50% de sa taille d'origine, c'est maintenant 50% du parent de img_wrap ..
Wesley
Consultez ma réponse mise à jour pour tenter de résoudre le problème. Qu'est-ce que tu penses?
Wesley
Je pense qu'il devrait être possible d'utiliser display: none au lieu de la visibilité, comme dans mon code. Dans votre exemple, l'espace pour la fausse image cachée est toujours `` réservé '', ce qui gâche le flux si vous mettiez du contenu autour d'elle
Wesley
c'est impossible, car l'astuce principale consiste en deux balises imbriquées et flottantes.
Vladimir Starkov
1
La transform:scale()solution a cependant un gros problème. Il n'interagit pas bien avec le modèle de boîte CSS. Je veux dire qu'il ne réagit pas avec elle du tout , donc vous obtenez la mise en page qui ressemble tout faux. Voir: jsfiddle.net/kahen/sGEkt/8
kahen
47

HTML:

<span>
    <img src="example.png"/>
</span>

CSS:

span {
    display: inline-block;
}
img {
    width: 50%;
}

Cela doit être l'une des solutions les plus simples utilisant l'approche de l'élément conteneur.

Lorsque vous utilisez l'approche de l'élément conteneur, cette question est une variante de cette question . L'astuce consiste à laisser l'élément conteneur envelopper l'image enfant afin qu'elle ait une taille égale à celle de l'image non dimensionnée. Ainsi, lors de la définition de la widthpropriété de l'image en tant que valeur de pourcentage, l'image est mise à l'échelle par rapport à son échelle d'origine.

Certains des autres propriétés permettant de valeurs et feuille rétractable propriété sont: float: left/right, position: fixedet min/max-width, comme mentionné dans la question liée. Chacun a ses propres effets secondaires, mais ce display: inline-blockserait un choix plus sûr. Matt l'a mentionné float: left/rightdans sa réponse, mais il l'a attribué à tort overflow: hidden.

Démo sur jsfiddle


Edit: Comme mentionné par Trojan , vous pouvez également profiter du nouveau module de dimensionnement intrinsèque et extrinsèque CSS3 :

HTML:

<figure>
    <img src="example.png"/>
</figure>

CSS:

figure {
    width: intrinsic;
}
img {
    width: 50%;
}

Cependant, toutes les versions de navigateur populaires ne le prennent pas en charge au moment de la rédaction .

Communauté
la source
@Anyone comment corriger les bordures de travées qui ne s'effondrent pas? fiddle
CoR
C'était exactement ce dont j'avais besoin ... quelque chose de simple et rapide, merci. Je l'ai utilisé comme ceci: HTML: <img src="https://www.google.com/images/srpr/logo11w.png"/> CSS: img { display: inline-block; width: 15%; }
Chnikki
Pour les futurs lecteurs: la valeur correcte à définir figureest à width: fit-content;partir de maintenant. La prise en charge des navigateurs est également bien meilleure aujourd'hui.
Dániel Kis-Nagy le
12

Essayer la zoompropriété

<img src="..." style="zoom: 0.5" />

Edit: Apparemment, FireFox ne prend pas en charge la zoompropriété. Tu devrais utiliser;

-moz-transform: scale(0.5);

pour FireFox.

Emir Akaydın
la source
4
Il n'existe pas de propriété CSS telle que "zoom" et elle n'est prise en charge par personne d'autre que IE. C'est une chose propriétaire de Microsoft et non standard.
Rob
9
Malheureusement, ces informations sont obsolètes. Zoom est actuellement pris en charge par les navigateurs Internet Explorer, Chrome et Safari. FireFox et Opera ne le prennent pas encore en charge. C'est pourquoi j'ai ajouté la partie d'édition. IE est le premier à le supporter mais pas le seul.
Emir Akaydın
Selon ce lien, Opera semble également prendre en charge le zoom. FireFox est le seul qui ne prend pas en charge. fix-css.com/2011/05/css-zoom
Emir Akaydın
2
C'est pourquoi IE a perdu la moitié de sa part de marché au cours des 8 dernières années. Si vous ne pouvez pas compter de manière fiable sur les navigateurs pour prendre en charge quelque chose, vous n'avez pas de terrain d'entente. La spécification est rédigée par les fournisseurs de navigateurs eux-mêmes. S'ils ne le mettent pas là-dedans, ne comptez pas dessus ou vous écrirez plusieurs lignes de balisage comme vous l'avez fait. Ce n'est pas encore une fois 1998.
Rob
1
Je ne sais pas si vous avez remarqué mais le "zoom" est pris en charge par Internet Explorer, Chrome, Safari et Opera. c'est la preuve que le "zoom" n'est pas spécifique au fournisseur. seul FireFox diffère. donc je répète ma question. quelle est la solution propre avec la propriété css compitible? ma réponse est la meilleure réponse jusqu'à ce que quelqu'un trouve une solution standard appropriée.
Emir Akaydın
5

Une autre solution consiste à utiliser:

<img srcset="example.png 2x">

Il ne validera pas car l' srcattribut est obligatoire, mais il fonctionne (sauf sur n'importe quelle version d'IE car il srcsetn'est pas pris en charge).

Benface
la source
2

C'est en fait possible, et j'ai découvert à quel point par accident lors de la conception de mon premier site de conception réactive à grande échelle.

<div class="wrapper">
  <div class="box">
    <img src="/logo.png" alt="">
  </div>
</div>

.wrapper { position:relative; overflow:hidden; }

.box { float:left; } //Note: 'float:right' would work too

.box > img { width:50%; }

Le débordement: hidden donne la hauteur et la largeur du wrapper, malgré le contenu flottant, sans utiliser le hack clearfix. Vous pouvez ensuite positionner votre contenu en utilisant des marges. Vous pouvez même faire du div wrapper un bloc en ligne.

Mat
la source
2

C'est un fil très ancien mais je l'ai trouvé en cherchant une solution simple pour afficher la capture d'écran de la rétine (haute résolution) sur un écran de résolution standard.

Il existe donc une solution HTML uniquement pour les navigateurs modernes:

<img srcset="image.jpg 100w" sizes="50px" src="image.jpg"/>

Cela indique au navigateur que l'image a deux fois la dimension de sa taille d'affichage prévue. La valeur est proportionnelle et n'a pas besoin de refléter la taille réelle de l'image. On peut également utiliser 2w 1px pour obtenir le même effet. L'attribut src n'est utilisé que par les anciens navigateurs.

Le bel effet de celui-ci est qu'il affiche la même taille sur la rétine ou l'affichage standard, rétrécissant sur ce dernier.

Max_B
la source
0
function shrinkImage(idOrClass, className, percentShrinkage){
'use strict';
    $(idOrClass+className).each(function(){
        var shrunkenWidth=this.naturalWidth;
        var shrunkenHeight=this.naturalHeight;
        $(this).height(shrunkenWidth*percentShrinkage);
        $(this).height(shrunkenHeight*percentShrinkage);
    });
};

$(document).ready(function(){
    'use strict';
     shrinkImage(".","anyClass",.5);  //CHANGE THE VALUES HERE ONLY. 
});

Cette solution utilise js et jquery et redimensionne en fonction uniquement des propriétés de l'image et non du parent. Il peut redimensionner une seule image ou un groupe en utilisant des paramètres de classe et d'identifiant.

pour en savoir plus, allez ici: https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5

Jenny Vallon
la source
0

Ceci est une approche pas difficile:

<div>
    <img src="sample.jpg" />
</div>

then in css:
div {
    position: absolute;
}

img, div {
   width: ##%;
   height: ##%;
}
nickthehero
la source
0

En fait, la plupart des réponses ici ne redimensionnent pas vraiment l'image à la largeur d' elle - même .

Nous devons avoir une largeur et une hauteur d'auto sur l' imgélément lui-même afin que nous puissions commencer avec sa taille d'origine.

Après cela, un élément de conteneur peut mettre l'image à l'échelle pour nous.

Exemple HTML simple:

<figure>
    <img src="[email protected]" />
</figure>

Et voici les règles CSS. J'utilise un conteneur absolu dans ce cas:

figure {
    position: absolute;
    left: 0;
    top: 0;
    -webkit-transform: scale(0.5); 
    -moz-transform: scale(0.5);
    -ms-transform: scale(0.5); 
    -o-transform: scale(0.5);
    transform: scale(0.5);
    transform-origin: left;
} 

figure img {
    width: auto;
    height: auto;
}

Vous pouvez modifier le positionnement de l'image avec des règles telles que transform: translate(0%, -50%);.

Floris
la source
-1

Je pense que vous avez raison, ce n'est tout simplement pas possible avec du CSS pur pour autant que je sache (pas cross-browser je veux dire).

Éditer:

Ok, je n'aimais pas beaucoup ma réponse alors je me suis un peu perplexe. J'aurais peut-être trouvé une idée intéressante qui pourrait aider ... peut-être que c'est possible après tout (bien que ce ne soit pas la plus jolie chose qui soit):

Edit: testé et fonctionnant sous Chrome, FF et IE 8 & 9. . Cela ne fonctionne pas dans IE7.

jsFiddle exemple ici

html:

<div id="img_wrap">
    <img id="original_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    <div id="rescaled_img_wrap">
        <img id="rescaled_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    </div>
</div>

css:

#img_wrap {
    display: inline-block;       
    position:relative;    
}

#rescaled_img_wrap {
    width: 50%;
}
#original_img {
    display: none;
}
#rescaled_img {
    width: 100%;
    height: 100%;
}
Wesley
la source
votre exemple redimensionner l'image pas proportionnellement
Vladimir Starkov
Votre méthode permet de diminuer l'image grâce au redimensionnement de la fenêtre
Vladimir Starkov
c'est parce que vous utilisez inline-block, c'est pourquoi la largeur #img_wrapdépend non seulement de la largeur html interne, mais aussi de la largeur du conteneur de contexte.
Vladimir Starkov
Autant que je sache, cet affichage: aucune image ne fait rien et peut être supprimé. Ou est-ce que je manque quelque chose?
tremby