Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Layout] Baseline vertical alignment #96

Open
Caellian opened this issue Dec 23, 2024 · 3 comments
Open

[Layout] Baseline vertical alignment #96

Caellian opened this issue Dec 23, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@Caellian
Copy link

There's no way of aligning text elements of different font size/family in same row based on font baseline property.

Baseline should be added to CLAY_TEXT_CONFIG and responsibility for specifying the correct baseline delegated to consumer, defaulting to 0px from the bottom. This would make the default behave as bottom aligned text.

I'd expect non-text components to have baseline 0 as well, so baseline aligned boxes would behave the same as bottom aligned ones.

@nicbarker
Copy link
Owner

There's no way of aligning text elements of different font size/family in same row based on font baseline property.

You are definitely correct here, but there is also currently no way of specifying multiple font sizes within one container (i.e. rich text)

Just to clarify, does declaring two seperate text elements and using CLAY_ALIGN_Y_BOTTOM on the outer container produce the correct behaviour? Or is that incorrect as well?

@nicbarker nicbarker self-assigned this Dec 24, 2024
@nicbarker nicbarker added the enhancement New feature or request label Dec 24, 2024
@nicbarker nicbarker changed the title Baseline vertical alignment [Layout] Baseline vertical alignment Dec 24, 2024
@Caellian
Copy link
Author

Caellian commented Dec 24, 2024

You are definitely correct here, but there is also currently no way of specifying multiple font sizes within one container.

Right, I mean multiple text elements with CLAY_ALIGN_Y_BASELINE in a single row.

Here's an image because it will be easier to explain this visually:

example

green - parent; blue - bounding box; red - baseline

  • The top row is correctly laid out - note that red line isn't broken up and text looks properly aligned.
  • The middle row includes spacing from baseline to bottom (i.e. descend) in character bounds even if there are no descending characters.
    • I'm assuming this is the case currently. Assuming the consumer correctly computes font bounds when drawing fonts.
  • The bottom row uses bounds of rasterized text instead of bounds provided by font files.
    • The worst case, this breaks text alignment even with same font size & family when a text element with no descending characters is next to another with descending characters.

To reiterate, this isn't a richtext component, it's a layout row, first is suggested CLAY_ALIGN_Y_BASELINE, and second two are CLAY_ALIGN_Y_BOTTOM. I included image box in examples to showcase expected (in browsers) behavior for non-text children.
As you can see, the middle (more correct) one still doesn't align text with respect to baseline (red line) properly. Which places text components lower than they should be. This can look somewhat passable when same font is used (most cases), but with different fonts and sizes it will look bad because users expect text to be bottom aligned on baseline, not font bottom.

To implement this, you'd need to:

  • ask for baseline position of text from bottom.
  • in a CLAY_ALIGN_Y_BASELINE aligned row:
    • container baseline is the largest child baseline,
    • subtract container baseline from other text element baselines to compute additional bottom offset,
    • offset non-text children by container baseline from the bottom.

If user doesn't specify baseline for fonts, they would still get CLAY_ALIGN_Y_BOTTOM second case even if CLAY_ALIGN_Y_BASELINE is used.

This suggestion is something that richtext usually handles as well, but it's also part of component layouting that's text aware. align-items in CSS can have this value, so you can look at play with that to test for edge cases or if I left something out.

It might also be a good idea to allow non-text children to also specify baseline offset. This will make your code simpler and could be useful in some cases - rasterized SVG image containing a LaTeX expression is an image (non-text) but still technically has a baseline. For the default baseline offset value of 0, it should still will work as shown on the first row.

@nicbarker
Copy link
Owner

Thank you so much for the in depth explanation, I totally understand what you're talking about now. A picture is worth a thousand words! 😁
Will look into this in the next week or two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants