Why is audio replay button not vertically centered relative to adjacent text? And how to do it?

I don’t understand why the audio replay button isn’t centered vertically relative to the text on iOS, while it’s just fine on desktop Anki?

A minimal card template example for demonstration:

  1. The template HTML:
{{Front}} English
  1. The default template CSS:
.card {
    font-family: arial;
    font-size: 20px;
    text-align: center;
    color: black;
    background-color: white;
}

With the Front field value being [sound:...] file, it’s rendered on desktop correctly:

CleanShot 2024-04-29 at 15.08.02

But in AnkiMobile, it’s quite off:

I don’t understand why they are different. On desktop, I can inspect from source, seeing .replay-button class has vertical-align: middle. On iOS, the same should be true, right? Is the replay button styled differently in AnkiMobile than in Anki desktop? Or is this a problem of WebKit engine used by AnkiMobile?

And last, how to vertically center replay button with adjacent text, in a way that works both in desktop Anki and AnkiMobile? To be specific, I want the replay button to be placed in and at the beginning of the first line of a multi-line sentence, and being vertically centered in the line, like so (rendered on desktop):

CleanShot 2024-04-29 at 15.28.48

I’m aware of the flex box solution. But it’s not exactly what I want. With flex box, the button is vertically centered with the entire sentence block rather than just its first line, and an entire column of space is taken by that button, which is quite wasteful on a narrow iPhone screen, like so:

CleanShot 2024-04-29 at 15.44.47

My knowledge of CSS is not very deep, and I can’t tell you anything about why this is appearing differently between the two Anki versions, but here’s what occurs to me –

What’s the vertical alignment of the text? Since you’re not setting that to anything, what is it defaulting to? Are the underlying defaults different in the two web engines (Qt 5 or 6 on Desktop, and … whatever it is on iOS)?

I also don’t know CSS very well. But to answer your question, I made some experiments, with weird findings … (Maybe not weird at all, if only I understand the nuances of line height, x-height, whatever in CSS)

I tried to access the computed value of vertical-align of both replay button and the text next to it, and print it out in the card. To make it possible to get properties of text, I had to wrap it in a <span>. So the template has been adjusted to this:

{{Front}} <span id="word">English</span>

<script>
    const button = document.getElementsByClassName("replay-button")[0];
    const buttonCss = window.getComputedStyle(button);
    const word = document.getElementById("word");
    const wordCss = window.getComputedStyle(word);
    const p = document.createElement("p");
    p.innerText = `button vertical align: ${buttonCss.verticalAlign}\nword vertical align: ${wordCss.verticalAlign}`;
    word.after(p);
</script>

Now render that template on desktop, I got:

CleanShot 2024-04-30 at 11.57.53

On iOS, I got:

OK, two platforms have different default vertical alignment for .replay-button. Now you would think that was the problem, except… changing it to middle doesn’t change anything. In fact, I tried all combinations:

OK, setting top worked :man_facepalming::

So, I really don’t know what’s going on here…

Try the following:

    display: inline-flex;
    vertical-align: middle;

I’ll make it the default in the next update.

1 Like

Ah, the magic bit! Wish I could’ve known this easier. But thank you anyway.