Browser: Firefox v134.0.2
In the following example, the bottom part of the y
letters in the word yesterday
don't seem to be contained within the <rb>
tag, as they should; these bottom parts intrude on the space of the element that immediately follows <rb>
tag.
ruby {
ruby-position: under;
}
ruby ruby {
ruby-position: over;
}
ruby {
background-color: rgb(100, 100, 100);
}
ruby rt {
background-color: rgb(200, 227.5, 255);
}
ruby ruby {
background-color: rgb(255, 200, 200);
}
ruby ruby rt {
background-color: rgb(200, 255, 200);
}
<ruby style="font-size:180px;display:inline-flex;flex-direction:column;text-align:center;/*justify-content:space-evenly;*/align-items:center;">
<span>
<ruby>昨<rp>(</rp><rt>キ</rt><rp>)</rp></ruby>
<ruby>日<rp>(</rp><rt>ノウ</rt><rp>)</rp></ruby>
</span>
<rt>yesterday</rt>
</ruby>
<br><div style="width:50%;margin-left:15px;font-size:40px;background-color:rgb(0,255,0);">the bottoms of the "y" letters intrude into this element</div>
Can we somehow solve this problem without hard-coding an additional space of a specific size (which we can determine by trial and error) below the y
letters (e.g. <rt style="padding-bottom:5px;">yesterday</rt>
), so that it's taken care of automatically (as it should've been)?
I don't think this has anything to do with Flexbox, but rather with how the height of text is calculated. The problem seems to be that the font's descender is not being taken into account when calculating the element's content-size. This can be fixed by setting line-height: normal
on the rt
element (see this blog post by Vincent De Oliveria: Deep dive CSS: font metrics, line-height and vertical-align).
Doing so gives us the following (in Firefox):
ruby {
ruby-position: under;
}
ruby ruby {
ruby-position: over;
}
ruby {
background-color: rgb(100, 100, 100);
}
ruby rt {
background-color: rgb(200, 227.5, 255);
line-height: normal;
}
ruby ruby {
background-color: rgb(255, 200, 200);
}
ruby ruby rt {
background-color: rgb(200, 255, 200);
}
<ruby style="font-size:180px;display:inline-flex;flex-direction:column;text-align:center;/*justify-content:space-evenly;*/align-items:center;">
<span>
<ruby>昨<rp>(</rp><rt>キ</rt><rp>)</rp></ruby>
<ruby>日<rp>(</rp><rt>ノウ</rt><rp>)</rp></ruby>
</span>
<rt>yesterday</rt>
</ruby>
<br><div style="width:50%;margin-left:15px;font-size:40px;background-color:rgb(0,255,0);">the bottoms of the "y" letters intrude into this element</div>
The reason this is a problem in Firefox and not in Chrome is that Firefox's user agent stylesheet has a line that sets line-height: 1
specifically for rt
and rtc
elements.
rt
elements sticking out the topAs you point out in your comment, the green rt
elements are still poking out from the top of the ruby
element. To answer your comment... mostly.
This can be fixed in Firefox by setting line-height: 1
for the ruby
elements:
p {
font-size: 80px;
font-family: serif;
}
ruby {
line-height: 1;
display: inline-flex;
flex-direction: column;
align-items: center;
text-align: center;
ruby-position: under;
}
ruby ruby {
ruby-position: over;
display: ruby; /* undo inline-flex */
}
ruby rt {
line-height: normal;
}
/* colours: */
ruby {
background-color: rgb(100, 100, 100);
}
ruby rt {
background-color: rgb(200, 227.5, 255);
}
ruby ruby {
background-color: rgb(255, 200, 200);
}
ruby ruby rt {
background-color: rgb(200, 255, 200);
}
p {
background-color: rgb(225, 225, 225);
}
<p lang="ja">
大阪さんに<ruby>
<span>
<ruby>昨<rp>(</rp><rt>キ</rt><rp>)</rp></ruby>
<ruby>日<rp>(</rp><rt>ノウ</rt><rp>)</rp></ruby>
</span>
<rt>yesterday</rt>
</ruby>会いました。
</p>
Unfortunately, this doesn't quite work in Chrome. Not only do the green rt
elements still poke out the top, but they now also overlap with the tops of the ruby
elements:
That said, Chrome seems to do a better job than Firefox in the first place when it comes to positioning ruby annotations: they are placed much closer to the base text, and it seems to be a bit better at considering the font family's inherent sizes. So it's entirely possible that this solution is satisfactory.
I should also note that I have found that changing the language of the document/containing element from en
to ja
and vice versa can introduce even more layout quirks: YMMV on that front.
Personally, I think it would be far less of a headache if you simply forwent the use of Flexbox entirely. You did not explain why you chose to use a Flexbox in the original post; in your comment to SyndRain's answer, you said that:
ruby
element.You mentioned that achieving the same layout without it would require introducing several more layers of <span>
/<div>
elements. In my testing, however, the default behaviour of ruby
text seems to do what you want without any additional help (if you have more specific requirements, please feel free to expand on them in the comments, and I will update my answer again).
Here's an example that uses ruby
and rt
exactly as shown in the HTML Standard:
p {
font-size: 60px;
font-family: serif;
}
ruby {
ruby-position: under;
}
ruby ruby {
ruby-position: over;
}
<p lang="ja">
大阪さんに<ruby><ruby>昨<rp>(</rp><rt>キ</rt><rp>)</rp></ruby><ruby>日<rp>(</rp><rt>ノウ</rt><rp>)</rp></ruby><rt lang="en">yesterday</ruby>会いました。あいうえお、かきくけこ。
</p>
The only thing this doesn't do out of the box is add a space between each kanji. I'm not entirely sure why you would want to do this, as it would be inconsistent with any surrounding Japanese writing (again, please expand in the comments if I'm misunderstanding your goal here); however, you can accomplish this fairly easily with a creative CSS selector:
p {
font-size: 60px;
font-family: serif;
}
ruby {
ruby-position: under;
}
ruby ruby {
ruby-position: over;
}
/* Insert space between annotated kanji: */
ruby ruby:not(:last-of-type)::after {
content: "\0a"; /* nbsp */
}
<p lang="ja">
大阪さんに<ruby><ruby>昨<rp>(</rp><rt>キ</rt><rp>)</rp></ruby><ruby>日<rp>(</rp><rt>ノウ</rt><rp>)</rp></ruby><rt lang="en">yesterday</ruby>会いました。あいうえお、かきくけこ。
</p>
Using a pseudo-element has the added benefit that the text no longer includes any actual whitespace when copy-pasting: it is purely visual.
Hopefully I didn't misunderstand your intentions with the flexbox. I hope this answers your question. :)