Add ability to set text in small caps?
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
All uppercase letters is a common styling technique for text in latin, cyrillic, and greek scripts. We use `text-transform: uppercase` to set this styling. This is not ideal for multilingual maps, because text using scripts that distinguish upper and lowercase letters (latin, cyrillic, greek) appear visually larger than text in other scripts.
- Mixed-script labels are not visually balanced between the two scripts:

*E.g. these "Suburb" labels in Hong Kong, where the English more prominent*
- Labels in different regions are visually different sizes, which is problematic for maintaining a uniform label hierarchy across different regions:


*E.g. these "Suburb" labels in London vs Tel Aviv*
I think it would be interesting to explore implementing some form of display for "small capitals" (glyphs that mimic uppercase letters, but sized appropriately to be incorporated within upper-and-lowercase text). Although the main use case for small caps is mostly irrelevant here (especially since we can't currently style text differently within a single label), perhaps it's worth implementing for the use case outlined above?
Here's an inital braindump. Would be curious to hear others' thoughts on whether this seems worthwhile, and if so, how we might want to proceed.
### True small caps
True small caps are glyphs specifically designed for this purpose, with appropriate stroke weights and proportions.
Typographically, displaying these glyphs would be ideal, but:
- These don't exist for many font families, especially san serifs (which are more common on web maps).
- I think we might need to use an [OpenType text shaping engine (e.g. Harfbuzz)](https://github.com/mapbox/mapbox-gl-native/issues/7528) to be able to make use of these glyphs (but perhaps we don't? @chrisloer? )
### "Fake" small caps
"Fake" small caps are just uppercase letters with a reduced text size (usually such that the new cap height is slightly larger than the old x-height).
I think most renderers that support "small caps" fall back to this approach if the specified font does not contain true small cap glyphs.
Usually fake small caps are a big typographic no-no, largely because just shrinking the uppercase letters means that their strokes become too thin, relative to the other characters displayed in that font at that size. However:
- Since for the most part our usage would only ever pair small cap letters in the same label with characters in scripts other than latin, cyrillic, or greek, perhaps the discrepency in text weight won't be so noticeable (especially in the cases where we're not even using the same font for different scripts).
- There might be ways to programmatically increase the apparent text weight of fake small caps (although it seems like getting consistently good results would be difficult).
This would mean that for some labels, we'd be technically rendering part of the text in one text size and the other part in another text size (for some multi-script labels). Is that possible?
### Spec
The CSS equivalent is `font-variant-caps: all-small-caps` or the shorthand [`font-variant: all-small-caps`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant), which use the OpenType [feature tags](https://www.microsoft.com/typography/otspec/features_pt.htm) for supporting small caps: `smcp` (small capitals) `c2sc` (capital to small caps). Perhaps we could support a similar property?
### Misc
Not directly related, but here's another ticket regarding better language support for uppercase styling: [text-tranform is not locale-aware](https://github.com/mapbox/mapbox-gl-js/issues/3999)
/cc @ChrisLoer @ansis @kkaefer @jfirebaugh @1ec5
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue does not name files, tests, or an entry point. Start by reviewing the existing text-transform rendering path and the CSS/OpenType small-caps requirements described here; the scope and completion criteria would need to be decided before implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css
- Domain
- design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100