smallest filesize for transparent single pixel image
The smallest valid transparent GIF is 35 bytes.
data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=
47 49 46 38 39 61 01 00 01 00 00 00 00 21 f9 04 01 00 00 00 00 2c
00 00 00 00 01 00 01 00 00 02 01 00 00
This should work in every browser, new and old, as well as basically any image editor/viewer. However, it might not work with weak GIF parsers such as the one in PHP's image library.
If you need it to be absolutely foolproof, then the minimum is 41 bytes:
data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAAAAAAALAAAAAABAAEAAAIBAAA=
47 49 46 38 39 61 01 00 01 00 80 00 00 FF FF FF FF FF FF 21 F9 04
00 00 00 00 00 2C 00 00 00 00 01 00 01 00 00 02 01 00 00
Here's the explanation.
The smallest possible GIF can vary between different implementations of the GIF spec, and even over time. Web browsers have often been lenient and inconsistent with GIF rendering, allowing for partially damaged GIFs to display. Throughout the history of this answer, I had crafted a 14-byte GIF that was transparent only in Chrome, but this no longer works. There was a 23-byte version that worked in Chrome and Firefox, but it eventually stopped being transparent in Firefox. I settled on a 32-byte version that I thought worked everywhere, only to later discover it didn't work in Safari 14. Even a 33-byte version that fixed Safari 14 stopped working in Safari 15! So clearly it is better to follow the standards and not rely on hacky solutions that may not work forever. Though I should also mention that spacer GIFs haven't been relevant since 1996, and you really shouldn't be using them. Use CSS instead. I just wrote this answer to learn more about GIFs.
If we follow the official GIF spec, we come up with a figure of 43 bytes, made of the following parts:
- File signature, 6 bytes
- Logical Screen Descriptor, 7 bytes
- Global Color Table, 6 bytes
- Graphics Control Extension, 8 bytes
- Image Descriptor, 10 bytes
- Compressed LZW Image Data, 5 bytes
-
Trailer (
0x3B
), 1 byte
Some of this is technically optional. For example, the Trailer byte can be safely omitted and won't prevent the image from being rendered. The LZW data can be reduced to 4 bytes by changing the sub-block count to 1 instead of 2. That gets us to the 41-byte GIF above. We can then safely disable the Global Color Table by turning off a bit flag, which safely works in every browser, but might confuse inept GIF parsers. That gets us the 35-byte above.
Here is what I use in a C# byte array (avoids file access)
static readonly byte[] TrackingGif = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x1, 0x0, 0x1, 0x0, 0x80, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x2, 0x2, 0x44, 0x1, 0x0, 0x3b };
In asp.net MVC this can be returned like this
return File(TrackingGif, "image/gif");
Checkout this blank.gif
file (43 bytes). Less than 49 :D