NeuroAgent

CSS Ruby Baseline Alignment Techniques

Learn how to position multi-line text baselines consistently with or without ruby annotations in CSS. Maintain alignment in fixed-size containers using ruby-align property and space reservation techniques.

Question

How can I position the baseline of multi-line text with or without ruby annotations at the same position using CSS? I need to place multi-line text in a fixed-size container where the baseline of the first line should remain consistent regardless of whether ruby annotations are present on that first line. Ruby annotations on subsequent lines are acceptable as they fit within the line-height. I’m looking for a solution that maintains the use of elements while ensuring consistent baseline positioning, preferably working in the latest stable version of Chrome. If direct positioning isn’t possible, I’m open to alternative approaches like adding invisible ruby annotations to the first line to reserve space without affecting appearance or accessibility.

NeuroAgent

To achieve consistent baseline positioning for multi-line text with or without ruby annotations in CSS, you need to combine proper line-height settings with the ruby-align property and potentially use absolute positioning techniques. The key is to ensure sufficient line-height to accommodate ruby annotations while maintaining consistent baseline alignment across different content variations, using the ruby-align: start property to control annotation positioning and implementing fallback strategies for browser compatibility.

Contents

Understanding the Baseline Positioning Challenge

Baseline positioning in CSS refers to aligning text along the invisible line on which most characters sit. When working with ruby annotations (small text that appears above or alongside base text, commonly used in Japanese for furigana), maintaining consistent baseline alignment becomes particularly challenging. According to the CSS Ruby Annotation Layout Module Level 1, documents with ruby typically ensure that the line-height is large enough to accommodate ruby between lines of text.

The core issue is that ruby annotations can affect the visual positioning of the base text’s baseline, especially when annotations are present on the first line of multi-line text. This can cause inconsistent alignment between content that has ruby annotations and content that doesn’t.


CSS Ruby-Align Property and Values

The ruby-align CSS property, available in Chrome 128 and later, controls the alignment of ruby base text and ruby annotation text. As described in the Chrome Developer documentation, this property accepts several keyword values:

  • start - aligns ruby to the start of the base text
  • center - centers ruby over the base text
  • space-between - distributes ruby evenly between the start and end of the base text
  • space-around - distributes ruby with equal space around each ruby annotation

For consistent baseline positioning, ruby-align: start is often the most appropriate choice as it aligns the ruby annotation to the beginning of the base text, maintaining more predictable positioning behavior.

The MDN documentation explains that this property defines the distribution of different ruby elements over the base, which is crucial for maintaining alignment consistency.


Techniques for Consistent Baseline Positioning

1. Proper Line-Height Management

The foundation of consistent baseline positioning is appropriate line-height settings. As mentioned in the W3C specification, you need to ensure that the line-height is large enough to accommodate ruby between lines of text. This means:

css
.text-container {
  line-height: 1.8; /* Adjust based on your font and annotation size */
}

A larger line-height creates space for ruby annotations without affecting the baseline positioning of the base text.

2. Ruby Container Styling

For more control over ruby positioning, you can style the ruby container directly. As shown in some StackOverflow solutions, you can use:

css
ruby {
  font-size: inherit;
  display: inline-block;
  line-height: 1em;
  position: relative;
}

span.rb {
  display: inline-block;
  padding-top: 0.6em; /* Adjust based on your needs */
}

span.rt {
  font-size: 0.55em;
  position: absolute;
  display: block;
  line-height: 1.3em;
  top: 0;
}

This approach gives you precise control over the vertical positioning of ruby annotations.

3. Baseline Alignment with Flexbox

For multi-line text containers, you can use flexbox with baseline alignment. As discussed in this StackOverflow answer, you can create a flex container where the first line maintains consistent baseline:

css
.text-container {
  display: flex;
  flex-direction: column;
}

.text-container > *:first-child {
  align-self: baseline;
}

Alternative Approaches for Fixed-Size Containers

1. Invisible Ruby Annotations for Space Reservation

If direct positioning proves challenging, you can add invisible ruby annotations to the first line to reserve space without affecting appearance. This approach maintains the semantic structure of <ruby> elements while ensuring consistent container sizing:

html
<div class="text-container">
  <p>
    <ruby>
      <span class="rb">First line</span>
      <span class="rt invisible">a</span>
    </ruby>
    with invisible annotation to reserve space...
  </p>
</div>
css
.rt.invisible {
  visibility: hidden;
  font-size: 0;
  line-height: 0;
}

2. Pseudo-Element Space Reservation

Another approach is to use CSS pseudo-elements to reserve space:

css
.text-container::before {
  content: '';
  display: inline-block;
  height: 1em; /* Height equivalent to ruby annotation */
  width: 0;
  vertical-align: baseline;
}

3. Fixed Container with Baseline Compensation

For fixed-size containers, you can calculate and compensate for the space that ruby annotations would occupy:

css
.fixed-container {
  height: 200px; /* Fixed height */
  display: flex;
  flex-direction: column;
}

.has-ruby .first-line {
  margin-bottom: calc(1em * 0.6); /* Compensate for ruby space */
}

Implementation Example

Here’s a complete implementation that demonstrates consistent baseline positioning:

html
<div class="text-container">
  <p class="text-line">
    <ruby>
      <span class="rb">Base text</span>
      <span class="rt">Annotation</span>
    </ruby>
    continues with more text that might wrap to multiple lines...
  </p>
</div>
css
.text-container {
  max-width: 300px;
  border: 1px solid #ccc;
  padding: 10px;
}

.text-line {
  line-height: 1.8;
  margin-bottom: 10px;
}

/* Ruby styling */
ruby {
  ruby-align: start;
  display: inline-block;
  position: relative;
}

.rb {
  display: inline-block;
}

.rt {
  font-size: 0.6em;
  line-height: 1.2;
  position: absolute;
  left: 0;
  top: -0.8em;
}

/* Alternative approach for space reservation */
.text-container.has-ruby .text-line::before {
  content: '';
  display: inline-block;
  height: 0.8em; /* Height of ruby annotation */
  width: 0;
  vertical-align: baseline;
}

Browser Compatibility and Fallbacks

While ruby-align is supported in Chrome 128+ and other modern browsers, you may need fallbacks for older browsers:

css
/* Modern browsers */
ruby {
  ruby-align: start;
}

/* Fallback for older browsers */
@supports not (ruby-align: start) {
  ruby {
    position: relative;
  }
  
  .rt {
    position: absolute;
    top: -0.8em;
    left: 0;
    font-size: 0.6em;
  }
}

As noted in the StackOverflow discussion, type rendering varies between OSes and browsers, making pixel-perfect control challenging. Testing across different browsers is essential.

Conclusion

  1. Use proper line-height: Ensure sufficient line-height (typically 1.6-2.0em) to accommodate ruby annotations without affecting baseline positioning.

  2. Leverage ruby-align property: Use ruby-align: start for consistent annotation positioning in modern browsers (Chrome 128+).

  3. Consider space reservation techniques: Add invisible ruby annotations or use pseudo-elements to reserve space for the first line when needed.

  4. Implement fallback strategies: Provide CSS fallbacks for older browsers that don’t support the ruby-align property.

  5. Test across browsers: Due to variations in text rendering between browsers and operating systems, thorough testing is crucial for achieving consistent results.

The most robust solution combines proper line-height management with the ruby-align property and fallback positioning techniques, ensuring that your multi-line text maintains consistent baseline alignment whether ruby annotations are present or not.

Sources

  1. CSS Ruby Annotation Layout Module Level 1 - W3C
  2. Line-breakable and CSS ruby-align property - Chrome for Developers
  3. ruby-align - CSS | MDN
  4. Adjust the vertical positioning of ruby text - Stack Overflow
  5. How to position text on a baseline? - Stack Overflow
  6. Align items baseline for multi-line text - Stack Overflow
  7. CSS Ruby Align - CSS3
  8. ruby-align is Baseline Newly available - web.dev
  9. Ruby Styling - W3C International
  10. The CSS ruby-align Property - WebReference