Hi everyone,
I’ve encountered a strange bug in the Anki app on my iPad. Initially, the built-in zoom feature works fine when I use it to enlarge the cards. However, when I switch to a different card, the card zooms in again, creating an unpleasant double-zoom effect that makes the text difficult to read and ruins the appearance of the card.
Resetting the zoom to 1.0x or zooming again doesn’t resolve the issue. The problem persists until I exit the deck and return. At that point, the cards look normal again and the zoom function works as expected – until I click on the answer again, which triggers the issue anew.
I’m not sure whether this issue stems from my HTML and CSS setup, whether I’m using the zoom feature incorrectly, or whether it’s a bug within the Anki app itself. I’ve scoured the internet for information, but I haven’t found anything relevant.
Interestingly, this issue does not occur on my iPhone, where the cards remain properly zoomed and readable.
For additional context, I’m using the latest version of Anki on my iPad (25.07.1) and version 25.02.6 on my computer.
For reference, I have included two screen recordings: one from my iPad showcasing this behavior, and another from my iPhone demonstrating smooth zooming and unzooming without any visual problems. Below are the front and back templates for recognition and recall cards, along with my CSS styles. Please note that I am using Tailwind CSS and am unsure whether this is contributing to the problem.
Thank you very much!
iPad Screen Recording:
iPhone Screen Recording:
Front Template (Recognition Card):
<div class="p-4">
<div
class="block rounded-lg solarized-bg-base02 text-left solarized-text-base2 shadow-md text-base max-w-xl m-auto"
>
<div class="border-b-2 border-[#002b36] px-6 py-3">
<div class="grid grid-cols-3 grid-rows-1 gap-0 items-center">
<div class="text-xs solarized-text-base1">
{{#Frequency}}
<div
class="solarized-bg-base01 solarized-text-base2 px-2 py-1 rounded text-xs inline-block"
>
{{Frequency}}
</div>
{{/Frequency}}
</div>
<div class="flex flex-col justify-center items-center">
{{#Lesson name (Hanzi)}}
<span
class="solarized-bg-base2 solarized-text-base02 text-xs font-medium px-2.5 py-0.5 rounded"
>
{{Lesson name (Hanzi)}}
</span>
{{/Lesson name (Hanzi)}} {{#HSK}}
<span
class="solarized-bg-base01 solarized-text-base2 text-xs px-2 py-0.5 rounded mt-1"
>
HSK {{HSK}}
</span>
{{/HSK}}
</div>
<div class="ml-auto flex items-center gap-2">
{{#Classifier}}
<span class="solarized-text-base1 text-xs">{{Classifier}}</span>
{{/Classifier}} {{#Sound}}
<span class="replay-button" style="display: none">{{Sound}}</span>
<!-- Custom Material Design play button -->
<a
href="#"
class="group p-2 rounded-full hover:bg-base01 transition sound-button"
title="Play audio"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="w-6 h-6 fill-current solarized-text-base2 group-hover:solarized-text-base0 transition-colors"
>
<title>volume-high</title>
<path
d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z"
/>
</svg>
</a>
{{/Sound}}
</div>
</div>
</div>
<div class="p-6">
<div class="flex items-center justify-between mb-2">
<h5 class="text-2xl font-medium leading-tight">{{Hanzi}}</h5>
{{#Traditional}}
<span
id="traditional-display"
class="solarized-text-base1 text-sm"
style="display: none"
>
{{Traditional}}
</span>
{{/Traditional}}
</div>
<p class="solarized-text-base1">{{Pinyin}}</p>
{{#Also Written}}
<p class="solarized-text-base01 text-sm mt-1">Also: {{Also Written}}</p>
{{/Also Written}}
</div>
</div>
</div>
<script>
(function () {
const tradSpan = document.getElementById("traditional-display");
if (!tradSpan) return;
const simplified = "{{Hanzi}}".trim();
const traditional = tradSpan.textContent.trim();
if (simplified !== traditional) {
tradSpan.style.display = "inline";
}
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
const hiddenBtn =
this.closest(".ml-auto").querySelector(".replay-button");
if (hiddenBtn) hiddenBtn.click();
});
});
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
// Find the closest parent with class "ml-auto"
const container = this.closest(".ml-auto");
if (!container) return;
// Then find the .replay-button > a inside it
const replayLink = container.querySelector(".replay-button a");
if (replayLink) {
replayLink.click(); // Simulate a click on the hidden replay link
}
});
});
})();
</script>
Back Template (Recognition Card):
<div class="p-4">
<div
class="block rounded-lg solarized-bg-base02 text-left solarized-text-base2 shadow-md text-base max-w-xl m-auto"
>
<!-- Same header as front template -->
<div class="border-b-2 border-[#002b36] px-6 py-3">
<div class="grid grid-cols-3 grid-rows-1 gap-0 items-center">
<div class="text-xs solarized-text-base1">
{{#Frequency}}
<div
class="solarized-bg-base01 solarized-text-base2 px-2 py-1 rounded text-xs inline-block"
>
{{Frequency}}
</div>
{{/Frequency}}
</div>
<div class="flex flex-col justify-center items-center">
{{#Lesson name (Hanzi)}}
<span
class="solarized-bg-base2 solarized-text-base02 text-xs font-medium px-2.5 py-0.5 rounded"
>
{{Lesson name (Hanzi)}}
</span>
{{/Lesson name (Hanzi)}} {{#HSK}}
<span
class="solarized-bg-base01 solarized-text-base2 text-xs px-2 py-0.5 rounded mt-1"
>
HSK {{HSK}}
</span>
{{/HSK}}
</div>
<div class="ml-auto flex items-center gap-2">
{{#Classifier}}
<span class="solarized-text-base1 text-xs">{{Classifier}}</span>
{{/Classifier}} {{#Sound}}
<span class="replay-button" style="display: none">{{Sound}}</span>
<!-- Custom Material Design play button -->
<a
href="#"
class="group p-2 rounded-full hover:bg-base01 transition sound-button"
title="Play audio"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="w-6 h-6 fill-current solarized-text-base2 group-hover:solarized-text-base0 transition-colors"
>
<title>volume-high</title>
<path
d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z"
/>
</svg>
</a>
{{/Sound}}
</div>
</div>
</div>
<div class="p-6">
<div class="flex items-center justify-between mb-2">
<h5 class="text-2xl font-medium leading-tight">{{Hanzi}}</h5>
{{#Traditional}}
<span
id="traditional-display"
class="solarized-text-base1 text-sm"
style="display: none"
>
{{Traditional}}
</span>
{{/Traditional}}
</div>
<p class="solarized-text-base1">{{Pinyin}}</p>
{{#Also Written}}
<p class="solarized-text-base01 text-sm mt-1">Also: {{Also Written}}</p>
{{/Also Written}}
</div>
<hr id="answer" class="border-[#002b36]" />
<div class="block rounded-b-lg solarized-bg-base3">
<div class="p-6">
<div class="mb-4">
<h5
class="text-xl font-medium leading-tight solarized-text-base02 mb-2"
>
{{French}}
</h5>
</div>
{{#Notes}}
<div class="mb-4">
<hr
class="w-48 h-px mx-auto my-4 solarized-bg-base2 border-0 rounded"
/>
<div class="solarized-text-base01 text-sm">{{Notes}}</div>
</div>
{{/Notes}} {{#Example 1 (Chinese)}}
<div class="inline-flex items-center justify-center w-full mt-6 mb-4">
<hr class="w-full h-px solarized-bg-base2 border-0" />
<span
class="absolute px-3 font-medium solarized-text-base02 solarized-bg-base3"
>
Exemples
</span>
</div>
<div class="space-y-3">
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 1 (Chinese)}}</div>
{{#Example 1 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 1 (French)}}
</div>
{{/Example 1 (French)}}
</div>
{{#Example 2 (Chinese)}}
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 2 (Chinese)}}</div>
{{#Example 2 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 2 (French)}}
</div>
{{/Example 2 (French)}}
</div>
{{/Example 2 (Chinese)}} {{#Example 3 (Chinese)}}
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 3 (Chinese)}}</div>
{{#Example 3 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 3 (French)}}
</div>
{{/Example 3 (French)}}
</div>
{{/Example 3 (Chinese)}}
</div>
{{/Example 1 (Chinese)}}
</div>
</div>
</div>
</div>
<script>
(function () {
const tradSpan = document.getElementById("traditional-display");
if (!tradSpan) return;
const simplified = "{{Hanzi}}".trim();
const traditional = tradSpan.textContent.trim();
if (simplified !== traditional) {
tradSpan.style.display = "inline";
}
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
const hiddenBtn =
this.closest(".ml-auto").querySelector(".replay-button");
if (hiddenBtn) hiddenBtn.click();
});
});
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
// Find the closest parent with class "ml-auto"
const container = this.closest(".ml-auto");
if (!container) return;
// Then find the .replay-button > a inside it
const replayLink = container.querySelector(".replay-button a");
if (replayLink) {
replayLink.click(); // Simulate a click on the hidden replay link
}
});
});
})();
</script>
Front Template (Recall Card):
<div class="p-4">
<div
class="block rounded-lg solarized-bg-base02 text-left solarized-text-base2 shadow-md text-base max-w-xl m-auto"
>
<!-- Header (same as Recognition cards) -->
<div class="border-b-2 border-[#002b36] px-6 py-3">
<div class="grid grid-cols-3 grid-rows-1 gap-0 items-center">
<div class="text-xs solarized-text-base1">
{{#Frequency}}
<div
class="solarized-bg-base01 solarized-text-base2 px-2 py-1 rounded text-xs inline-block"
>
{{Frequency}}
</div>
{{/Frequency}}
</div>
<div class="flex flex-col justify-center items-center">
{{#Lesson name (Hanzi)}}
<span
class="solarized-bg-base2 solarized-text-base02 text-xs font-medium px-2.5 py-0.5 rounded"
>
{{Lesson name (Hanzi)}}
</span>
{{/Lesson name (Hanzi)}} {{#HSK}}
<span
class="solarized-bg-base01 solarized-text-base2 text-xs px-2 py-0.5 rounded mt-1"
>
HSK {{HSK}}
</span>
{{/HSK}}
</div>
<div class="ml-auto flex items-center gap-2">
{{#Classifier}}
<span class="solarized-text-base1 text-xs">{{Classifier}}</span>
{{/Classifier}}
</div>
</div>
</div>
<!-- Main Recall Prompt -->
<div class="p-6 flex flex-col items-center gap-3 text-center">
<div class="text-xl font-semibold">{{French}}</div>
</div>
<div class="block rounded-b-lg solarized-bg-base3">
<div class="p-6">
<div class="mb-4">
<h5
class="text-xl font-medium leading-tight solarized-text-base02 mb-2"
>
{{#Silhouette}}
<div class="flex items-center justify-between mb-2">
<h5 class="text-2xl font-medium leading-tight">{{Silhouette}}</h5>
</div>
{{/Silhouette}} {{#Pinyin}}
<p class="solarized-text-base1">{{hint:Pinyin}}</p>
{{/Pinyin}}
</h5>
</div>
</div>
</div>
</div>
</div>
Back Template (Recall Card):
<div class="p-4">
<div
class="block rounded-lg solarized-bg-base02 text-left solarized-text-base2 shadow-md text-base max-w-xl m-auto"
>
<!-- Same header as front template -->
<div class="border-b-2 border-[#002b36] px-6 py-3">
<div class="grid grid-cols-3 grid-rows-1 gap-0 items-center">
<div class="text-xs solarized-text-base1">
{{#Frequency}}
<div
class="solarized-bg-base01 solarized-text-base2 px-2 py-1 rounded text-xs inline-block"
>
{{Frequency}}
</div>
{{/Frequency}}
</div>
<div class="flex flex-col justify-center items-center">
{{#Lesson name (Hanzi)}}
<span
class="solarized-bg-base2 solarized-text-base02 text-xs font-medium px-2.5 py-0.5 rounded"
>
{{Lesson name (Hanzi)}}
</span>
{{/Lesson name (Hanzi)}} {{#HSK}}
<span
class="solarized-bg-base01 solarized-text-base2 text-xs px-2 py-0.5 rounded mt-1"
>
HSK {{HSK}}
</span>
{{/HSK}}
</div>
<div class="ml-auto flex items-center gap-2">
{{#Classifier}}
<span class="solarized-text-base1 text-xs">{{Classifier}}</span>
{{/Classifier}} {{#Sound}}
<span class="replay-button" style="display: none">{{Sound}}</span>
<!-- Custom Material Design play button -->
<a
href="#"
class="group p-2 rounded-full hover:bg-base01 transition sound-button"
title="Play audio"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="w-6 h-6 fill-current solarized-text-base2 group-hover:solarized-text-base0 transition-colors"
>
<title>volume-high</title>
<path
d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z"
/>
</svg>
</a>
{{/Sound}}
</div>
</div>
</div>
<div class="p-6 flex flex-col items-center gap-3 text-center">
<!-- Main Recall Prompt -->
<div class="text-xl font-semibold">{{French}}</div>
</div>
<hr id="answer" class="border-[#002b36]" />
<div class="block rounded-b-lg solarized-bg-base3">
<div class="p-6">
<div class="mb-4">
<h5
class="text-xl font-medium leading-tight solarized-text-base02 mb-2"
>
<div class="flex items-center justify-between mb-2">
<h5 class="text-2xl font-medium leading-tight">{{Hanzi}}</h5>
{{#Traditional}}
<span
id="traditional-display"
class="solarized-text-base1 text-sm"
style="display: none"
>
{{Traditional}}
</span>
{{/Traditional}}
</div>
<p class="solarized-text-base1">{{Pinyin}}</p>
{{#Also Written}}
<p class="solarized-text-base01 text-sm mt-1">
Also: {{Also Written}}
</p>
{{/Also Written}}
</h5>
</div>
{{#Notes}}
<div class="mb-4">
<hr
class="w-48 h-px mx-auto my-4 solarized-bg-base2 border-0 rounded"
/>
<div class="solarized-text-base01 text-sm">{{Notes}}</div>
</div>
{{/Notes}} {{#Example 1 (Chinese)}}
<div class="inline-flex items-center justify-center w-full mt-6 mb-4">
<hr class="w-full h-px solarized-bg-base2 border-0" />
<span
class="absolute px-3 font-medium solarized-text-base02 solarized-bg-base3"
>
Exemples
</span>
</div>
<div class="space-y-3">
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 1 (Chinese)}}</div>
{{#Example 1 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 1 (French)}}
</div>
{{/Example 1 (French)}}
</div>
{{#Example 2 (Chinese)}}
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 2 (Chinese)}}</div>
{{#Example 2 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 2 (French)}}
</div>
{{/Example 2 (French)}}
</div>
{{/Example 2 (Chinese)}} {{#Example 3 (Chinese)}}
<div class="solarized-text-base01 text-sm">
<div class="font-medium">{{Example 3 (Chinese)}}</div>
{{#Example 3 (French)}}
<div class="text-xs mt-1 solarized-text-base00">
{{Example 3 (French)}}
</div>
{{/Example 3 (French)}}
</div>
{{/Example 3 (Chinese)}}
</div>
{{/Example 1 (Chinese)}}
</div>
</div>
</div>
</div>
<script>
(function () {
const tradSpan = document.getElementById("traditional-display");
if (!tradSpan) return;
const simplified = "{{Hanzi}}".trim();
const traditional = tradSpan.textContent.trim();
if (simplified !== traditional) {
tradSpan.style.display = "inline";
}
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
const hiddenBtn =
this.closest(".ml-auto").querySelector(".replay-button");
if (hiddenBtn) hiddenBtn.click();
});
});
})();
(function () {
document.querySelectorAll(".sound-button").forEach((btn) => {
btn.addEventListener("click", function (e) {
e.preventDefault();
// Find the closest parent with class "ml-auto"
const container = this.closest(".ml-auto");
if (!container) return;
// Then find the .replay-button > a inside it
const replayLink = container.querySelector(".replay-button a");
if (replayLink) {
replayLink.click(); // Simulate a click on the hidden replay link
}
});
});
})();
</script>
Styling:
@import url("_tailwind.css");
/* Base card styling */
.card {
font-size: 24px;
text-align: center;
background-color: #FFF;
-webkit-text-size-adjust: 100%; /* try 'none' if 100% still inflates */
text-size-adjust: 100%;
}
/* Frequency badge styling */
.frequency-badge {
display: inline-block;
font-size: 0.75rem;
line-height: 1rem;
}
/* HSK level badge styling */
.hsk-badge {
margin-top: 0.25rem;
font-size: 0.75rem;
}
/* Traditional character variant styling */
.traditional-variant {
opacity: 0.8;
font-size: 0.875rem;
}
/* Alternative writing style */
.also-written {
font-style: italic;
opacity: 0.7;
}
/* Notes section divider */
.notes-section {
border-top: 1px solid #586e75;
margin: 1rem 0;
padding-top: 1rem;
}
/* Examples section styling */
.example-section {
border-top: 1px solid #586e75;
margin-top: 1.5rem;
padding-top: 1rem;
}
/* Individual example item */
.example-item {
margin-bottom: 0.75rem;
}
/* Chinese example text */
.example-chinese {
font-weight: 500;
margin-bottom: 0.25rem;
}
/* French translation text */
.example-french {
font-size: 0.875rem;
opacity: 0.8;
}
/* Solarized color palette classes */
.solarized-bg-base03 {
background-color: #012B36;
}
.solarized-bg-base02 {
background-color: #073642;
}
.solarized-bg-base01 {
background-color: #586e75;
}
.solarized-bg-base00 {
background-color: #657b83;
}
.solarized-bg-base0 {
background-color: #839496;
}
.solarized-bg-base1 {
background-color: #93a1a1;
}
.solarized-bg-base2 {
background-color: #eee8d5;
}
.solarized-bg-base3 {
background-color: #fdf6e3;
}
.solarized-text-base03 {
color: #012B36;
}
.solarized-text-base02 {
color: #073642;
}
.solarized-text-base01 {
color: #586e75;
}
.solarized-text-base00 {
color: #657b83;
}
.solarized-text-base0 {
color: #839496;
}
.solarized-text-base1 {
color: #93a1a1;
}
.solarized-text-base2 {
color: #eee8d5;
}
.solarized-text-base3 {
color: #fdf6e3;
}
/* Solarized accent colors */
.solarized-bg-yellow {
background-color: #B58901;
}
.solarized-bg-orange {
background-color: #CB4B15;
}
.solarized-bg-red {
background-color: #DC322F;
}
.solarized-bg-magenta {
background-color: #D23782;
}
.solarized-bg-violet {
background-color: #6C71C4;
}
.solarized-bg-blue {
background-color: #258BD2;
}
.solarized-bg-cyan {
background-color: #2AA198;
}
.solarized-bg-green {
background-color: #859901;
}
.solarized-text-yellow {
color: #B58901;
}
.solarized-text-orange {
color: #CB4B15;
}
.solarized-text-red {
color: #DC322F;
}
.solarized-text-magenta {
color: #D23782;
}
.solarized-text-violet {
color: #6C71C4;
}
.solarized-text-blue {
color: #258BD2;
}
.solarized-text-cyan {
color: #2AA198;
}
.solarized-text-green {
color: #859901;
}