Вчера на работе разработчик обратился ко мне с проблемой. Разговор шел примерно так:
Дев: Привет, Альваро! У нас проблема.
Я: Что не так?
Дев: Фавиконка на сайте неправильная. Это не наш корпоративный логотип.
Я: Что????
Дев: показывает экран
Я: .....
Я не мог поверить своим глазам: это был наш сайт, название было правильным, только фавиконка отображалась на вкладке не с логотипом компании, а с буквами «Алв» (от Альваро? ) Я обновлял и снова обновлял страницу, думая, что может это какой-то прикол. Но это было не так.
Примечание. Я удалил скриншоты названия и логотипа сайта, чтобы избежать проблем. Внизу статьи есть небольшой пример, воспроизводящий проблему.
Это озадачило меня. Фавиконка работала по-разному в зависимости от браузера. Chrome и Safari показывали правильный значок (с корпоративным логотипом), а Firefox показывал совершенно другой логотип (с буквами). И мы еще раз проверили, что файл тот же, а не старая кэшированная версия. Это был точно такой же файл... но он был другим.
К счастью для нас, потребовалось всего несколько минут, чтобы понять, что происходит (и решить проблему). Но я должен признать, что это одна из самых странных проблем, которые я видел в последнее время.
Мы скачали файл favicon.ico и открыли его в графическом редакторе, после чего увидели основную причину проблемы:
В файле .ico было несколько слоев. Верхний слой отображался в Chrome и Safari, а нижний слой отображался в Firefox.
Мы даже провели тест, чтобы убедиться, что это так. Мы поменяли порядок слоев, сохранили файл... и фавиконка изменилась во всех браузерах! Теперь у Chrome была фавиконка Alv (верхний слой), а у Firefox — корпоративный логотип (нижний слой).
Браузер игнорировал прозрачность. Проблема заключается не в наложении слоев, а в файле .ico, который содержит несколько слоев, а браузер выбирает один (и только один). Как предположил Брамус в Твиттере.
Выяснив причину ошибки, сделал решение простым: удалить слой из файла .ico и сохранить. Проблема (и загадка) решена.
Но почему буквы «Алв»? Сначала мы тестировали фиктивную иконку. Когда мы получили корпоративный логотип, мы поместили его в слой поверх графического редактора и скрыли тестовый слой. Но даже когда слой был скрыт, он все равно экспортировался как часть значка при сохранении!
Я не знаю, можно ли считать поведение Firefox ошибкой или особенностью. Но это превратилось в интересную головоломку.
Воспроизведение
Создайте такой HTML-файл на своем компьютере (вам даже не нужно содержимое):
<!doctype html>
<html>
<head>
<title>Favicon test</title>
<link rel="icon" href="./favicon.ico" />
</head>
<body>
<h1>favicon test</h1>
<p>The favicon has two layers and it is displayed differently by the browsers.</p>
</body>
</html>
Затем создайте файл favicon.ico с двумя слоями. Я использовал GIMP для создания файла, добавив два слоя 64x64, как показано ниже:
Примечание. Если у вас нет графического редактора, вы можете загрузить версию favicon.ico с моего веб-сайта.
Затем сохраните его как .ico и поместите в ту же папку, что и файл HTML. Вот и все. Откройте страницу в Chrome, и вкладка будет выглядеть так:
В Firefox вкладка будет выглядеть иначе:
Вы можете добавить к значку больше слоев, но результат всегда будет один и тот же: Chrome и Safari выберут верхний для отображения в качестве фавиконки, а Firefox выберет последний.
Комментарии (6)
SShtole
16.02.2022 14:07+20Формат .ico для favicon был навязан веб-сообществу на рубеже веков, когда самым популярным браузером был Internet Explorer. Он представляет собой альбом растровых изображений с поддержкой прозрачности. (Хотя термин «альбом» или “album” в статьях MSDN обычно не используется, по сути это именно он). У каждого изображения в альбоме есть свой размер и битность. В оригинальной среде (Windows) была принята следующая практика (то есть, считалось хорошим тоном, хотя и не было причин, заставляющих дизайнера так делать):
- Изображения используются именно в UI.
- Изображения стандартных размеров.
- Все изображения в альбоме семантически эквивалентны. Везде нарисован один и тот же объект. В UI они взаимозаменяемы и программа, поддерживающая формат, может выбирать любое изображение по чисто техническим соображениям (например, в зависимости от режима отображения списка элементов: таблицей, мелкими значками, крупными и т.п.)
- Художник рисует изображение подо все популярные размеры: от 16x16 до 256x256. Ленивый художник просто перерастрирует вектор в разные размеры. Неленивый художник адаптирует количество деталей под размер, меняет ракурс объекта и т.п.
- Программа выбирает изображение нужного в данном месте UI размера. Если такого изображения нет, она подбирает ближайшее подходящее по размеру и рескейлит его как может.
- Программа выбирает изображение нужной битности в соответствии с поддержкой видеорежима. Когда видеорежимы 8 и 16 бит (не на канал, а вообще! да, такое было!) ушли в прошлое, чтобы эта фича не пропала даром, в обиход вошёл протокол RDP, где малобитные режимы экономили трафик. Если такого изображения нет, она подбирает ближайшее подходящее по битности и адаптирует его как может.
Формат, мягко говоря, подустарел, да и изначально был чисто виндовой штучкой. (Программисты Safari, наверное, после его поддержки тщательно вымыли руки). На смену ему используется много чего, от связки .png до авторастрируемого вектора, но курилка по-прежнему жив.
Если всё это не знать, очень легко перепутать изображения со слоями (которых там просто нет) и поиметь проблем, описанных в статье.
geekmeek
16.02.2022 15:19Напомнил давний курьёз дозаписи на CD-Rы, когда с грустью обнаруживалось у друга на ноуте, что на дисках "всё затёрто" и осталась лишь последняя сессия... при том что на моём пишущем дисководе было видно всё в момент записи.
Adler_lug
16.02.2022 15:22+1Было подумал, что я что-то не знаю о файлах иконки, в частности о том, что там могут быть слои, но скачав пример стало понятно, что там просто две разные иконки одного размера в контейнере.
daggert
Это конечно перевод и писать комментарии бессмысленно но всеже - когда зумеры открывают для себя очевидные вещи это удивительно. Эта особенность известна со времен... 95й системы. Например старый пост: https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513
ICO не поддерживает слои. Совсем. Вообще-вообще. Новый слой сохраняется в зависимости от программы либо как новый чанк, по сути создавая еще одну иконку такого-же размера в контейнере ICO файла, либо делая flat в один чанк. Заставить одно изображение налезть на другое можно, но только обработкой. Нужно было это еще для тех времен когда палитры в 256 цветов были рядом с 16к и надо было рисовать разные иконки, учитывая возможности системы. То о чем сейчас не думают вовсе.
Сам-же браузер, как и многие программы просмотра, рассматривают формат по заголовку ICONDIR, а конкретно idCount, и забирает ПОСЛЕДНЮЮ иконку нужного ему формата. Поведение Хрома тут какраз-таки и не правильное, т.к. он берет первое изображение и не обрабатывает далее.
Revertis
То есть баг ещё и в GIMP, который позволяет экспортировать .ico с одинаковыми слоями. Какой-нибудь IcoFX (редактор иконок) не позволяет даже создать два одинаковых варианта.
daggert
Вы имеете ввиду что можно затолкать несколько изображений одинакового размера? Это не баг, запрета на это не описано. То что ICO контейнер используют как контейнер под 1 иконку разного размера и цвета - привычка, не более того. В винде, а конкретно я такое делал в Борланд С++ в 2004 году, вы можете в зависимости от цветности экрана загрузить ресурсы как из ICO с указанием конкретной иконки, вроде через file.com:{id} синтаксис (но уже не помню точно), например для подгрузки иллюстраций на кнопки.