I'm not sure which operating system you're aiming for, but you can build your FS driver in FUSE for linux or WinFUSE for Windows, which allow you to write your own filesystem drivers in userspace. You write your code which translates filesystem calls to zlib calls, and you're good to go.
There are, however, a lot of caveats that you should be aware of. Keeping a zip-based filesystem means you're replacing disk storage for CPU activity, to unzip the files when needed. You would often be surprised, however, at how frequently data is accessed, and you should plan accordingly, so you don't end up re-extracting the same files over and over again.
For instance, Windows Explorer doesn't use only the file extension to determine a file's icon - it digs into the file to find an icon handler, and uses that, so an Excel file saved as XML, for instance, will still get the Excel icon. If you're implementing your own filesystem you should be aware of things like that, and maybe save a fast cache of the first 1k or so of every file so you won't have to extract it all whenever Windows Explorer wants a peek. (This example courtesy of Raymond Chen)
This is just one example, and I'm sure that other programs have their own idiosyncracies. Best idea is to start with a naive implementation and start testing it under real-world conditions, profile and see what triggers excessive re-extractions.