web-dev-qa-db-fra.com

sprites réactifs / pourcentages

J'ai lu toutes les questions sur les sprites réactifs en utilisant css, j'ai vu jsfiddle avec des exemples de sprites réactifs, mais je ne comprends toujours pas comment obtenir le pourcentage de position d'arrière-plan et de taille d'arrière-plan, comment utiliser un wrapper (certains les gens disent que c'est nécessaire) autour du div qui utilise background-image et pourquoi l'utiliser ...
Par exemple, si j'ai un div qui a une largeur: 20% (disons 40px) et est un cercle. L'image que je dois utiliser comme image de fond a une largeur de 80 pixels (un cercle et je dois la redimensionner pour l'adapter à ma div) et est l'une des 40 images que j'ai dans ma feuille Sprite. Il est à la position -173px -293px.
Je ne sais vraiment pas comment le faire fonctionner.
J'ai essayé:

div {
  width:20%;
  border-radius:50%;
  background: url('images/sprites.png') no-repeat 72.083% 67.981%;
  background-size: 50%;
  }

Bien sûr, cela n'a pas fonctionné. Je ne comprends pas comment obtenir la position d'arrière-plan-x, la position d'arrière-plan-y (les chiffres que j'ai proviennent de la feuille Sprite de taille "auto") lorsque la taille d'arrière-plan n'est pas automatique, ou comment la taille d'arrière-plan se rapporte au pourcentage de la taille div.
Y a-t-il une formule mathématique que je peux utiliser? Quelqu'un peut-il m'expliquer ou me donner un nom de site Web/livre où je peux l'apprendre?
Merci,

23
user3097405

La dimension div ne joue pas dans le calcul, seulement les tailles d'arrière-plan et la partie que vous allez utiliser.

Disons que votre fond a une largeur de 1000px et une hauteur de 500px.

L'image que vous allez utiliser a une largeur et une hauteur de 80 pixels.

taille d'arrière-plan:

x part     1000px / 80px = 12.5   ->> 1250%
y part      500px / 80px = 6.25   ->>  625%

background-size: 1250% 625%;

position d'arrière-plan:

x-part     173px / 1000px = 0.173   ->> 17.3%
y part     293px / 500px = 0.586    ->> 58.6%

background-position: 17.3% 58.6%;
18
vals

Une mise à jour de la réponse de @vals. Certains de ses calculs n'ont pas vraiment fonctionné pour moi.

Les calculs de taille d'arrière-plan ont fonctionné, sauf qu'il multipliait par 1000 au lieu de 100 pour obtenir les pourcentages finaux. Donc 12500% devrait être 1250% et ainsi de suite. (Mise à jour: 10/2015 - il semble que @vals ait corrigé cela dans sa réponse.)

Les calculs de la valeur X de la position d'arrière-plan étaient très légèrement pour moi. Ils ne correspondent pas à ce qui a été généré par spritecow.com (selon la suggestion d'Adrian Florescu). C'est, je pense, parce que les coordonnées absolues sont calculées à partir de la gauche de l'image d'arrière-plan, alors qu'avec les pourcentages, vous devez calculer à partir de la droite de l'image d'arrière-plan. Cela étant, vous devez soustraire la largeur de l'image de la largeur globale de l'arrière-plan avant vous divisez le nombre absolu de x-pos avec.

Donc au lieu de:

x-part 173px / 1000px = 0.173 ->> 17.3%

faites ceci:

x-part 173px / (1000px - 80px) = 0.1880434783 ->> 18.80434783%

Où:

1000px est la largeur de l'image d'arrière-plan (Sprite)

80px est la largeur de l'image affichée

173px est la coordonnée absolue en X de l'image affichée.

C'est ce qui fonctionne pour moi en tout cas!

28
ChillyPenguin

J'ai écrit un Responsive CSS Sprite Generator pour prendre soin de tout le travail pour vous. Vous pouvez simplement télécharger un tas d'images et cela vous donnera une image Sprite et le CSS pour cela.

Il utilise une nouvelle méthode pour rendre les sprites réactifs - un src de données avec un PNG transparent pour que l'image conserve son rapport d'aspect, donc contrairement aux autres méthodes, les images n'ont pas besoin d'être carrées, ou tout de même le même rapport.

14
Greg

Ceci est le meilleur responsive exemple que j'ai trouvé pour résoudre le problème de Sprite !

Cross-browser, redimensionnement/étirement réactif des images CSS Sprite

Cette méthode ne dépend pas de la taille de l'arrière-plan , elle fonctionnera donc dans les anciens navigateurs.

Sprites extensibles

  • Cet exemple utilise une image de 800 de large x 160 de haut. Cette image contient 6 sprites de taille égale (160x160 chacun).

  • Si votre taille de Sprite est différente, tout ce que vous devez changer est la propriété max-width de .Sprite pour correspondre à la largeur individuelle de Sprite.

  • Pour définir le Sprite visible: Réglez la valeur de gauche de .Sprite sur: 0 = 1er Sprite -100% = 2e Sprite -200% = 3e Sprite etc ... Facile!

  • Si vous souhaitez que les images s'étendent plus que leur taille naturelle: ajoutez la classe .no-limit à .stretchy. Cela supprime la largeur maximale: 160px de .stretchy et ajoute la hauteur minimale: 100% à .Sprite Alternativement, vous pouvez définir une largeur maximale plus grande en utilisant une valeur px, par ex. 300px.

  • L'image d'espacement peut être de n'importe quelle taille, à condition qu'elle soit proportionnelle aux dimensions des sprites individuels.

5
Andres Separ

Ceci est une solution plus simple, vérifiez ceci

.my_picture{
    //target your Sprite
    background: url(my_img.jpg) no-repeat;

    //Specify it full image
    backgound-size: 100%;

    //Position of the targeted picture
    background-position: left 0 bottom x%;

    //Zoom in or out on the position
    width: x%;

    //Scale height by playing with padding
    padding-bottom: x%;

    //Set height to 0 because of Sprite size
    height: 0;
}

Comment ça marche? Pour cibler facilement des images Sprite, nous devons spécifier la taille de Sprite à l'original, "100%". Nous ciblerons ensuite une position d'image à partir du bas correspondant, avec le 0 gauche.

Étant donné que la taille de Sprite est définie sur 100% maximum, nous devons désactiver la hauteur, et la seule option pour définir la hauteur maintenant, est de jouer avec padding-bottom, en pourcentage également.

Votre image est désormais entièrement réactive, il vous suffit de jouer avec les valeurs de largeur (en pourcentage), pour effectuer un zoom avant ou arrière, et c'est tout, vous avez un Sprite css entièrement réactif.

Article original sur mon blog ici: http://creativcoders.wordpress.com/2014/05/05/css-responsive-sprites/

3
Edouard Kombo

Vous pouvez utiliser des sites Web pour connaître les coordonnées exactes de votre Sprite. J'utilise personnellement http://www.spritecow.com/

2
Ankur Aggarwal

J'ai passé beaucoup de temps à chercher une réponse à ce sujet, je suis sorti avec cette solution, cela fonctionne pour moi au moins pour l'instant, est basé sur une taille de pixel fixe, et les sprites horizontaux, seront de toute façon un gâchis avec un pourcentage parce que vous devrez faire le calcul pour les valeurs de pixels pour ce pourcentage, et pour les sprites localisés au hasard parce que vous devrez trouver l'emplacement aléatoire du Sprite à l'intérieur de l'image, trop de maths pour une tâche simple je crois.

Vous avez besoin:

  • Connaître la largeur de l'image (compass image-width($image))
  • La taille en pixels et l'emplacement d'origine du Sprite à l'intérieur de l'image (Photoshop fait l'affaire)
  • La taille de la boîte contenant proportionnelle au Sprite correspondant que vous êtes censé montrer
  • Et bien sûr, la quantité d'étirement que vous souhaitez appliquer au Sprite spécifique.

Comme conseil, vous devrez laisser au moins 1px de marge physique entre chaque image car les pourcentages produisent des pixels non entiers, et vous vous retrouverez avec des sprites qui se chevauchent !! ;)

Vérifiez-le et donnez-moi des commentaires s'il vous plaît:

//functions

//stretch by percentage
@function stretchImage($width, $height, $percentage) {

    $s_width: round( ($width * $percentage) / 100 );
    $s_height: round( ($height * $percentage) / 100 );

    @return ($s_width, $s_height);
}

//strip units
//(Eric M Suzanne) http://stackoverflow.com/questions/12328259/how-do-you-strip-the-unit-from-any-number-in-sass
@function strip-units($number) {
  @return $number / ($number * 0 + 1);
}

//replace in string
//(css tricks) http://css-tricks.com/snippets/sass/str-replace-function/
@function str-replace($string, $search, $replace: '') {
    $index: str-index($string, $search);

    @if $index {
        @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
    }

    @return $string;
}

//get unitless percentage
@function getPercentageFrom($valueA, $valueB) {

    $percentage: percentage(strip-units($valueA)/strip-units($valueB));

    @return ($percentage);
}


//now the magic

//we know the witdh of the image containing the sprites 
$image: url(http://www.cssguy4hire.com/codePenAssets/Sprite_test.png);
$image_width: 965px;

//the amount of strech we want to aply
$stretchTo: 175;

//we know the current Sprite measures we  going to set 
$Sprite_width: 150px;
$Sprite_height: 150px;
//left is 0 cuz is first Sprite                
$Sprite_left: 0%;                

//stretch Sprite                            
$stretch: stretchImage($Sprite_width, $Sprite_height, $stretchTo);
$width: nth($stretch, 1);                
$height: nth($stretch, 2);                

//set background size and position          
$bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);

//default position 0
$bkg_left: $Sprite_left;              


//compose the css
#image {
    margin: auto;
    width: $width;
    height: $height;
    position: relative;
    display: block;
    background: #00f00f $image $bkg_left 0 no-repeat;
    background-size: $bkg-size;
    border: 5px solid #cccccc;

    //we chage the Sprite
    &.Sprite_1 {

        //the amount of strech we want to aply
        $stretchTo: 250;

        //we know the current Sprite measures we  going to set 
        //0 is te first Sprite starting left to right
        $Sprite_width: 250px;
        $Sprite_height: 75px;
        $Sprite_left: 150px;              

        //stretch Sprite                            
        $stretch: stretchImage($Sprite_width, $Sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($Sprite_left / ($image_width - $Sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.Sprite_2 {

        //the amount of strech we want to aply
        $stretchTo: 80;

        //we know the current Sprite measures we going to set 
        $Sprite_width: 140px;
        $Sprite_height: 120px;
        $Sprite_left: 400px;              

        //stretch Sprite                            
        $stretch: stretchImage($Sprite_width, $Sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($Sprite_left / ($image_width - $Sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.Sprite_3 {

        //the amount of strech we want to aply
        $stretchTo: 125;

        //we know the current Sprite measures we going to set 
        $Sprite_width: 290px;
        $Sprite_height: 134px;
        $Sprite_left: 540px;              

        //stretch Sprite                            
        $stretch: stretchImage($Sprite_width, $Sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($Sprite_left / ($image_width - $Sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.Sprite_4 {

        //the amount of strech we want to aply
        $stretchTo: 153;

        //we know the current Sprite measures we going to set 
        $Sprite_width: 135px;
        $Sprite_height: 56px;
        $Sprite_left: 830px;              

        //stretch Sprite                            
        $stretch: stretchImage($Sprite_width, $Sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($Sprite_left / ($image_width - $Sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

}

http://codepen.io/wolfitoXtreme/pen/BymKyP

0
wolfitoXtreme

Mon approche est similaire à celle de Greg en ce que j'ai écrit un outil pour générer des sprites css réactifs. J'ai cependant pris un peu plus loin et ajouté un algorithme de tri afin que vous puissiez emballer plus d'images efficacement sur un png.

Voici l'outil responsive CSS Sprite Generator: https://responsive-css.us/

0
eivers88

À partir d'une grande expérience FE, j'ai développé un cadre de sprites réactif qui ne s'appuie pas sur l'image d'arrière-plan, mais à la place, il utilise une image "physique" dans un conteneur qui est mis à l'échelle comme une image/partie d'origine de sprites. Le problème avec css bgd-img est de calculer la taille et la position et c'est souvent pour css de "manquer" la possession de photos pour quelques pixels. La plupart des navigateurs affichent ces valeurs à 0,1 px, mais les arrondissent également. La précision est donc (environ 1/2 du px). Ce missmatch se multiplie lorsque vous essayez de le mettre à l'échelle (pour le rendre réactif). - alors ne vous laissez pas berner par les "sprites réactifs" qui reposent sur l'image d'arrière-plan css. Ils sont juste une mauvaise image déplacée de l'image-objet dont vous avez besoin. - Le JavaScript (framework) est beaucoup plus précis 1/100px), et sa base solide pour des images réactives - car vous avez une taille 1/50 pour mettre à l'échelle les photos et ne perdre aucun pixel. Je ne fais pas de publicité, si quelqu'un est intéressé - jetez un œil à: --- (responsive-sprites.com

0
Bambino Negro