compatibility

Animated favicon: what actually works in each browser

Only Firefox animates a GIF favicon. Chrome, Edge, and Safari show one frame. Here is the GIF route, the JavaScript route, and how to pick without breaking your icon everywhere else.

FaviconMaker Editorial Team

5 min read
#compatibility#how-to#formats
Share this guide
Animated favicon: what actually works in each browser
On this page9 sections

An animated favicon is a browser-tab icon that moves. You can build one two ways: link an animated GIF, or swap the icon from JavaScript frame by frame. Neither works everywhere, so before you spend an afternoon on it, the honest summary is this: only Firefox animates a GIF favicon on its own. Chrome, Edge, and Safari show a single frame.

That is not a reason to skip it. It is a reason to build the static fallback first and treat motion as a bonus. If you already have a GIF, start here:

Browser support, as of 2026

BrowserAnimated GIF faviconJavaScript frame swap
FirefoxAnimatesWorks
ChromeFirst frame onlyWorks
EdgeFirst frame onlyWorks
SafariFirst frame onlyWorks, but unreliable

Chrome's request to support animated page icons was closed as "not planned", so this is a deliberate gap rather than a bug awaiting a fix. Assume most of your visitors see frame one.

There is a second limitation people discover late: browsers throttle timers in background tabs. An animation driven by setInterval slows to roughly one tick per second once the tab loses focus. An animated favicon is therefore something users mostly see while they are already looking at your tab.

This is the whole technique. Put both files at your site root and add two tags:

<!-- Static ICO: every browser can use this -->
<link rel="icon" href="/favicon.ico" sizes="any" />
<!-- Animated GIF last: Firefox animates it, others show frame one -->
<link rel="icon" type="image/gif" href="/favicon.gif" />

Order matters here, and not for the reason most people assume. When several icons are equally suitable, MDN documents that the browser uses the last one; if that one turns out to be unusable, it falls back to the next best. Putting the GIF last means Firefox reaches for the animation, and anything that cannot use it still has a real favicon.ico to fall back on.

A 512×512 source GIF is far larger than a tab needs. Resize it to 32×32 and the file usually drops by an order of magnitude, which matters because the icon loads on every page. The GIF to ICO tool does the resize and the first-frame ICO in one pass, keeping frame delays and the loop count intact.

Make frame one carry the whole message

Every browser that will not animate shows your first frame, and Google Search uses a static icon in results. If frame one is a blank canvas or the middle of a fade, most people see nothing. Design the loop so the opening frame is the logo, then animate away from it and back.

Option 2: swap the icon from JavaScript

To animate in Chromium browsers you have to replace the icon yourself on a timer. The mechanism is simply assigning a new href:

const frames = ['/icon-0.png', '/icon-1.png', '/icon-2.png'];
const link = document.createElement('link');
link.rel = 'icon';
document.head.appendChild(link);

let index = 0;
setInterval(() => {
  index = (index + 1) % frames.length;
  link.href = frames[index];
}, 200);

This works, and appending the link means it lands last in <head>, so it wins over earlier icons. But it has a cost that is easy to miss: the browser fetches the image every time the href changes. Running the snippet above in Chromium produced a request per frame — 25 requests in three seconds — because a favicon swap is a normal resource load.

Draw the frames instead

Rendering to a canvas and handing over a data URL avoids the network entirely. The same three seconds that cost 25 requests above cost zero here:

const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');

const link = document.createElement('link');
link.rel = 'icon';
document.head.appendChild(link);

let angle = 0;
setInterval(() => {
  ctx.clearRect(0, 0, 32, 32);
  ctx.fillStyle = '#1b1b1f';
  ctx.fillRect(0, 0, 32, 32);
  ctx.strokeStyle = '#22d3ee';
  ctx.lineWidth = 4;
  ctx.beginPath();
  ctx.arc(16, 16, 11, angle, angle + Math.PI * 1.2);
  ctx.stroke();
  angle += 0.4;
  link.href = canvas.toDataURL('image/png');
}, 200);

Canvas suits progress rings, spinners, and unread badges — anything generated from state. For hand-drawn artwork, pre-encode each frame as a data URL string at build time and cycle through those instead of hitting the network.

When an animated favicon is worth it

The technique earns its keep when the motion means something:

  • A progress or upload indicator so a background tab shows how far along a job is
  • An unread count on a chat or inbox tab
  • A build or deploy status on a dashboard someone leaves open

A logo that spins forever for no reason is the version people complain about. It competes with the tab title, it draws the eye away from whatever the reader is doing, and it burns a little CPU on every open tab.

Common problems

Nothing animates in Chrome. Expected. Chrome shows the first frame of a GIF. Use the JavaScript approach if you need motion there.

It animates locally, then stops after deploy. Check that the GIF is actually being served and is not being converted or stripped by your build. Run the Favicon Checker against the live URL to see what the server returns.

The old icon will not go away. Favicons cache hard. Follow the cache-busting checklist rather than clearing your browser cache repeatedly.

The animation looks like mush at 16px. A 32×32 icon is displayed around 16×16 on many screens. Thin strokes and small text disappear. Test at the real size before shipping.

Frame one is blank. See above; it is the frame most people will see.

FAQs

Does an animated favicon hurt SEO? No. Google Search shows a static icon, and it uses your first frame or your ICO. Nothing about animation changes how the icon is crawled. The rules in favicon not showing in Google Search still apply.

Can I use an animated SVG? Firefox will animate SVG favicons via CSS or SMIL. Chromium will not, and the same "not planned" decision covers it. If you already ship an SVG icon, keep the PNG/ICO fallback regardless.

What about APNG or animated WebP? Support is thinner than GIF and the fallback story is the same, so there is little to gain. GIF remains the format browsers actually accept for rel="icon".

How many frames should I use? Few. A tab icon is roughly 16 pixels across, so subtle motion over 4–12 frames reads better than a detailed sequence, and the file stays small.

Do I still need favicon.ico? Yes. It is the fallback for every browser that will not animate, and it covers contexts that never look at your <head> at all.

Ship it

  1. Build both files with GIF to ICO
  2. Upload favicon.ico and favicon.gif to your site root
  3. Paste the two <link> tags into <head>
  4. Confirm what is live with the Favicon Checker

If you would rather skip animation and get a complete, conventional icon set, the Favicon Generator produces the ICO, PNG sizes, manifest, and snippet in one step.

Put this guide into practice

Build a complete favicon pack, then test the live result before you ship.

Written by

FaviconMaker Editorial Team

Practical favicon guidance for designers, developers, and site owners, with a focus on files you can verify in production.

Follow new guides via RSS

Worth sharing?

Send this guide to someone fixing their site icon.

Keep learning

wix3 min

How to Change Favicon on Wix

Step-by-step: change your Wix favicon from the dashboard Settings, understand Premium + domain requirements, choose the right file format/size, and troubleshoot caching and Google display.

Read guide
shopify4 min

How to Change Favicon on Shopify

Step-by-step: change your Shopify store favicon via Theme settings, pick the right 16×16/32×32 image, understand plan limitations, and fix common caching and Google display issues.

Read guide