Flags are emoji, and Windows draws them as two letters #88
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#88
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Observation
What is wrong
A flag emoji is not a character.
🇵🇹is two regional indicator code points, P and T,and a font is invited — never required — to draw the pair as a flag. Segoe UI Emoji has
never accepted the invitation and Microsoft has said it does not intend to. Windows
therefore draws exactly what the code points say:
PT.Both places this was used carry a comment admitting it:
core/languages.py— "Windows shows the two letters instead —FRrather than aFrench flag — which is a legible fallback and not a broken image, and is worth knowing
before it is reported as a bug."
core/phones.py— "The same Windows caveat as the language picker applies, and the sameanswer: two letters is a legible fallback."
It has now been reported as a bug, by the maintainer, on the platform he develops on. The
prediction was right and the judgement behind it was wrong: two letters where everyone else
sees a flag does not read as a fallback, it reads as something broken. Postulo runs on the
machine somebody already has, and a great many of those machines are Windows.
Where it shows
<select>The constraint that shapes the fix
An
<option>element can contain text and nothing else. No<img>, no<svg>, in anybrowser; it is not a styling problem to work around. So the two places need two answers.
The language picker is already rows rather than a dropdown — it was rebuilt that way in
#64, because an
<option>cannot carrylangon its content either. A row can hold animage, so it simply gets one.
The phone picker stays a native
<select>. It is the best-supported control there is:the system picker on a phone, a familiar target for every screen reader, and typing a letter
jumps to a country. Replacing it with a custom listbox to make room for an image would trade
something that works everywhere for something that has to be re-implemented and re-tested
against every assistive technology. Instead the flag moves beside the closed select, where
it is arguably more use than it was inside the list: visible without opening anything.
Each
<option>carries its flag's URL in adata-flagattribute — an attribute is notcontent, so this is allowed — and the change handler swaps the image. With scripts off the
server has already rendered the flag for the country the field loaded with, which is correct;
it just stops following the select until the form is saved. That is the project's usual
shape: the control works without JavaScript, and JavaScript makes it better.
The artwork
flag-icons 7.5.0, MIT, vendored the way Lucide and
zxcvbn already are:
npm run sync:flagscopies the listed files out ofnode_modulesintostatic/flags/, the result is committed, and Node is never needed to run Postulo. Thecontent security policy already says
img-src 'self', so nothing has to be loosened.Rectangular 4:3, the flag as officially drawn. The maintainer was offered
circle-flags — also MIT, ten times smaller —
and turned it down: "i don't like circle flags". Recorded here so that the size below is
understood as a decision rather than an oversight.
What it costs, measured rather than guessed
Static files are served by WhiteNoise from
CompressedManifestStaticFilesStorage, so they goout pre-compressed and under a content-hashed name that can be cached for ever. svgo was
tried on the worst offenders and recovered 2% — the set is already optimised and the weight
is real detail, not slack.
Also fixed on the way
languages.FLAGSheld the emoji andphones.FROM_LANGUAGEheld the ISO code, for the same24 languages, and the two were verified to agree exactly — one fact written down twice, in
the codebase whose own phone field refuses to store a country column for precisely that
reason.
FLAGSbecomesFLAG_COUNTRIESand holds ISO codes; a test asserts the two mapsnever contradict each other where both have an opinion.
Classification
Bug, interface, internationalisation. Cosmetic in consequence and unmissable in effect: it
is the first screen a new Windows user opens.