Подтвердить что ты не робот

Firefox и Chrome перестали отображать мой спрайт после 655 изображений

проблема

Привет, я работаю со спрайтами и получаю интересное поведение firefox и Chrome. Когда у моего спрайта есть 655 или меньше, мой спрайт отлично работает. Но когда он идет дальше (656 или более), он не отображается (просто становится невидимым). Я предполагаю, что проблема не в моем коде, так как отлично работает в Opera и IE. Почему?


подробности

Я использую PHP для генерации спрайтов "на лету". Сгенерированный html будет выглядеть следующим образом:

<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>

[...]

и CSS выглядит так:

._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;}

[...]

Каждое изображение моих спрайтов имеет размер 50x50 (px) и составляет около 2-6 КБ. Я тестировал их с типами jpg, png и gif. Все получили те же результаты.


Скриншоты

655 изображений

655 images

656 изображений

enter image description here

4b9b3361

Ответ 1

Изменить: Если причиной проблемы является не целочисленное значение длины CSS, то это максимальный размер изображения, который может обрабатывать браузер (ы). Вероятно, это более важно, если вы перечитаете свой вопрос.

См. Ошибка Firefox 591822: изображения выше или выше 32767

Я использовал рассчитанное ниже значение, чтобы быстро найти этот билет через google;)

Если вы хотите, чтобы это сработало, помогите с cairo, базовой библиотекой изображений.

То, что вы можете сделать, - это не распространять ваши спрайты только на одну ось (y в вашем случае), но на обоих (x и y):

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

и т.д. PHP:

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

У вас есть смещение -50 пикселей на спрайт.

Первый спрайт имеет смещение 0 ((1-1) * -50).

Для спрайта # 655 смещение 654 * -50, которое -32,700.

Справа # 656 имеет смещение 655 * -50, которое -32,750.

Справа # 657 имеет смещение 656 * -50, которое -32,800.

16 бит, без знака integer Википедия (полуслова, слово, короткое) варьируется от 0 до 65535, он подписал от -32,768 до 32,767.

Простое сравнение этих значений показывает, что если рассматриваемый браузер использует этот тип данных для хранения целочисленного значения пиксельного блока, он не сможет:

-32,800 is lower than -32,768

Что может случиться в этом случае, так это получение туда-обратно:

-32,800 => 32

Если вы разместите спрайт на своей области спрайтов (относительной) координаты -32 (что невозможно), вы можете увидеть его.

Это только предположение, я не проверял исходные коды рассматриваемых браузеров, поэтому возьмите его с солью.

Однако это может привести к быстрой стратегии решения, которая справедлива, если она будет работать быстро:

Как решить?

Вы можете попробовать (пока это не повлияет на алгоритмы рендеринга), чтобы использовать другой блок. Поместите все спрайты в родительский элемент, например. a <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;}

Это может быть более совместимо с несколькими браузерами, так как целая длина каждой единицы не намного меньше.

Сообщите мне, если это сработает, вы не опубликовали какой-либо код в своем вопросе в качестве демонстрационного примера, поэтому я тоже не скомпилировал демо, но я надеюсь, что идея решения решения понятна.