I'm building an IMAP webmail client. Problem is that HTML emails may include CSS which affects the layout / style of the client.
The app front-end is built on AngularJS.
One potential solution is to use frames / iframes. The problem with these is that you have to provide an src attribute. This content is reaching the browser as json data. I could potentially set the back-end up to provide a URL for each email but it means many more requests to the server.
Looking at the gmail DOM (for example) I don't see any use of frames, so I infer there must be alternate techniques out there.
I worked on a smallish project that was trying to do what you're describing here, though for different reasons. It was a lot of hard work, and in the end we gave up, and just went with the iframe solution.
The route we tried was similar to SpamAssassin:
<head>
by just extracting the innerHTML
of <body>
.<...float:left...>
and munged it by replacing it with floatXXX:left
. We did this for every CSS property we wanted to 'quarantine'.The problem was simply that, while we were able to 'quarantine' the CSS, it left most of the emails unusable. Formatting-only CSS (such as font-weight
) got caught in the crossfire, and the never-ending list of regex patterns to replace made it horrendously slow.
We tried to simplify this by putting a lot of defaults at the top of the page with !important
rules, then munging any inline !important
rules. This is the approach Yahoo takes. This improved performance but we continued to make too many emails unreadable.
I believe Google's approach is essential doing a reverse polyfill - they replace the browser's way of, say, handling floats with their own. However, this was beyond our ability and we didn't even try it.
In the end, the iframe solution is very quick to implement, and may well be quick enough to satisfy your users' needs. You can always roll out with that now, and update to a more complicated solution later. They also have the added advantage that they get pretty much full CSS support. The only thing I would disable in the iframed content is JavaScript, which can wreak havoc with the parent in a way that CSS cannot, and would also be very insecure.