web-dev-qa-db-fra.com

Comment puis-je redimensionner une image dans un sprite CSS

Dans cet article, http://css-tricks.com/css-sprites/ , il est décrit comment je peux rogner une image plus petite à partir d'une image plus grande. Pouvez-vous me dire s'il est possible/comment je peux rogner une image plus petite puis redimensionner la région rognée avant de la tracer?

Voici un exemple de cet article:

A
{
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

J'aimerais savoir comment puis-je redimensionner cette image après l'avoir recadrée à partir de spriteme1.png

Voici l'URL de l'exemple: http://css-tricks.com/examples/CSS-Sprites/Example1After/

Je voudrais donc savoir si je peux réduire les icônes à côté de Item1,2,3,4?

151
michael

Vous pouvez utiliser background-size , comme il est supporté par la plupart des navigateurs (mais pas tous http://caniuse.com/#search= taille du fond )

background-size : 150% 150%;

Ou

Vous pouvez utiliser une combinaison de zoom pour webkit/ie et transformer: scale pour Firefox (-moz-) et Opera (-o-) pour ordinateurs de bureau et téléphones mobiles sur plusieurs navigateurs

[class^="icon-"]{
    display: inline-block;
    background: url('../img/icons/icons.png') no-repeat;
    width: 64px;
    height: 51px;
    overflow: hidden;
    zoom:0.5;
    -moz-transform:scale(0.5);
    -moz-transform-Origin: 0 0;
}

.icon-huge{
    zoom:1;
    -moz-transform:scale(1);
    -moz-transform-Origin: 0 0;
}

.icon-big{
    zoom:0.60;
    -moz-transform:scale(0.60);
    -moz-transform-Origin: 0 0;
}

.icon-small{
    zoom:0.29;
    -moz-transform:scale(0.29);
    -moz-transform-Origin: 0 0;
}
125
aWebDeveloper

Lorsque vous utilisez des images-objets, vous êtes limité aux dimensions de l'image dans l'image-objet. La propriété CSS background-size, mentionnée par Stephen, n'est pas encore largement prise en charge et pourrait poser des problèmes avec les navigateurs tels que IE8 et les versions antérieures - et compte tenu de leur part de marché, ce n'est pas une option viable.

Une autre façon de résoudre le problème consiste à utiliser deux éléments et à redimensionner le Sprite en l’utilisant avec une balise img, comme ceci:

<div class="Sprite-image"
     style="width:20px; height:20px; overflow:hidden; position:relative">
    <!-- set width/height proportionally, to scale the Sprite image -->
    <img src="Sprite.png" alt="icon"
         width="20" height="80"
         style="position:absolute; top: -20px; left: 0;" />
</div>

De cette façon, l'élément externe (div.Sprite-image) recadre une image de 20 x 20 pixels de la balise img, qui agit comme un background-image mis à l'échelle.

29
Alex Gyoshev

Essayez ceci: Sprites extensibles - Redimensionnement/étirement transversal du navigateur, des images CSS Sprite

Cette méthode adapte les images-objets de manière réactive afin que la largeur/hauteur s’adapte à la taille de la fenêtre de votre navigateur. Il n'utilise pas background-size comme support dans les navigateurs plus anciens, il n’existe pas.

CSS

.stretchy {display:block; float:left; position:relative; overflow:hidden; max-width:160px;}
.stretchy .spacer {width: 100%; height: auto;}
.stretchy .Sprite {position:absolute; top:0; left:0; max-width:none; max-height:100%;}
.stretchy .Sprite.s2 {left:-100%;}
.stretchy .Sprite.s3 {left:-200%;}

HTML

<a class="stretchy" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
<a class="stretchy s2" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
<a class="stretchy s3" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
19
tobyj

transform: scale(); fera en sorte que l'élément d'origine conserve sa taille.

J'ai trouvé la meilleure option est d'utiliser vw. Cela fonctionne comme un charme:

https://jsfiddle.net/tomekmularczyk/6ebv9Lxw/1/

#div1,
#div2,
#div3 {
  background:url('//www.google.pl/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png') no-repeat;
  background-size: 50vw;   
  border: 1px solid black;
  margin-bottom: 40px;
}

#div1 {
  background-position: 0 0;
  width: 12.5vw;
  height: 13vw;
}
#div2 {
  background-position: -13vw -4vw;
  width: 17.5vw;
  height: 9vw;
  transform: scale(1.8);
}
#div3 {
  background-position: -30.5vw 0;
  width: 19.5vw;
  height: 17vw;
}
<div id="div1">
  </div>
  <div id="div2">
  </div>
  <div id="div3">
  </div>
10
Tomasz Mularczyk

Voici ce que j'ai fait pour faire ça. Gardez à l'esprit que cela ne fonctionnera pas sur IE8 et inférieur.

#element {
  width:100%;
  height:50px;
  background:url(/path/to/image.png);
  background-position:140.112201963534% 973.333333333333%;
}

La largeur de l'image d'arrière-plan sera réduite en tant que parent de #element. Vous pouvez également faire de même avec sa hauteur si vous convertissez height en pourcentage. Le seul élément délicat consiste à calculer les pourcentages pour background-position.

Le premier pourcentage correspond à la largeur de la zone cible du Sprite à la largeur normale, divisée par la largeur totale du Sprite et multipliée par 100.

Le second pourcentage correspond à la hauteur de la zone ciblée du Sprite avant sa mise à l'échelle divisée par la hauteur totale du Sprite et multipliée par 100.

Le libellé de ces deux équations est un peu bâclé, alors laissez-moi savoir si vous avez besoin de moi pour mieux l'expliquer.

7
user621994

Ancien post, mais voici ce que j'ai fait en utilisant background-size:cover; (astuce de chapeau à @Ceylan Pamir) ...

EXEMPLE D'UTILISATION
Flipper à cercle horizontal (survolez l'image du côté avant, bascule vers l'arrière avec une image différente).

EXEMPLE Sprite
480px x 240px

EXEMPLE DE TAILLE FINALE
Image unique à 120px x 120px

CODE GÉNÉRIQUE
.front {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:0px 0px;}

.back {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:-120px 0px;}

FIDDLE DE CAS ABRÉGÉ
http://jsfiddle.net/zuhloobie/133esq63/2/

5
chris

essayez d’utiliser une taille d’arrière-plan: http://webdesign.about.com/od/styleproperties/p/blspbgsize.htm

y a-t-il quelque chose qui vous empêche de restituer les images à la taille souhaitée?

4
stephenmurdoch

Il m'a fallu un certain temps pour trouver une solution à ce problème qui me satisfit:

Problème:

  • Un Sprite SVG d'icônes - disons 80px x 3200px

  • Nous souhaitons mettre à l'échelle chaque utilisation de ceux-ci dans les sélecteurs de contenu (: before /: after) à différents endroits sur différentes tailles sans redéfinir les coordonnées de chaque Sprite en fonction de la taille utilisée.

Cette solution vous permet donc d'utiliser les mêmes coordonnées Sprite dans un <button> qu'un <menuitem> tout en le redimensionnant.

[data-command]::before {
    content: '';
    position: absolute;
    background-image: url("images/Sprite.svgz");
    background-repeat: no-repeat;
    background-size: cover;
}

button[data-command]::before {
  width: 32px;
  height: 32px;
}

menuitem[data-command]::before {
  width: 24px;
  height: 24px;
}

[data-command="cancel"]::before {
  background-position: 0% 35%;
}

[data-command="logoff"]::before {
  background-position: 0% 37.5%;
}

En utilisant des pourcentages (jusqu'à 2 décimales) en position d'arrière-plan plutôt qu'en taille d'arrière-plan, comme le suggèrent d'autres personnes ici, vous pouvez redimensionner la même déclaration d'icône à n'importe quelle taille, sans avoir à la redéclarer.

Le pourcentage position-y correspond à la hauteur originale de Sprite/à la hauteur de l'icône, exprimée en% - dans notre cas 80px * 100/3200px == chaque Sprite est représenté par une position y de 2,5%.

Si vous avez des états de survol/souris, vous pouvez doubler la largeur de l’image-objet et spécifier une coordonnée en position x.

L'inconvénient de cette approche est que l'ajout ultérieur d'icônes modifiera la hauteur du sprite et donc la position y, mais si vous ne le faites pas, les coordonnées de votre sprite devront être modifiées pour chaque résolution mise à l'échelle requise.

4
Neil

Eh bien, je pense que nous avons trouvé une solution plus simple pour redimensionner les images: exemple - disons qu'il existe une image avec 3 sprites de taille égale que vous voudriez utiliser. Utilisez CSS pour redimensionner l'image.

background-size : 300% 100%;

puis spécifiez la hauteur et la largeur personnalisées à appliquer à votre élément html, par exemple:

 width :45%;
 height:100px;

Un exemple de code ressemblerait à ceci:

.customclass {
    background: url("/sample/whatever.png") 0 0 no-repeat ;
    background-size : 300% 100%;
    width :45%;
    height:100px;
}

je suis assez nouveau pour css, et le style n’est pas mon meilleur domaine, cela pourrait être une mauvaise façon de le faire .. mais cela a fonctionné pour moi dans Firefox/Chrome/Explorer 10, espérons que cela fonctionne aussi dans les anciennes versions ..

2
Dasith

2018 ici. Utilisez la taille de l'arrière-plan avec un pourcentage.

FEUILLE:

Cela suppose une seule rangée de sprites. La largeur de votre feuille doit être un nombre divisible par 100 + largeur d'un Sprite. Si vous avez 30 images-objets de 108x108 px, ajoutez un espace supplémentaire à la fin pour obtenir une largeur finale de 5508px (50 * 108 + 108).

CSS:

.icon{
    height: 30px;  /* Set this to anything. It will scale. */
    width: 30px; /* Match height. This assumes square sprites. */
    background:url(<mysheeturl>);
    background-size: 5100% 100%; /*  5100% because 51 sprites. */
}

/* Each image increases by 2% because we used 50+1 sprites. 
   If we had used 20+1 sprites then % increase would be 5%. */

.first_image{
    background-position: 0% 0;
}

.ninth_image{
    background-position: 16% 0; /* (9-1) x 2 = 16 */
}

HTML:

<div class ="icon first_image"></div>
<div class ="icon ninth_image"></div>
2
user984003

Utilisez transform: scale(...); et ajoutez margin: -...px correspondant pour compenser l'espace libre de la mise à l'échelle. (vous pouvez utiliser * {outline: 1px solid}pour voir les limites des éléments).

2
adyry

Cela semble fonctionner pour moi.

Si les images-objets sont dans la grille, définissez le background-size sur 100% du nombre d'images-objets et sur 100% du nombre d'images-objets. Puis utilisez background-position -<x*100>% -<y*100>% où x et y sont le Sprite à base zéro

En d'autres termes, si vous voulez que le 3ème Sprite de la gauche et de la 2ème rangée soit 2 sur et 1 en bas,

background-position: -200% -100%;

Par exemple, voici une feuille de sprite 4x2 sprites

enter image description here

Et voici un exemple

div {
  margin: 3px;
  display: inline-block;
}
.Sprite {
  background-image: url('https://i.stack.imgur.com/AEYNC.png');
  background-size: 400% 200%;  /* 4x2 sprites so 400% 200% */
}
.s0x0 { background-position:    -0%   -0%; }
.s1x0 { background-position:  -100%   -0%; }
.s2x0 { background-position:  -200%   -0%; }
.s3x0 { background-position:  -300%   -0%; }
.s0x1 { background-position:    -0%  -100%; }
.s1x1 { background-position:  -100%  -100%; }
.s2x1 { background-position:  -200%  -100%; }
.s3x1 { background-position:  -300%  -100%; }
<div class="Sprite s3x1" style="width: 45px; height:20px"></div>
<div class="Sprite s3x1" style="width: 128px; height:30px"></div>
<div class="Sprite s3x1" style="width: 64px; height:56px"></div>
<div class="Sprite s2x1" style="width: 57px; height:60px"></div>
<div class="Sprite s3x0" style="width: 45px; height:45px"></div>
<div class="Sprite s0x1" style="width: 12px; height:100px"></div>

<br/>
<div class="Sprite s0x0" style="width: 45px; height:20px"></div>
<div class="Sprite s1x0" style="width: 128px; height:45px"></div>
<div class="Sprite s2x0" style="width: 64px; height:56px"></div>
<div class="Sprite s3x0" style="width: 57px; height:60px"></div>
<br/>
<div class="Sprite s0x1" style="width: 45px; height:45px"></div>
<div class="Sprite s1x1" style="width: 12px; height:50px"></div>
<div class="Sprite s2x1" style="width: 12px; height:50px"></div>
<div class="Sprite s3x1" style="width: 12px; height:50px"></div>

Si les images-objets sont de tailles différentes, vous devez définir le pourcentage de background-size de chaque image-objet de sorte que la largeur de cette image-objet atteigne 100%.

En d'autres termes, si l'image a une largeur de 640px et que le Sprite à l'intérieur de cette image a une largeur de 45px, il faut alors obtenir une résolution de 640px pour cette image de 45px.

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

Ensuite, vous devez définir le décalage. La complication du décalage est que 0% est aligné à gauche et 100% est aligné à droite.

enter image description here

En tant que programmeur graphique, je m'attendrais à un décalage de 100% pour déplacer l'arrière-plan de 100% sur l'élément, autrement dit, entièrement du côté droit, mais ce n'est pas ce que 100% signifie lorsqu'il est utilisé avec backgrouhnd-position. background-position: 100%; signifie aligné à droite. Ainsi, le forum pour prendre cela en compte après la mise à l'échelle est

xOffsetScale = 1 + 1 / (xScale - 1)              
xOffset = offsetX * offsetScale / imageWidth

Supposons que le décalage est de 31px

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

Voici une image 640x480 avec 2 sprites.

  1. à 31x 27y taille 45w 32h
  2. à 500x 370y taille 105w 65h

enter image description here

Suivre les calculs ci-dessus pour Sprite 1

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

yScale = imageHeight / spriteHEight
yScale = 480 / 32
yScale = 15
yPercent = yScale * 100
yPercent = 1500%

yOffsetScale = 1 + 1 / (15 - 1)
yOffsetScale = 1.0714285714285714
yOffset = offsetY * yOffsetScale / imageHeight
yOffset = 27 * 1.0714285714285714 / 480
yOffset = 0.06026785714285714
yOffsetPercent = 6.026785714285714
div {
  margin: 3px;
  display: inline-block;
}
.Sprite {
  background-image: url('https://i.stack.imgur.com/mv9lJ.png');
}
.s1 {
  background-size:      1422.2222% 1500%;
  background-position:  5.210084033619603% 6.026785714285714%;
}
.s2 {
  background-size:      609.5238095238095% 738.4615384615385%;
  background-position:  93.45794392523367% 89.1566265060241%;
}
<div class="Sprite s1" style="width: 45px; height:20px"></div>
<div class="Sprite s1" style="width: 128px; height:30px"></div>
<div class="Sprite s1" style="width: 64px; height:56px"></div>
<div class="Sprite s1" style="width: 57px; height:60px"></div>
<div class="Sprite s1" style="width: 45px; height:45px"></div>
<div class="Sprite s1" style="width: 12px; height:50px"></div>
<div class="Sprite s1" style="width: 50px; height:40px"></div>
<hr/>
<div class="Sprite s2" style="width: 45px; height:20px"></div>
<div class="Sprite s2" style="width: 128px; height:30px"></div>
<div class="Sprite s2" style="width: 64px; height:56px"></div>
<div class="Sprite s2" style="width: 57px; height:60px"></div>
<div class="Sprite s2" style="width: 45px; height:45px"></div>
<div class="Sprite s2" style="width: 12px; height:50px"></div>
<div class="Sprite s2" style="width: 50px; height:40px"></div>
1
gman

Définissez la largeur et la hauteur sur l'élément wrapper de l'image Sprite. Utilisez ce css.

{
    background-size: cover;
}
0
Ceylan Pamir