· Working ·
Choosing a UI font for Vietnamese: a 5-minute diacritics test
If your product ships in Vietnamese, check three things before you commit to a typeface: the vietnamese subset on Google Fonts, stacked tone marks at 12–14px, and line height for accented capitals. Includes a table of ten popular fonts with only verified facts.
A typeface is ready for a Vietnamese interface when it passes three checks: it ships a vietnamese subset on Google Fonts (or full glyph coverage if you self-host), tone marks stacked on a circumflex stay distinct at 12–14px, and accented capitals clear the line above at your heading line height. All three take about five minutes.
I'm Hai Le, a product designer who builds design systems and codes this site myself. If you design for Vietnamese users without reading Vietnamese, this post is the checklist I would hand you. An earlier version claimed Inter loses to Be Vietnam Pro on diacritics. I had no measurement behind that, so I removed it.
Why isn't "supports Vietnamese" enough?
"Supports Vietnamese" usually means the font contains the Unicode characters. How those marks are drawn and positioned is a separate question. Vietnamese is harder than most Latin-script languages because one letter can carry two marks at once: a circumflex or breve plus a tone mark, as in ề, ẫ or ặ.
The Google Fonts production guide (GF Guide) has a page on diacritics that calls these stacked diacritics. It makes three points worth knowing as a designer. The gap between the two marks is usually tight and should be consistent across the font. Stacked marks can be drawn smaller than standalone ones to keep balance, especially on capitals. And marks should not sit too high or look too heavy. When a font ignores this, you see the hook of the hỏi tone touching the circumflex at small sizes, or accented capitals towering over the rest of the line.
Be Vietnam Pro is an example of a font designed with this in mind. Its GitHub README says the authors "refined Vietnamese letterforms with diacritics adaptive forms for specific use cases." Google Fonts credits it to Lâm Bảo, Tony Le and ViệtAnh Nguyễn.
Which fonts support Vietnamese well for UI?
This table lists only what I could check in Google Fonts metadata on 2026-10-04: whether a vietnamese subset exists, who designed the font, and which variable axes it has. I don't rank diacritic quality here. That takes your own eyes and the test string in the next section.
| Font | Vietnamese subset | Designer (per Google Fonts) | Variable axes |
|---|---|---|---|
| Google Sans Flex | Yes | wght 1–1000, wdth, opsz, slnt, GRAD, ROND | |
| Be Vietnam Pro | Yes | Lâm Bảo, Tony Le, ViệtAnh Nguyễn | None (static, 18 styles) |
| Inter | Yes | Rasmus Andersson | wght 100–900, opsz 14–32 |
| Roboto | Yes | Christian Robertson et al. | wght 100–900, wdth 75–100 |
| Noto Sans | Yes | wght 100–900, wdth 62.5–100 | |
| Nunito Sans | Yes | Vernon Adams et al. | wght 200–1000, wdth, opsz, YTLC |
| Montserrat | Yes | Julieta Ulanovsky et al. | wght 100–900 |
| Lexend | Yes | Bonnie Shaver-Troup et al. | wght 100–900 |
| Poppins | No | Indian Type Foundry et al. | None (static) |
| DM Sans | No | Colophon Foundry | wght 100–1000, opsz 9–40 |
The last two rows matter because both show up in a lot of Figma templates. The Google Fonts Poppins has a latin-ext subset, but that subset's range skips U+1EA0 to U+1EF1, which holds most Vietnamese letters with tone marks: ạ, ề, ộ, ữ. Letters like ă, đ, ơ and ư live in U+0100 to U+02BA, so they do render. The word "Đề" ends up with Đ in Poppins and ề in the operating system's fallback. Figma may hide this, since it uses the font file installed on your machine. The browser only has what Google Fonts sends.
How do you test a font's Vietnamese diacritics in 5 minutes?
You need a blank HTML page or a Figma frame, plus a browser.
-
Check the subset. On the font's Google Fonts page, look for Vietnamese in the language list. To be sure, request the CSS API and look for the
/* vietnamese */comment. No block means accented letters will come from another font.curl -s -A "Mozilla/5.0" "https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro" | grep "vietnamese" -
Type a stacked-mark test string. Cover circumflex, breve and horn with all five tones:
ấ ầ ẩ ẫ ậ · ắ ằ ẳ ẵ ặ · ế ề ể ễ ệ · ố ồ ổ ỗ ộ · ớ ờ ở ỡ ợ · ứ ừ ử ữ ự. View it at 12px and 14px in the weights you actually use. You are checking two things: whether hỏi (the hook) and ngã (the tilde) are distinguishable, and whether the tone mark touches the circumflex. -
Try capitals at heading size. Type
ỄỘ ẲẪ ỞỮat your largest heading size. Stacked marks on capitals are where problems show first, because capitals are already tall. -
Check line height. Stack two lines: descenders such as
gyon top, accented capitals such asỄỘbelow. Apply the real line height of your heading style and look for a collision. -
Check for fallback. In Chrome DevTools, select the text, open the Computed tab and scroll to Rendered Fonts. If a run of Vietnamese text lists two fonts, some characters are falling back to a system font.
Each step takes about a minute. Step 5 catches the Poppins case above, which is easy to miss when the fallback looks similar.
What line height leaves room for Vietnamese marks?
I can't give you a universal number, because each font places its marks at a different height. I can point you to where to look.
Body text rarely breaks. On this site, body copy is 16px at a 1.4 line height (22.4px), which leaves comfortable room for stacked marks. The risk is in large headings, where designers tighten line height to make the block feel solid. This site's 48px heading style uses a 1.04 line height. A two-line heading with stacked capitals at that setting is exactly the case to run through step 4 before signing it off.
Tracking matters too. The system here uses negative tracking that grows with size: -0.04em from 32px up, -0.025em for 18–28px, -0.01em at 14px, and 0 for 16px body text. Negative tracking pulls letters closer horizontally, which also pulls neighbouring marks closer. Test with your real tracking on.
Why did this site switch from Be Vietnam Pro to Google Sans Flex?
In September 2026 I replaced Be Vietnam Pro with Google Sans Flex as the site's main font. Google Sans Flex was added to Google Fonts on 12 November 2025 and includes a vietnamese subset. The reasons recorded in the site's DESIGN.md are two: its Vietnamese marks are drawn for the family itself, and its tight, low-contrast grotesque shapes suit the current layout.
Google Sans Flex is a variable font with six axes. The site loads only wght and uses only 400 and 500. The other axes are left out on purpose to keep the file small. In Next.js, the font setup looks like this:
const googleSansFlex = Google_Sans_Flex({
subsets: ["latin", "latin-ext", "vietnamese"],
// ...
});I treat vietnamese in that array as non-negotiable. Without it, Vietnamese text still appears, but in another font, and the bug often only shows on a user's machine.
A font change has to land in three places at once: the CSS, DESIGN.md, and the conventions file the AI reads. If I only change the CSS, the next time I ask an AI to build a screen it reads the stale docs and brings the old font back. I explain that setup in What is DESIGN.md. To turn font and size choices into variables shared between Figma and code, start with What is a design token.
What should a design system say about fonts?
The type section of a design system should answer what a new teammate, or an AI, will ask:
- Which font, which subsets are required, which weights are loaded.
- The size scale, with line height and tracking per step.
- Named exceptions. Here, the Button label is the only place that uses weight 600.
- The Vietnamese test string used to review any font change.
That last item is the one teams forget. On Joyme, the type system used a single family, Nunito Sans, in three weights and six sizes from 12 to 32px. You can see the specimen in the Joyme case study. Nunito Sans has a vietnamese subset on Google Fonts, but that only covers the characters. Mark quality still needs the five-step check.
Once the type works, the next thing to tune is the whitespace around it, which I cover in the 4px grid and spacing rhythm. If you build UI from Figma with AI, Claude Code for designers shows how I keep rules like a required subset from being dropped.
If your team needs someone to build a design system for a Vietnamese-language product, you can read more about me.
Sources
- Google Fonts metadata: subsets, designers, variable axes and date added for each family. Accessed 2026-10-04.
- Google Fonts CSS API:
unicode-rangeof the latin-ext and vietnamese subsets. Accessed 2026-10-04. - GF Guide: Diacritics: stacked diacritics in Vietnamese, mark spacing and size. Accessed 2026-10-04.
- Be Vietnam Pro on GitHub: design intent, OFL 1.1 license. Accessed 2026-10-04.
DESIGN.md,app/globals.cssandapp/[locale]/layout.tsxin this site's repo.
Frequently asked questions
- Is the Google Fonts vietnamese subset enough to call a font UI-ready?
- The subset only confirms the characters exist. It says nothing about whether the marks are drawn well or crowd each other at small sizes. You still need to type a test string with ề, ữ, ộ and ẳ and look at it at 12px, 14px and your largest heading size.
- Why does Poppins render some Vietnamese letters in a different font?
- The Google Fonts build of Poppins has no vietnamese subset. Its latin-ext range skips U+1EA0 to U+1EF1, the block that holds letters like ề, ộ and ữ, so the browser pulls those from a fallback font. Letters like ă, đ, ơ and ư sit in latin-ext and still render in Poppins.
- What line height does Vietnamese need?
- There is no single number, because mark height varies between typefaces. The quick check: stack two lines, descenders like gy on top and accented capitals like ỄỘ below, set your real line height, and see whether they collide.
- What font does this site use?
- Google Sans Flex, since September 2026, replacing Be Vietnam Pro. The site loads the vietnamese subset as a hard requirement and only the weight axis, at 400 and 500.
You might also like
What is Claude Code? Install it and run your first session, no coding needed
A designer's walkthrough for people who have never opened a terminal: what Claude Code is, what you need, installing on macOS and Windows, a safe first session, and fixes for the usual errors. Every command comes from Anthropic's docs.
Working· 2026-10-04
Claude Code for designers: turning a Figma design into a working page
How I use Claude Code as a designer to get from Figma frames to a real, maintained website: what to set up, how to write rules the agent follows, a six-step workflow, and the mistakes I made building this site.
Working· 2026-10-04
What is Claude? A guide for people who have never used AI
Claude is Anthropic's AI assistant. This guide covers what it can do, how the free and paid plans differ, how to run your first conversation, and where Claude tends to get things wrong. Every feature and price was checked against Anthropic's own pages.
Working· 2026-10-04