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;}
[...]
Каждое изображение моих спрайтов имеет размер 50х50 (px) и составляет от 2 до 6 КБ. Я проверил их с типами JPG, PNG и GIF. Все получили одинаковые результаты.
скриншоты
655 изображений
656 изображений
1 ответ
Редактировать: Если причина проблемы не в целочисленном значении длины CSS, то это максимальный размер изображения, который могут обрабатывать браузеры. Это, вероятно, больше относится к делу, перечитывая ваш вопрос.
См. Firefox Bug 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-разрядное целочисленное Википедия без знака (половина слова, слово, короткий) варьируется от 0
в 65535
Подписано коллегой из -32,768
в 32,767
,
Простое сравнение этих значений показывает, что если рассматриваемый браузер использует этот тип данных для хранения целочисленного значения пиксельной единицы, он не сможет:
-32,800 is lower than -32,768
Что может произойти в этом случае, это то, что он получает туда-обратно:
-32,800 => 32
Если вы поместите спрайт на панель спрайтов по (относительной) координате -32 (что невозможно), вы сможете увидеть его.
Это только предположение, я не проверял исходные коды рассматриваемых браузеров, так что возьмите его с собой.
Однако это может привести к некоторой стратегии быстрого решения, которая справедлива, если она работает быстро:
Как решить?
Вы можете попытаться (если это не влияет на алгоритмы рендеринга) использовать другой модуль. Поместите все свои спрайты в родительский элемент, например <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;}
Это может быть более кросс-браузерной совместимостью, так как целочисленная длина каждого блока не намного меньше.
Дайте мне знать, если это работает, вы не опубликовали код в своем вопросе в качестве демонстрационного примера, поэтому я также не скомпилировал демо, но я надеюсь, что идея, лежащая в основе решения, ясна.