4
\$\begingroup\$

I'm doing a hobby project for fun recently, it's a GitHub webpage using Jekyll.

One of the main component of my site is displaying Chinese characters with their Sino-Vietnamese pronunciation. I use <ruby> elements to render these texts, for those who don't know, you can read its MDN docs

The problem with that is word spacing is broken when a <rt> element is longer than its associated <rb> element. So I created a jQuery function to dynamically adjust spacing.

A minimal example here:

const stdSpace = "1em"; // for ruby annotation spacing
$(function () {
 $("rb").each(rubyAdjust);
});
function rubyAdjust(i, el) { // for each ruby base
 const rbW = $(el).width(), // take its width
 rtW = $(el).next("rt").width(), // its associated ruby text width
 diff = (rtW - rbW).toFixed(0), // excess amount
 addSpace = diff > 0
 ? `calc(${stdSpace} + ${diff.toString()}px)`
 : stdSpace;
 $(el).css("margin-right", addSpace);
}
rb {
 display: inline-block /* fluid word spacing with margin using JS */
}
rt {
 text-align: left /* to work together with rb margin */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ruby>
 <rb>是</rb><rt>Thị</rt>
 <rb>故</rb><rt>cố</rt>
 <rb>空</rb><rt>không</rt>
 <rb>中</rb><rt>trung</rt>
</ruby>

My function rubyAdjust works as expected, but becomes a UI blocking point when I have a very long text. For a full fledged example, you can visit a page of my project which shows the Diamond Sutra.

So what I want is to improve the rendering speed:

  1. Is there a better way to adjust word spacing of <ruby>? The official docs of <ruby> doesn't have much, maybe because the feature is still uncomplete and fews people are using it?
  2. I've also searched for a multi thread execution of jQuery, but it seems like DOM manipulation isn't possible. Do you guys have any idea?

Many thanks,

asked May 14, 2021 at 10:35
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Some improvements:

  • completely remove the JS function and replace with CSS (thanks to this SO answer); this greatly reduces loading time
  • wrap one ruby for each pair rb & rt with ruby, instead of having multiple pairs of them inside ruby
  • use flex to render rather than the default display: block

The improved code:

ruby {
 display: inline-flex;
 flex-direction: column-reverse;
 margin-right: 0.5em; /* additional spacing */
}
rb, rt {
 display: inline;
 line-height: 1; /* spacing between rb & rt can be changed */
 text-align: left; /* my personal preference */
}
<ruby><rb>是</rb><rt>Thị</rt></ruby>
<ruby><rb>故</rb><rt>cố</rt></ruby>
<ruby><rb>空</rb><rt>không</rt></ruby>
<ruby><rb>中</rb><rt>trung</rt></ruby>

Toby Speight
87.9k14 gold badges104 silver badges325 bronze badges
answered Jun 25, 2021 at 15:57
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.