Question Firefox et Chrome cessent d'afficher mon sprite après 655 images


le problème

Bonjour, je travaille avec des sprites et a un comportement intéressant de Firefox et de Chrome. Quand mon sprite a 655 images ou moins, mon sprite fonctionne bien. Mais quand il va plus loin (656 ou plus), il ne s'affiche pas (devenez simplement invisible). Je suppose que le problème ne réside pas dans mon code, car il fonctionne correctement dans Opera et IE. Comment venir?


détails

J'utilise PHP pour générer les sprites à la volée. Le HTML généré va comme ceci:

<span class="_sprite_images _sprite_images_1"></span>
<span class="_sprite_images _sprite_images_0"></span>
<span class="_sprite_images _sprite_images_2"></span>
<span class="_sprite_images _sprite_images_3"></span>
<span class="_sprite_images _sprite_images_4"></span>
<span class="_sprite_images _sprite_images_5"></span>

[...]

et le CSS ressemble à ceci:

._sprite_images{background:url("../sprite_images/sprite.jpg");display:inline-block;}

._sprite_images_0{width:50px;height:50px;background-position:0 0px;}
._sprite_images_1{width:50px;height:50px;background-position:0 -50px;}
._sprite_images_2{width:50px;height:50px;background-position:0 -100px;}

[...]

Chaque image de mes sprites a la taille 50x50 (px) et est d'environ 2 à 6 Ko. Je les ai testés avec les types jpg, png et gif. Tous ont eu les mêmes résultats.


captures d'écran

655 images

655 images

656 images

enter image description here


12
2017-11-01 02:06


origine


Réponses:


Modifier: Si la cause du problème n'est pas la valeur d'entier de la longueur CSS, c'est la taille d'image maximale que le ou les navigateurs en question peuvent traiter. C'est probablement plus le cas ici en relisant votre question.

Voir Bug de Firefox 591822: Images plus grandes ou plus larges que 32767

J'ai utilisé la valeur calculée ci-dessous pour rechercher ce ticket rapidement via google;)

Si vous voulez que cela fonctionne, aidez avec cairo, la bibliothèque d'images sous-jacente.

Ce que vous pouvez faire également, c'est de ne pas répartir vos sprites sur un seul axe (y dans votre cas), mais à la fois sur (x et y):

0: 0 0
...
654: 0 -32700
655: -50 0

etc. PHP:

$offset = -50;
$x = (int)($n/655) * $offset;
$y = $n % 655 * $offset;

Vous avez un décalage de -50 pixels par sprite.

Le premier sprite a un décalage de 0 ((1-1) * -50).

Pour le sprite # 655, le décalage est 654 * -50 lequel est -32,700.

Le sprite # 656 a le décalage 655 * -50 lequel est -32,750.

Le sprite # 657 a le décalage 656 * -50 lequel est -32,800.

Un 16 bits, non signé entier Wikipédia (demi-mot, mot, court) va de 0 à 65535, il est signé homologue de -32,768 à 32,767.

La simple comparaison de ces valeurs montre que si le navigateur en question utilise ce type de données pour stocker la valeur entière de l'unité de pixels, il ne pourra pas:

-32,800 is lower than -32,768

Qu'est-ce qui peut arriver dans ce cas, c'est qu'il fait un aller-retour:

-32,800 => 32

Si vous souhaitez placer une image-objet sur votre panneau d'image-objet sur la coordonnée (relative) -32 (ce qui n'est pas possible), vous pourrez peut-être le voir.

Ceci n'est qu'une hypothèse, je n'ai pas vérifié les codes sources des navigateurs en question, alors prenez-les avec un grain de sel.

Cependant, cela pourrait conduire à une stratégie de résolution rapide, ce qui est juste si elle fonctionne rapidement:

Comment résoudre?

Vous pouvez essayer (tant que les algorithmes de rendu ne sont pas affectés par cela), utiliser une autre unité. Mettez tous vos sprites dans un élément parent, par exemple une <div>:

<div class="sprites">
  <span class="img-1"></span>
  <span class="img-2"></span>
  <span class="img-3"></span>
  ...
  <span class="img-656"></span>
</div>

CSS:

div.sprites {font-size:50px;}
    div.sprites span {background: ... ; height: 1em; width: 1em;} /* default sprite definition*/
        div.sprites span.img-1 {background-position:0 0;}
        div.sprites span.img-2 {background-position:0 -1em;}
        div.sprites span.img-3 {background-position:0 -2em;}
        ...
        div.sprites span.img-656 {background-position:0 -655em;}

Cela pourrait être plus compatible avec tous les navigateurs, car la longueur entière de chaque unité n'est pas beaucoup plus petite.

Faites-moi savoir si cela fonctionne, vous n'avez pas publié de code dans votre question comme exemple de démonstration, donc je n'ai pas compilé une démo aussi, mais j'espère que l'idée derrière la suggestion de solution est claire.


11
2017-11-01 14:26