AOY
TR EN
← Writing

text-transform: uppercase breaks brand names on a Turkish page

3 September 2026· 2 min read· Front end

A short piece, because the bug is short. But once you have seen it you notice it in every Turkish interface.

I added platform badges to the project cards on this site: iOS · Android · Web. The badges use the same styling as everything else on the page — small monospace, uppercased:

text-transform: uppercase;

What came out was:

İOS · ANDROİD · WEB

The browser is not wrong

The page is <html lang="tr">. CSS uppercasing applies the casing rules of the text’s language, and in Turkish the capital of i is İ — with the dot. Turkish also has a dotless ı whose capital is I: four letters, two pairs.

So iOS becomes İOS and Android becomes ANDROİD. For a Turkish word that is correct. For a brand name it is not.

Why it slips past you

Every other badge on the page was a Turkish word — MOBİL + WEB, OYUN, WEB SİTESİ — and all of them came out right. Only the badge carrying a brand name broke, and at small monospace sizes the difference between İOS and IOS is a single dot.

The fix

There are two routes:

  • text-transform: none, and write the text the way you want it. That is what I chose: the badges now read iOS · Android · Web. Brand names already carry their own casing; not destroying it is the more correct answer.
  • Put lang="en" on the element. The transform then uses English rules and yields IOS. Technically correct, semantically a lie — that element is not English, it is a brand name.

⚠️ Writing the text as IOS and keeping uppercase also works (in Turkish the capital of I is still I), but then you are the one mangling the brand name.

The same rule bites elsewhere

  • JavaScript. 'i'.toUpperCase() always returns 'I' — JS is locale-insensitive by default. But 'i'.toLocaleUpperCase('tr') returns 'İ'. So CSS and JS can uppercase the same string differently.
  • Search and comparison. A user typing istanbul and a database holding İSTANBUL may not match once lowercased on a system with a Turkish locale. The classic “Turkish I problem”.
  • Database collation. If the server’s locale differs from the app’s, the same query returns different results in two environments.

What to take from it

  • Never text-transform a brand name. Its casing is part of the data, not of the presentation.
  • The lang attribute is not cosmetic. Casing, hyphenation and screen-reader pronunciation all read it; it needs to be correct, and being correct is what produces surprises like this.
  • Eyeball uppercase transforms in Turkish interfaces. Especially on English words containing an i.

More writing

all of it