diff --git a/src/lib/__tests__/emailHtml.test.ts b/src/lib/__tests__/emailHtml.test.ts
index 286de8f..94060df 100644
--- a/src/lib/__tests__/emailHtml.test.ts
+++ b/src/lib/__tests__/emailHtml.test.ts
@@ -104,14 +104,21 @@ describe("prepareHtml", () => {
assert.ok(!result.includes("filter:invert"));
});
- it("adapts only low-contrast neutral text in dark mode", () => {
+ it("adapts only low-contrast neutral text and list markers in dark mode", () => {
const result = prepareHtml(
documentWith(
- '
Black text
Brand text
Image-backed text
',
+ 'Black text
Brand text
Image-backed text
',
),
);
assert.ok(result.includes("data-email-client-adapted-text"));
- assert.ok(result.includes("contrastRatio(foreground,background)>=4.5"));
+ assert.ok(result.includes("data-email-client-adapted-marker"));
+ assert.ok(
+ result.includes(
+ "li[data-email-client-adapted-marker]::marker{color:#e2e8f0!important}",
+ ),
+ );
+ assert.ok(result.includes("getComputedStyle(element,'::marker')"));
+ assert.ok(result.includes("contrastRatio(foreground,background)<4.5"));
assert.ok(result.includes("spread>56||luminance(foreground)>0.18"));
assert.ok(
result.includes(
diff --git a/src/lib/emailHtml.ts b/src/lib/emailHtml.ts
index d9b1706..c60379f 100644
--- a/src/lib/emailHtml.ts
+++ b/src/lib/emailHtml.ts
@@ -186,10 +186,20 @@ function darkTextAdaptationScript(theme: EmailRenderTheme): string {
}
return parseRgb(${fallbackBackground});
}
+ function needsAdaptation(foreground,background){
+ if(!foreground||!background)return false;
+ var spread=Math.max(foreground.r,foreground.g,foreground.b)-
+ Math.min(foreground.r,foreground.g,foreground.b);
+ if(spread>56||luminance(foreground)>0.18)return false;
+ return contrastRatio(foreground,background)<4.5;
+ }
function adaptDarkText(){
- var marked=document.querySelectorAll('[data-email-client-adapted-text]');
+ var marked=document.querySelectorAll(
+ '[data-email-client-adapted-text],[data-email-client-adapted-marker]'
+ );
for(var i=0;i56||luminance(foreground)>0.18)continue;
- if(contrastRatio(foreground,background)>=4.5)continue;
- element.setAttribute('data-email-client-adapted-text','true');
+ if(!background)continue;
+
+ if(element.tagName==='LI'&&String(element.textContent||'').trim()){
+ var markerStyle=window.getComputedStyle(element,'::marker');
+ var markerColour=parseRgb(markerStyle.color)||parseRgb(computed.color);
+ if(needsAdaptation(markerColour,background)){
+ element.setAttribute('data-email-client-adapted-marker','true');
+ }
+ }
+
+ if(hasDirectText(element)&&needsAdaptation(parseRgb(computed.color),background)){
+ element.setAttribute('data-email-client-adapted-text','true');
+ }
}
}
if(darkMode){
@@ -321,6 +336,7 @@ export function prepareHtml(
body:not([text]){color:${theme.textDarkColor}}
body:not([link]) a{color:${theme.linkDarkColor}}
[data-email-client-adapted-text]{color:${theme.textDarkColor}!important}
+ li[data-email-client-adapted-marker]::marker{color:${theme.textDarkColor}!important}
}
`;
const inject = `${viewport}${baseStyle}${resizeScript(!!opts?.stripQuotes, theme)}`;