I’m building a web app where I need to show email content alongside other information on the same page. The emails come from my server via AJAX calls and some contain HTML with inline styles that mess up my page layout.
I don’t want to use iframes because they don’t fit well with my responsive design. I noticed that email services like Outlook and Hotmail can display rich HTML emails without the email CSS interfering with their interface.
What techniques do these major email providers use to isolate email styling? Is there a way to sandbox the email HTML so it doesn’t affect my main page styles?
iframe sandboxing works better than you’d expect - just use srcdoc instead of src. Inject the email HTML directly and set sandbox=“allow-same-origin” for responsive stuff. Outlook web probably does this plus postMessage for resizing. Way cleaner than DOM manipulation and no style bleed.
Shadow DOM is your best bet for style isolation - it’s what email providers like Outlook and Hotmail use. Just attach a shadow root to a container element and inject the HTML content there. Any styles in the email won’t mess with your main page. I’ve used this in production and it works great on modern browsers. Pretty straightforward: create a div, attach shadow DOM, set the email HTML as innerHTML. Watch out though - older email HTML sometimes needs styles from the parent document, so you’ll want to set basic typography defaults in the shadow root. For browsers with weak shadow DOM support, try CSS containment with contain: style layout as a fallback, but the isolation won’t be as solid.
CSS scoping works great for this. Had the same issue last year with newsletter content in my dashboard. I preprocessed the email HTML server-side - added unique class prefixes to all CSS selectors and wrapped everything in a container with the same prefix. PostCSS works well for this, or you can write a simple parser. Don’t forget to sanitize and strip out global selectors like body/html tags that’ll leak out. It’s lighter than Shadow DOM and has better browser support. Pro tip: watch your CSS specificity. Give your scoped container enough weight to override conflicting styles from your main stylesheet - learned that one the hard way.