Since I made the switch to a narrower main column and larger text, I’d been feeling like the “jagged right edge” of my posts had become much more noticeable. The fewer words there are on each line, the greater a proportion of a line each word occupies, you see, which means that when a long word was too long to fit on the end of a line and was forced to become the first word of the next, this could leave a really large gap, relatively. I had a hunch that hyphenation could ease my woes and that CSS had support to do it automatically now, so I did a search and came across this excellent blog post: All you need to know about hyphenation in CSS(external link).

Automatic hyphenation can be implemented at an extremely rudimentary level in two steps:

  1. Make sure your <html> tag specifies what language your webpage is in, because browsers use some kind of in-built dictionary to determine where to insert their automatic hyphens. For example, mine now says <html lang="en-AU">. Note that Firefox has by far the best support for languages other than English, with Safari runner-up. Browsers beyond those two basically only support English.
  2. Put hyphens: auto; in your stylesheet, on the element(s) you want it to apply to. For example, I put mine on the main element, so it applies to everything in the main column and nothing outside of it. (I’ve added some exceptions though, like multi-column lists.)

At this rudimentary level, automatic hyphenation is supported by most browsers now(external link). However, as All you need to know about hyphenation in CSS explains, this basic support has not really been implemented with the most optimal settings. The major one from my perspective is that, by default, Firefox and Chromium will hyphenate a word after as few as two characters. To my mind, this is not enough characters to warrant breaking the word there instead of just moving the entire word to the next line. It also feels a bit disruptive when reading, especially when there are 3+ words all in the same paragraph that broke after very few characters.

There do exist a number of other attributes that you can set to tweak the hyphenation rules in use, but a) they require browser-specific prefixes and b) they are currently only supported by Safari and IE/Edge (and the latter maybe only on Mac and Android?). Nonetheless, at the suggestion of that great blog post I linked to (which you should read if you want a detailed explanation of what this all does, because it’ll explain it all better than me 🙂), this now graces the bottom of my base stylesheet:

/* Hyphenation with aaaall the per-browser fallbacks */
main {
    -webkit-hyphens: auto;
    -webkit-hyphenate-limit-before: 3;
    -webkit-hyphenate-limit-after: 3;
    -webkit-hyphenate-limit-chars: 6 3 3;
    -webkit-hyphenate-limit-last: always;   
    -webkit-hyphenate-limit-zone: 8%;

    -moz-hyphens: auto;
    -moz-hyphenate-limit-chars: 6 3 3;
    -moz-hyphenate-limit-last: always;
    -moz-hyphenate-limit-zone: 8%;

    -ms-hyphens: auto;
    -ms-hyphenate-limit-chars: 6 3 3;
    -ms-hyphenate-limit-last: always;   
    -ms-hyphenate-limit-zone: 8%;

    hyphens: auto;
    hyphenate-limit-chars: 6 3 3;
    hyphenate-limit-last: always;   
    hyphenate-limit-zone: 8%;

The blog post also suggests hyphenate-limit-lines: 2; to prevent “laddering” in justified texts, which is when line after line is hyphenated resulting in a whole column of vertically-aligned hyphens. However, because my text is left-aligned, it’s very unlikely that hyphens on consecutive lines will align vertically, so I didn’t think this was necessary for my own stylesheet.

At any rate, I think these tweaks improve the situation on Safari a ton – and since, apparently, just under 60% of my visitors are using that browser, that should mean awesome readability for a lot of you 🙂 What I was in two minds about was what to do with Firefox and Chromium. I seriously considered using a @supports conditional(external link) in my CSS so text would only auto-hyphenate if one of the hyphenate-limit-chars or hyphenate-limit-before attributes was supported. However, when I went to collect screenshots for this very post to demonstrate that non-hyphenated text looked better than non-tweaked auto-hyphenated text I realised that… it didn’t, really? Sure, I can pick on examples where breaking after two characters looks bad. But I found more examples where the failure to break up a long word looked worse. So I scratched that whole idea to use a conditional and just used the CSS I posted above.

One thing you can do, if you think you know better than a web browser where to break up words, is to use the HTML encoded character &shy;. This character stays invisible if a word isn’t broken up, since all it does is tell the browser, “hey, this is a good place to break this word up, if you’re looking for one”. I have found this particularly useful for place names, like “Boroon­dara” or “Haw­thorn”, that browser in-built dictionaries don’t always seem to know what to do with. (On that note, I will admit that Safari seems to be stumped on fewer words compared to Firefox.) But this is, obviously, a very manual process. I mentioned the other day that I strongly dislike using HTML to work around issues that should be strictly stylistic, and it’s also just a hassle to insert random extra characters into words (especially because, you know, responsive design means all kinds of different words could be the break point depending on what device or window size someone’s browsing from). So I don’t see myself using this workaround very often – just occasionally, if my own testing leads me to do it for a specific word.

The other value of &shy; is that you can use it to manually control hyphenation, if you want that degree of control. That is, even if you don’t set hyphens: auto; on any element in your CSS, you can still insert &shy; into words if you want and enable words to break there. You could even combine this approach with a @supports conditional, e.g. to permit automatic hyph­enation on browsers that support the hyphenate-limit attributes, but allow only manual hyphenation (breaking on the &shy; character) in brows­ers that don’t. I mean, this sounds like way too much work to me, but if you don’t write very much or if you really really care about every minor detail of typography, you can do it.

Anyway, there you go, that’s been my rabbit hole of the day! Where does the time go 😅