Вчера на работе разработчик обратился ко мне с проблемой. Разговор шел примерно так:

Дев: Привет, Альваро! У нас проблема.

Я: Что не так?

Дев: Фавиконка на сайте неправильная. Это не наш корпоративный логотип.

Я: Что????

Дев: показывает экран

Я: .....

Я не мог поверить своим глазам: это был наш сайт, название было правильным, только фавиконка отображалась на вкладке не с логотипом компании, а с буквами «Алв» (от Альваро? ) Я обновлял и снова обновлял страницу, думая, что может это какой-то прикол. Но это было не так.

Примечание. Я удалил скриншоты названия и логотипа сайта, чтобы избежать проблем. Внизу статьи есть небольшой пример, воспроизводящий проблему.

Это озадачило меня. Фавиконка работала по-разному в зависимости от браузера. 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)


  1. daggert
    16.02.2022 14:05
    +24

    Это конечно перевод и писать комментарии бессмысленно но всеже - когда зумеры открывают для себя очевидные вещи это удивительно. Эта особенность известна со времен... 95й системы. Например старый пост: https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513

    ICO не поддерживает слои. Совсем. Вообще-вообще. Новый слой сохраняется в зависимости от программы либо как новый чанк, по сути создавая еще одну иконку такого-же размера в контейнере ICO файла, либо делая flat в один чанк. Заставить одно изображение налезть на другое можно, но только обработкой. Нужно было это еще для тех времен когда палитры в 256 цветов были рядом с 16к и надо было рисовать разные иконки, учитывая возможности системы. То о чем сейчас не думают вовсе.

    Сам-же браузер, как и многие программы просмотра, рассматривают формат по заголовку ICONDIR, а конкретно idCount, и забирает ПОСЛЕДНЮЮ иконку нужного ему формата. Поведение Хрома тут какраз-таки и не правильное, т.к. он берет первое изображение и не обрабатывает далее.


    1. Revertis
      16.02.2022 14:52

      То есть баг ещё и в GIMP, который позволяет экспортировать .ico с одинаковыми слоями. Какой-нибудь IcoFX (редактор иконок) не позволяет даже создать два одинаковых варианта.


      1. daggert
        16.02.2022 15:06
        +1

        Вы имеете ввиду что можно затолкать несколько изображений одинакового размера? Это не баг, запрета на это не описано. То что ICO контейнер используют как контейнер под 1 иконку разного размера и цвета - привычка, не более того. В винде, а конкретно я такое делал в Борланд С++ в 2004 году, вы можете в зависимости от цветности экрана загрузить ресурсы как из ICO с указанием конкретной иконки, вроде через file.com:{id} синтаксис (но уже не помню точно), например для подгрузки иллюстраций на кнопки.


  1. SShtole
    16.02.2022 14:07
    +20

    Формат .ico для favicon был навязан веб-сообществу на рубеже веков, когда самым популярным браузером был Internet Explorer. Он представляет собой альбом растровых изображений с поддержкой прозрачности. (Хотя термин «альбом» или “album” в статьях MSDN обычно не используется, по сути это именно он). У каждого изображения в альбоме есть свой размер и битность. В оригинальной среде (Windows) была принята следующая практика (то есть, считалось хорошим тоном, хотя и не было причин, заставляющих дизайнера так делать):

    • Изображения используются именно в UI.
    • Изображения стандартных размеров.
    • Все изображения в альбоме семантически эквивалентны. Везде нарисован один и тот же объект. В UI они взаимозаменяемы и программа, поддерживающая формат, может выбирать любое изображение по чисто техническим соображениям (например, в зависимости от режима отображения списка элементов: таблицей, мелкими значками, крупными и т.п.)
    • Художник рисует изображение подо все популярные размеры: от 16x16 до 256x256. Ленивый художник просто перерастрирует вектор в разные размеры. Неленивый художник адаптирует количество деталей под размер, меняет ракурс объекта и т.п.
    • Программа выбирает изображение нужного в данном месте UI размера. Если такого изображения нет, она подбирает ближайшее подходящее по размеру и рескейлит его как может.
    • Программа выбирает изображение нужной битности в соответствии с поддержкой видеорежима. Когда видеорежимы 8 и 16 бит (не на канал, а вообще! да, такое было!) ушли в прошлое, чтобы эта фича не пропала даром, в обиход вошёл протокол RDP, где малобитные режимы экономили трафик. Если такого изображения нет, она подбирает ближайшее подходящее по битности и адаптирует его как может.


    Формат, мягко говоря, подустарел, да и изначально был чисто виндовой штучкой. (Программисты Safari, наверное, после его поддержки тщательно вымыли руки). На смену ему используется много чего, от связки .png до авторастрируемого вектора, но курилка по-прежнему жив.

    Если всё это не знать, очень легко перепутать изображения со слоями (которых там просто нет) и поиметь проблем, описанных в статье.


  1. geekmeek
    16.02.2022 15:19

    Напомнил давний курьёз дозаписи на CD-Rы, когда с грустью обнаруживалось у друга на ноуте, что на дисках "всё затёрто" и осталась лишь последняя сессия... при том что на моём пишущем дисководе было видно всё в момент записи.


  1. Adler_lug
    16.02.2022 15:22
    +1

    Было подумал, что я что-то не знаю о файлах иконки, в частности о том, что там могут быть слои, но скачав пример стало понятно, что там просто две разные иконки одного размера в контейнере.