Toggle WebFonts on/off in Marketo Email Preview (or your own pages)

You might be surprised that WebFonts (via CSS @font-face) are supported in Apple Mail for desktop and mobile. Those apps comprise at least 20% of email opens; using some methodologies, as much as 60%. Even the low end, IMO, doesn’t match the common take that “few” end users will see your fancy fonts!

Yes, you must fallback forcefully for Outlook. But it’s totally doable: this month (August 2026) I’ve seen WebFont-enabled emails from CDW, Dolby, London Review of Books, Malwarebytes, Mural, Salesforce, Verizon, and Zapier.

Juice-worth-squeeze questions remain[1] but here’s something to make adoption easier. With the code below, you get a toggle in Email Editor 2.0 Preview to switch between WebFont-enabled view, emulating Apple Mail:

And WebFont-disabled view, emulating (almost) everything else:

Hold on — if Marketo supports WebFonts in Preview, why doesn’t our self-hosted corporate font show up?

Sounds like you’re using <link rel="stylesheet"> to load @font-face rules. The <link> method won’t work in Preview unless the url() points to Google Fonts or Adobe Fonts.

That strict allow-list, enforced via CSP, leads people to think WebFonts aren’t supported, when font files themselves totally are. Just need to reference them in a local <style> instead:

<style>
@font-face {
    font-family: "Example Corporate New";
    font-weight: 100;
    src: url("https://assets.example.com/67d2f61b52ec4/custom-fonts/example-sans-pro-thin.ttf");
}
</style>

Add the toggle

Put the code below in a Velocity token {{my.WebFont Manager}} and include it anywhere in the email <body>:

#if( $mktmail.DefaultTrackingHost.equals("localhost") )
<teknkl-webfont-control popover="manual" tabindex="0" style="all: initial; display: none;">
      <template shadowrootmode="open">
        <form>
          <label title="Click to toggle all WebFonts&#x0D;&#x0A;Focus and ↑/↓ on keyboard to move widget">
          WebFonts
          <input type="checkbox" checked switch>
        </label>
        </form>
        <style>     
          :host, 
          :host([data-manual-position-y="ArrowUp"]) {            
            top: 60px !important;
            right: -2px !important;
          }
          :host([data-manual-position-y="ArrowDown"]) {            
            top: auto !important;
            bottom: 60px !important;
          }
          
          form {
            font-family: system-ui;
            font-size: 16px;
            border-radius: 12px 0 0 12px;
            box-shadow: 2px 2px 0 currentColor;
            background-color: gainsboro;
            color: #222;
            clip-path: inset(0 0px -2px 0);
            user-select: none;
            -webkit-text-stroke: 0.25px;
            padding: 5px 10px 6px 12px;
            
          }

          label, 
          input {
            cursor: pointer;
          }
          
          input {
            vertical-align: text-bottom;
            margin-left: 4px;
            filter: drop-shadow(1px 1px 0px currentColor);
            height: 16px;
            width: 16px;
            outline: none !important;
          }

          
          @supports (font: -apple-system-body) {
            :host {
              -webkit-text-stroke: 0;
            }
            input[switch] {
              filter: none;
              height: auto;
              width: auto;
            }
          }
        </style>
<script>
/**
 * Add WebFont toggle to any page 
 * @author Sanford Whiteman
 * @version v1.0.1 2026-09-01
 * @license Hippocratic 3.0: This license must appear with all reproductions of this software.
 *
 */
          {
            const allowedSuffixes = [".marketodesigner.com"];
            const allowedProtocols = ["about:"];
            const allowedHashes = ["#enable-webfont-control"];

            const unicodeNullOnly = "U+0";
            const unicodeAll = "U+0-10FFFF";
            
            const previewDocument = document.querySelector("[data-testid='emailDesignerPreview']")?.contentDocument || document; 
            const control = previewDocument.querySelector("teknkl-webfont-control");
            const input = control.shadowRoot.querySelector("input[type='checkbox']");
                      
            input.addEventListener("change", {
              unicodeRangeCache: new WeakMap(),
              handleEvent(e) {
                for (const font of previewDocument.fonts) {
                  if ( e.target.checked && this.unicodeRangeCache.has(font) ) {
                    console.log("Restoring WebFont",font)
                    font.unicodeRange = this.unicodeRangeCache.get(font);
                  } else if ( !e.target.checked ) {
                    if ( font.unicodeRange !== unicodeNullOnly ) {
                      console.log("Storing and disabling WebFont",font)
                      this.unicodeRangeCache.set(font, font.unicodeRange);
                      font.unicodeRange = unicodeNullOnly;                  
                    }
                  }
                }
              }
            });

            control.addEventListener("keyup",{
              handleEvent(e){
                if( ["ArrowUp","ArrowDown"].includes(e.key) ) {
                  control.dataset.manualPositionY = e.key;
                }
              }            
            });

            if( allowedHashes.includes(previewDocument.location.hash) ||
                allowedProtocols.includes(previewDocument.location.protocol) || 
                allowedSuffixes.some( (suffix) => ("." + previewDocument.location.hostname).endsWith(suffix) ) ||
 ) {
              control.style.display = "block";
              control.showPopover();
            }
          }
        </script>
      </template>
    </teknkl-webfont-control>
#end

More features of the widget

  • The toggle widget appears at the upper right by default. You might want to move it out of the way on certain designs. Focus the widget via click or tab and use the ↑ and ↓ keys to move it.
  • You can also use the widget in View as Web Page view if you want. Set the URL hash to #enable-webfont-control and refresh.
  • Progressively enhanced with the new <input checkbox switch> on Safari. Not completely sold on it but was fun to explore.
  • <teknkl-webfont-control> isn’t a real Custom Element but an undefined HTMLElement to make it easier to see in the DOM.🤷‍♂️

Use it on non-Marketo pages as well

The only Marketo-specific part is the Velocity #if wrapper to restrict output to Marketo web views. You can paste the HTML into any site you want, just add your domain(s) to allowedSuffixes.

Browser compatibility

The widget works in late-model Blink and Webkit browsers: Chrome, Edge, and Safari. Firefox doesn’t work because its CSS Font Loading API implementation ignores programmatic changes to the unicode-range property. (Might be a hackier method that works in Firefox, but for an admin-only tool it’s not worth the complexity.)

Marketo editor compatibility

The widget is designed for Email Editor 2.0. It doesn’t work with Email Editor 3.0, though preparations are underway and at a future date I’ll publish an additional bookmarklet that’s necessary for 3.0 support.

Notes

[1] Multi-device users are one mystery: if a person sees fancy fonts on their iPhone but generic fonts on their Windows desktop, do they round down or round up, brand-wise?