[Перевод] Фавиконы в 2021 году: шесть самых важных файлов

Пришло время переосмыслить используемый нами подход к подготовке наборов фавиконов для современных браузеров и остановить безумие генераторов фавиконов. В наши дни фронтенд-разработчикам приходится иметь дело с более чем 20 статическими PNG-файлами только для того чтобы вывести на вкладке браузера или на сенсорном экране миниатюрный логотип сайта. В этом материале раскрывается более разумный подход к работе с фавиконами, который направлен на подбор минимального количества файлов, использование которых способно решить большинство «фавиконных» задач, стоящих перед современным веб-разработчиков.

Известно, что создание фавиконов — это гораздо сложнее, чем многим хотелось бы. Поэтому я, чтобы не мучить тех, кто уже достаточно от всего этого настрадался, кто точно знает, что делать, собрал всю суть статьи в паре примеров кода. Но я, всё равно, советую читать этот материал целиком.

Очень короткая версия статьи

Вместо того чтобы готовить для сайта десятки фавиконов — достаточно будет создать пять иконок и один JSON-файл.

Вот HTML-код, который попадает в браузер:

<link rel="icon" href="/favicon.ico"><!-- 32×32 -->
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple.png"><!-- 180×180 -->
<link rel="manifest" href="/manifest.webmanifest">

Вот код, который предназначен для манифеста веб-приложения:

// manifest.webmanifest
{
  "icons": [
    { "src": "/192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

Вот и всё. А если вы хотите узнать о том, как я до всего этого дошёл, на какие компромиссы мне пришлось пойти, и о том, как самостоятельно, с нуля, создать подобный набор файлов — читайте дальше. Ниже я всё объясню и приведу пошаговые примеры.

Длинная версия статьи, в которой даны все необходимые пояснения

Совершенство достигнуто не тогда, когда нечего добавить, а когда нечего убрать.

Антуан де Сент-Экзюпери

Понятие «фавикон» (favicon, favorite icon, значок для избранного) существует с начала 2000-х годов. Все мы видели фавиконы в списках вкладок браузеров — маленькие симпатичные изображения, которые помогают различать открытые страницы. Пользователи ожидают наличия фавиконов у сайтов. Это — одна из тех мелочей, внимание к которым со стороны разработчика сайта заставляет воспринимать этот сайт как некий серьёзный проект.

Даже компания Apple, у которой всегда были претензии эстетического плана, направленные на иконки, созданные не в Купертино, и которая не уделяла особого внимания фавиконам в Safari, наконец сдалась. Теперь фавиконы правильно отображаются на всех устройствах от Apple.

Если у вас есть общедоступный веб-сайт — у него должен быть фавикон. К сожалению, то, что пользователи воспринимают в виде одной иконки, на самом деле представлено множеством изображений.

Часто тяжёлый труд по созданию графических файлов, необходимых для поддержки постоянно растущего списка экранов и устройств, перекладывают на генераторы фавиконов. Никто, пребывающий в здравом уме, не станет тратить многие часы на ручное создание этих изображений. Мы, в конце концов, занимаемся разработкой сайтов, смысл нашей жизни не в том, чтобы угождать производителям браузеров.

Набор фавиконов, созданный популярным онлайн-генератором

Я, как создатель NanoID и сторонник минималистичного опенсорса, обычно склонен смотреть в несколько ином направлении. Какой набор графических файлов позволяет наиболее эффективно обеспечить веб-сайт фавиконами? Какие форматы являются устаревшими? Иконки каких типов можно заменить на другие, пойдя на небольшие компромиссы?

Размышляя об этом, я решил создать минимальный набор фавиконов, который подойдёт для всех ситуаций и будет работать во всех браузерах. Его единственный недостаток заключается в том, что в некоторых особых случаях он, хотя окажется работоспособным, не позволит добиться на 100% идеального результата.

Универсальный набор фавиконов

Вместо того чтобы создавать множество изображений разных размеров, я решил положиться на формат SVG и на возможности браузеров по уменьшению масштабов картинок. Если вы беспокоитесь о производительности — сейчас я внесу ясность в этот вопрос:

  • Браузеры загружают фавиконы в фоновом режиме. Поэтому загрузка достаточно большого изображения фавикона не повредит производительности сайта.
  • Применение формата SVG позволяет экономно хранить изображения, не являющиеся растровыми. Так, в случае с большинством логотипов, их хранение в формате SVG даёт гораздо меньший размер файла, чем использование формата PNG.
  • В этом минималистичном наборе фавиконов имеется всего три PNG-изображения. Для оптимизации их размеров можно использовать продвинутые инструменты. Это позволяет решить проблемы тех пользователей, у которых нет безлимитного интернет-подключения.

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

I. Файл favicon.ico для устаревших браузеров

ICO-файлы, на самом деле, имеют структуру директорий. В них могут быть упакованы графические файлы разных размеров. Я рекомендую остановиться на одном изображении размера 32×32 пикселя. Если же это изображение плохо масштабируется до размера 16×16 (например, оказывается размытым), то вам стоит попросить дизайнера создать его высококачественную уменьшенную версию.

Не стоит увлекаться экспериментами со структурой папки для статических ресурсов и со средствами для улучшения кеширования ресурсов сайта. Предположим, у нас имеется сайт https://example.com. Его фавикон должен находиться по адресу https://example.com/favicon.ico. Некоторые программы, вроде RSS-читалок, пытаясь загрузить фавикон, просто запрашивают с сервера файл /favicon.ico и не утруждают себя поисками этого файла где-то ещё.

II. Одна SVG-иконка с поддержкой тёмной и светлой темы для современных браузеров

SVG — это векторный графический формат, описывающий не пиксели, а кривые. SVG-файлы, при хранении некоторых больших изображений, оказываются эффективнее растровых форматов. На момент написания этого текста 72% браузеров поддерживают SVG-иконки.

Для подключения к HTML-странице SVG-значка в её коде, в разделе <head>, должен быть тег <link>, в котором имеются атрибуты rel="icon", type="image/svg+xml" и атрибут href со ссылкой на SVG-файл.

SVG-файлы содержат XML-данные, в состав которых может входить тег <style>, содержащий CSS-код. Тут, как и в любом CSS-коде, могут использоваться медиазапросы, наподобие @media (prefers-color-scheme: dark). Это позволяет организовать подстройку внешнего вида значка под системную тему — тёмную или светлую.

III. PNG-файл размером 180×180 для устройств Apple

Если добавить веб-страницу на домашний экран iPhone или iPad — в качестве значка для её открытия будет использовано изображение, указанное в разделе страницы <head>, в теге, который может выглядеть как <link rel="apple-touch-icon" href="icon.png">.

Устройства iPad, начиная с iOS 8+, требуют использования изображений размером 180×180 пикселей. Другие устройства могут уменьшить изображение. Если подготовить исходное изображение достаточно высокого качества, то его уменьшение не повредит конечным пользователям (мы ещё об этом поговорим).

Хочу дать небольшой совет о подготовке значков, рассчитанных на устройства Apple. Значок будет выглядеть лучше в том случае, если вокруг основного изображения будет поле размером в 20 пикселей, и если фон значка будет закрашен каким-то цветом. Изображение можно обработать подобным образом, воспользовавшись любым графическим редактором.

IV. Манифест веб-приложения с PNG-значками размерами 192×192 и 512×512, рассчитанными на Android-устройства

  • Манифест веб-приложения — это JSON-файл, содержащий сведения, необходимые браузеру для установки приложения на устройство. Формат этого файла предложен Google в рамках технологии PWA.
  • Манифест подключается к веб-странице посредством тега, который может выглядеть как <link rel="manifest" href="path.webmanifest">.
  • В манифесте должно присутствовать поле icons, в котором содержатся ссылки на две иконки. Одна из них, размерами 192×192 пикселя, используется для значка приложения на домашнем экране. Другая, размером 512×512, применяется в качестве экрана-заставки, показываемого при загрузке PWA.
{
  "icons": [
    { "src": "/192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

Не забыли ли мы о чём-нибудь?

Мы поговорили лишь о нескольких форматах фавиконов, но, на самом деле, существует гораздо больше их разновидностей. Некоторые из них не отличаются широкой известностью. Поэтому поговорим о том, как те значки, которые мы описали выше, ведут себя в различных ситуациях. Забегая вперёд, скажу, что, возможно, пришло время попрощаться с некоторыми форматами фавиконов, не получившими широкого распространения.

Иконки для плиточного интерфейса Windows

Браузер Microsoft Edge поддерживал иконки особого формата, используемые при закреплении сайтов в стартовом меню. В современных версиях Windows это уже не нужно.

Иконки для закреплённых вкладок Safari

Браузер Safari выдвигал особые требования для иконок, которые предназначены для закреплённых вкладок. Но, с выхода Safari 12, на таких вкладках можно использовать обычные фавиконы. Даже на apple.com больше не используется mask-icon.

Атрибут rel=«shortcut»

Во множестве руководств (теперь устаревших) предлагается включать favicon.ico в HTML с помощью следующей конструкции:

<link rel="shortcut icon" href="/favicon.ico">

Обратите внимание на то, что ключевое слово shortcut не является допустимым значением атрибута rel и никогда таковым не являлось. Вот отличная статья десятилетней давности, в которой можно найти соответствующие пояснения и указание на то, что конструкция rel="icon" — это всё, что нужно.

Табло браузера Яндекс

Браузер Яндекс основан на Chromium. Его разработкой занимается крупнейшая российская поисковая система, которой принадлежит 20% рынка поиска в России. У этого браузера есть удобная функция, которая позволяет сайтам выводить актуальные данные в виджетах, закреплённых на особой панели, называемой Табло. Для реализации этого функционала нужен особый JSON-файл манифеста, загружаемой по ссылке, значением атрибута rel которой является yandex-tableau-widget. Но оказалось, что эта возможность особой популярностью не пользуется. Компания Яндекс удалила со своего сайта соответствующую техническую документацию. В результате для нормальной работы с сайтами в браузере Яндекс достаточно обычного файла-манифеста.

Браузер Opera Coast

Opera Coast — это экспериментальный браузер для iOS, который требовал использования иконок особого размера — 228×228. В 2017 году браузер исчез из App Store. Я сомневаюсь, что он пережил множество обновлений iOS, которые были выпущены с тех пор.

Собственно говоря, теперь, когда мы попрощались технологиями, ушедшими в небытие, поговорим о том, как подготовить универсальный набор фавиконов, подходящих для актуальных браузеров и устройств.

Создание универсального набора фавиконов

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

Шаг 1. Подготовка SVG-файла

Проверьте, чтобы ваш исходный SVG-файл был бы квадратным. Откройте исходный файл в вашей системной программе просмотра графики и проверьте ширину и высоту изображения. Если файл нуждается в правке — сделать это можно в любом SVG-редакторе. Например, в Inkscape можно изменить размеры документа, перейдя по пули File > Document Properties. Выровнять логотип по центру изображения можно, прибегнув к команде Object > Align and Distribute.

Сохраните файл с именем icon.svg. Теперь давайте поработаем с кодом SVG-файла, подготовим этот файл к работе с темами, поддерживаемыми современными системами. Уточните у дизайнера вопрос о том, как должны меняться цвета в варианте изображения, рассчитанном на тёмную тему (если речь идёт о чёрно-белом логотипе, то достаточно просто поменять чёрный цвет на белый, а белый — на чёрный).

Теперь откройте SVG-файл в текстовом редакторе. Найдите элемент <path>, в котором значение fill отсутствует или представлено тёмным цветом. Добавьте в код медиа-запрос CSS, который срабатывает при изменении темы, и соответствующим образом поменяйте цвета этого элемента:

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
+   <style>
+     @media (prefers-color-scheme: dark) {
+     .a { fill: #f0f0f0 }
+     }
+   </style>
-   <path fill="#0f0f0f" d="…" />
+   <path class="a" fill="#0f0f0f" d="…" />
  </svg>

Шаг 2. Создание ICO-файл

Откройте файл icon.svg в растровом графическом редакторе. Я рекомендую GIMP — бесплатный многоплатформенный редактор.

Согласитесь с растеризацией SVG-изображения. Установите ширину и высоту изображения в 32 пикселя. Экспортируйте изображение в файл favicon.ico, используя настройки 2 bpp, 8-bit alpha, no palette.

Уменьшите изображение до размеров 16×16 пикселей и проверьте его качество. Если оно окажется слишком сильно размытым — лучше будет попросить дизайнера сделать особую версию этого изображения, хорошо выглядящую в маленьком размере.

Для того чтобы включить в состав favicon.ico отдельную версию значка размером 16×16 пикселей, выполните следующие действия:

  1. Откройте favicon.ico, содержащий изображение размером 32×32 пикселя.
  2. Создайте новый слой размером 16×16.
  3. Поместите изображение значка размера 16×16 пикселей на этот слой.
  4. Экспортируйте файл. GIMP сохранит каждый вариант значка в виде отдельной версии.

Шаг 3. Создание PNG-изображения

Снова откройте исходный SVG-файл в растровом редакторе и создайте изображение размером 512×512 пикселей. Экспортируйте его в файл icon-512.png. Уменьшите изображение до размером 192×192 пикселя и экспортируйте его в файл icon-192.png. Далее, уменьшите само изображение до размеров 140×140 пикселей, а размеры холста установите в 180×180. Экспортируйте изображение в файл apple-touch-icon.png.

Шаг 4. Оптимизация PNG- и SVG-файлов

Лучший инструмент для оптимизации SVG-файлов — это SVGO. Выполните следующую команду:

npx svgo --multipass icon.svg

Для оптимизации растровых изображений отлично подходит веб-приложение Squoosh.

  1. Откройте в Squoosh файл icon-512.png.
  2. Измените значение параметра Compress на OxiPNG.
  3. Включите установку Reduce palette.
  4. Установите количество цветов в 64.
  5. Пользуясь слайдером сравните то, как выглядело изображение до оптимизации, с тем, как оно выглядит после оптимизации. Если вы заметите различия — увеличьте количество цветов.
  6. Сохраните файл.

Повторите эти действия для файлов icon-192.png и apple-touch-icon.png.

Шаг 5. Подключение значков в HTML

Теперь нужно подключить favicon.ico и apple-touch-icon.png к веб-странице.

Вот как это выглядит в коде статической страницы:

  <title>My website</title>
+ <link rel="icon" href="/favicon.ico">
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">

Но мы рекомендуем использовать продвинутые средства для работы с кешем (речь идёт о включение в имя файла его хеша). Например, если вы пользуетесь Webpack с плагином html-webpack-plugin, выполните следующие действия:

  1. Создайте шаблон index.html.
  2. Добавьте этот шаблон в параметры плагина:
    new HtmlWebpackPlugin({ template: "./view/index.html" });
    
  3. Опишите HTML-шаблон с включёнными в него ссылками (здесь для включения в шаблон ссылок на файлы используется ERB, но вы можете пользоваться и другим языком описания шаблонов):
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>My website</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="icon" href="/favicon.ico">
        <link rel="icon" type="image/svg+xml" href="<%=
          require('./icon.svg').default
        %>">
        <link rel="apple-touch-icon" href="<%=
          require('./apple-touch-icon.png').default
        %>"
       >
      </head>
      <body></body>
    </html>
    
  4. Воспользуйтесь плагином copy-webpack-plugin для копирования favicon.ico без добавления к имени файла его хеша.

Совет: использование особого значка для окружения разработки

Разные фавиконы — это отличный механизм, позволяющий отличать продакшн-окружение от окружения для разработки ПО. Я полагаю, что использование альтернативного значка для окружения разработки крайне эффективно в деле предотвращения дорогостоящих ошибок.

Создадим файл favicon-dev.ico, содержащий то же изображение, что и обычный фавикон, но изображение каким-то образом изменённое (это могут быть инвертированные цвета, или нечто подобное). Точно так же создадим и файл icon-dev.svg.

Теперь настроим смену значков в HTML-шаблоне, проверяя условие process.env.NODE_ENV === 'production':

<!doctype html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>My website</title>
      <meta name="viewport" content="width=device-width,initial-scale=1">
-     <link rel="icon" href="/favicon.ico">
+     <link rel="icon" href="<%=
+       process.env.NODE_ENV === 'production'
+         ? '/favicon.ico'
+         : require('./favicon-dev.ico').default
+     %>">
      <link rel="icon" type="image/svg+xml" href="<%=
-       require('./icon.svg').default
+       process.env.NODE_ENV === 'production'
+         ? require('./icon.svg').default
+         : require('./icon-dev.svg').default
      %>">
      <link rel="apple-touch-icon" href="<%=
        require('./apple-touch-icon.png').default
      %>">
    </head>
    <body></body>
  </html>

Шаг 6. Создание манифеста веб-приложения

При работе со статическим HTML-кодом нужно создать JSON-файл с именем manifest.webmanifest:

{
  "name": "My website",
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

Этот файл нужно подключить в HTML-коде:

<title>My website</title>
+ <link rel="manifest" href="/manifest.webmanifest">
  <link rel="icon" href="/favicon.ico">
  <link rel="icon" href="/icon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">

При использовании Webpack можно воспользоваться плагином webpack-pwa-manifest:

plugins: [
    …,
    new WebpackPwaManifest({
      name: 'My website',
      icons: [
        { src: resolve('./icon-192.png'), sizes: '192x192' },
        { src: resolve('./icon512.png'), sizes: '512x512 }
      ]
    })
  ]

Итоги

Как видите, благодаря существованию современных веб-стандартов создать универсальный набор фавиконов не так уж и сложно. Но, хотя ручное выполнение вышеописанных задач не должно отнять у вас слишком много времени, ещё лучше было бы, если бы их можно было автоматизировать. Если вы хотите создать средство для автоматизации подобных задач — пишите мне в Twitter. Я буду более чем счастлив вам помочь.

Как вы готовите фавиконы для своих веб-проектов?

Let’s block ads! (Why?)

Read More

Recent Posts

В VK Рекламе появилась возможность продвижения каналов в Дзене

В сентябре 2023 года в кабинете VK Рекламы появился инструмент «Промо в Дзене», позволяющий продвигать статьи Дзена на платформе. Теперь…

1 час ago

Несколько СМИ запретили роботу «Яндекса» использовать свой контент для нейросетей

Администраторы сайтов «Городские порталы» (E1.ru, NGS.ru, «Фонтанка» и т. п., принадлежат Skhulev Media Holding) запретили поисковым роботам, в том числе…

11 часов ago

РСЯ представила новые возможности для создания конверсионных объявлений

Команда Яндекс Рекламы рассказала о новых возможностях для рекламодателей, которые помогут сделать рекламу в сетях привлекательнее и разнообразнее. Рассказываем, как…

22 часа ago

Павел Дуров: «Свобода дороже денег». Интервью Такеру Карлсону

Американский журналист Такер Карлсон опубликовал интервью с Павлом Дуровым. Для основателя ВКонтакте и Telegram это стало первым видеоинтервью с 2016…

1 день ago

Павел Дуров дал интервью Такеру Карлсону

Павел Дуров рассказал, что дал интервью Такеру Карлсону, американскому журналисту, который в феврале 2024 года провел интервью с Владимиром Путиным.…

2 дня ago

Яндекс Маркет изменил условия для попадания на платиновый уровень Клуба Маркета

Яндекс Маркет меняет условия для попадания на платиновый уровень Клуба Маркета в мае. Минимальное значение индекса цен для попадания в…

2 дня ago