Shaping ligatures in monospace fonts

joshleeb.com

78 points

todsacerdoti

a day ago


30 comments

Shugyousha 21 hours ago

In general, I think having ligatures in a monospace fonts is a bad idea.

The reason is that in a monospaced font all the glyphs are supposed to the same advance value. This forces the ligatures to always take up the same space as two (or however many glyphs) are involved, which may stretch the ligature glyph in a non-intended way (if it is even possible to rasterise it that way).

Monospace fonts are also often used for programming (because they make sure that the columns line up consistently, regardless of the font being used). I personally don't see the point in showing ligature glyphs that do not correspond to the actual Unicode code points encoded to bytes in the source code.

Just my 2 cents.

  • ojkelly 18 hours ago

    I thought the same, but when Berkeley Mono got ligatures I gave them a go and never turned them off.

    I think the truth is that any good monospace font is designed with an awareness of the grid those characters are laid out in. The rhythm and stability of that grid is a feature of monospace fonts. It lets us line up text, draw shapes and so on.

    You would think not having the underlying characters visible would be an issue, but ligatures are just symbols like any other. In a short time you learn to read them, like you would any contracted word.

    • 0110101001 16 hours ago

      Decided to check those ligatures out, but this is pretty much entirely unreadable to me.

      https://usgraphics.com/static/products/TX-02/images/TX-02-li...

      • WorldMaker 12 hours ago

        It is probably a bit easier to start from a language you are familiar with. That image intentionally is a mismatch of random arrows and operators that don't necessarily align to the semantics of real code.

        I think that's one of the things Fira Code's Readme [1] does a better job at than Berkeley Mono's page. The top big image breaks down the ligatures in high level categories or the programming language they are most associated with, side by side the version with a ligature. Further down the Readme you can several real examples from programming languages with the ligatures called out, giving you the context clues of what it looks like in a language you may be already familiar with.

        [1] https://github.com/tonsky/FiraCode/tree/6.2

  • InsideOutSanta 20 hours ago

    Rationally, what you say makes sense, of course. But I love ligatures for programming. First of all, I think they just look nice.

    But second, I also feel that for me, they make code a bit more readable. Without ligatures, multiple characters are often used to create one symbol; with ligatures, one symbol is always rendered as one single visual character. So if I read code, it just feels a bit easier for my brain to parse ≥, rather than >=.

    • Zanfa 19 hours ago

      > So if I read code, it just feels a bit easier for my brain to parse ≥, rather than >=.

      Clearly there's personal preferences involved, so there's no objectively better or worse, but it still blows my mind, because reading ligature symbols like ≥ and ≠ always makes my brain skip a beat, so I need to reread a few times to "get it".

      • WorldMaker 12 hours ago

        Some of that subjective influence with ≥ and ≠ especially is how much time you've spent in math courses or reading math papers. For some of us those have always been the "real" operators and >= and != the fallback replacements that look "close enough" in easy to type ASCII. We were sort of doing the opposite all along, translating the ASCII breakdowns into the math notation in our heads, and ligatures can feel like a bit of a relief because now you see the "real thing".

  • tsimionescu 17 hours ago

    At least for programming ligatures, wouldn't they tend to be shown as a single glyph (and occupy the same space)? I don't like them, but for people that do, I expected ≠ to be displayed instead of !=, not a different longer glyph.

    • InsideOutSanta 16 hours ago

      In coding fonts with ligatures, ligatures usually have the same width as all of the component characters combined. So if you type !=, you will see a character looking like ≠ that is two advances wide. You will even be able to select the middle of the character, hit backspace, and delete the (invisible) "!".

      This is necessary because if all ligatures were one advance wide, you couldn't easily tell the difference between =, ==, and ===, or between != and !==.

    • athenot 17 hours ago

      I would rather != stay the way it is, and have the language support ≠ as a synonym. 30 years ago, on the mac's HyperCard, the language supported ≠ as an inequality comparator (as well as ≤ and ≥ for <= and >=, respectively). On the mac it's easy to type with the Option key and =.

      Back then, those characters weren't easy to type on dos/windows so it seems to be a case of being stuck with the "lowest common denominator" in terms of character input across OSes, reminiscent of C's trigraphs where "??<" was used because keyboards didn't have "{"—thankfully those are long gone. Ligatures are a hack around that but it always struck me as an inelegant solution.

Etheryte a day ago

I think the ligature from MonoLisa is a good example of how not to do ligatures. I can't tell whether it stands for "#={" or "#{". Ligatures can be nice, to each their own, but only if they don't introduce ambiguity.

  • propter_hoc a day ago

    It also makes no sense and looks terrible to connect those two glyphs with a ligature. Unlike "fi" or "ij", there's no reason (kerning or spelling) to want to smush # into {.

    • weinzierl a day ago

      I don't doubt that but I cannot really pinpoint what the reason is to want "fi" and "ij" in a monospace font? Do these narrow letter ligatures then take up only a single character cell?

      • stevesimmons 21 hours ago

        If you're Dutch, "ij" is a technically a single letter, and may sometimes be written as "y".

        (Traditionally, Dutch words are sorted alphabetically with "ij" treated as if it were "y". On my first visit to Amsterdam, pre-Google Maps, I had the bizarre experience of standing in one of the main streets, Vijzelstraat, but being unable to find it on my map. Its index of streets has nothing starting "Vij...". I sheepishly had to ask someone wtf was going on. He pointed me lower down to the end of the "V"s where all the "Vij..." street names were hiding!)

    • WorldMaker 11 hours ago

      #{ in a few languages is a bit of a high-level operator like "start a record/object/hash table". The # is visually a bit like a handle on a coffee cup (which you are about to fill). The octothorpe (#) is also sometimes called a "hash", making it also a bit of a visual pun if it is indeed the start of a hash-table. (Think JSON object syntax in a language where you want to make sure you can't just accidentally write objects anywhere or confuse different uses of { such as starting a code block, so you put a handle on them.)

      "Smushing" it together makes it even more visually distinct as a "single" operator, further adds to the visual metaphor of the "coffee cup handle", maybe obscures the "hash" visual pun a little bit, but maybe not enough to care.

Stratoscope 21 hours ago

Why should code have to be in a monospace font?

I've read and written all my code and that of others in proportional fonts for at least 15 years.

Of course there are coding styles that look better in a monospace font, e.g. if you use column alignment instead of simple indentation.

But even those are nearly as readable in a proportional font.

So things don't line up perfectly? Big deal.

As a specific example, any Python code formatted with Black will be equally readable in a proportional font or a monospace font.

This is because Black forgoes column alignment tricks and uses simple indentation for everything.

  • upofadown 19 hours ago

    >Why should code have to be in a monospace font?

    Because it usually is. Most people have learned it that way. What would be the point in having to learn both ways?

    Having the characters on a grid makes it less likely that two characters will be interpreted as a single character. Absolute legibility is better with monospaced fonts. Programming involves a lot of characters adjacent to one another that are normally not in prose.

    You could turn the question around: why anyone would ever use proportional fonts for anything other than prose? The only real advantage that a proportional font has is that you can squeeze more text into a particular space and as a result you can read faster. The increase in reading speed comes from the sort of context that you normally don't have for programming. The increase in the amount of text is not reliable (it depends on the number of thin characters) and as a result is not helpful for programming.

    • Stratoscope 9 hours ago

      I appreciate you sharing your thoughts on this. I would gently note that you addressed a question other than the one I posed:

      > Why should code have to be in a monospace font? [emphasis added]

      The short answer is that it doesn't. Many programmers prefer proportional fonts, just as the vast majority prefer monospaced.

      Similarly, many programmers prefer light themes. Being somewhat older than most programmers, I find dark themes very hard to work with. There is a scientific and practical reason for this: A light theme causes the irises in my eyes to "stop down" so there is less blurring of the text. This is similar to the way a camera lens may give a sharper result when stopped down a bit instead of wide open.

      > The only real advantage that a proportional font has is that you can squeeze more text into a particular space and as a result you can read faster.

      Interesting that you mention this, as it relates to one of the reasons I like proportional fonts. It's not to squeeze in more text, it's so I can use a larger font. At my age, this is helpful! And I find proportional fonts more beautiful and readable.

      Anyway, let's respect each other's preferences instead of trying to establish what is best for everyone. You like monospaced fonts, I like proportional, and it's great that we have the choice!

    • ossopite 10 hours ago

      > The only real advantage that a proportional font has is that you can squeeze more text into a particular space and as a result you can read faster

      I would disagree with that - I find it easier, more comfortable rather than just faster to read any text in a proportional font because the spacing of characters is, well, proportional to what the form of each letter requires. I think it makes it easier to recognise words. It's true that code has a lot of unusual combinations of characters but still it is mostly ordinary words. A proportional font that makes those unusual combinations of punctutation characters less clear is certainly bad, but there are proportional fonts that don't.

  • phinnaeus 18 hours ago

    Do you use syntax highlighting?

    • Stratoscope 9 hours ago

      I do, and I am curious about the question. Is there something about syntax highlighting that would be different with a monospaced vs. proportional font?

p4bl0 a day ago

> The text is almost all English with glyphs from the Basic Latin Unicode block.

Well, the code text probably, in most programming languages. But code also contains comments, and comments are very often written in other languages than English in personal project and/or during development phases before clean up for merging, and sometimes even after that.

hbosch a day ago

>Since we are working with a monospace font, every glyph must have the same advance

Just pointing out that this is merely an expectation and not a rule. You can happily design a "monospace" font in any font publishing software that blatantly disrespects a single width. In fact, you can just manually make any letterform 2x width, and that is exactly what most monospace ligatures do! (except the bad ones, which combine e.g. "fi" ligature a single width letter)

The ligature letters are just... 2x width. Believe it or not this is totally legal!

https://www.hanselman.com/blog/monospaced-programming-fonts-...

  • DHowett a day ago

    > > advance

    > you can just manually make any letterform 2x width,

    Yes. Any glyph may be wider than its advance. The advance, however, must remain the same across all glyphs. If it does not, the font is not monospaced.

    The passage you’ve quoted refers not to the width, but to the advance.

california-og a day ago

Fonts are kind of dumb. There's usually nothing actually weird going on. Ligatures are simple character substitutions. What the LIGSPACE is, most likely, is a spacing character added by the designer to align the characters in the ligature correctly. So, the LIGSPACE is just a character like any other and is nothing special. For example, when you hit a space bar, you are inserting a character which doesn't render anything because the designer didn't draw anything there. There's no extra logic.

  • eqvinox 15 hours ago

    I would recommend learning the difference between a character and a glyph; it's the first thing to learn in understanding fonts and font rendering.