
Smarter Link Underlines For Every Website - adamschwartz
https://eager.io/blog/smarter-link-underlines/?utm_source=hacker_news
======
fuzz_junket
It's a very nice idea — I always like smartening up the look of the Web — but
the resulting links are ghastly. If your word starts or ends with a descending
letter (e.g. "ghastly"), then the underline looks like it omits the first and
last letters. It breaks the semantics of what the underline means — any bit
that's underlined is supposed to be the link, and if it's not underlined it's
not a link.

They also made the mistake of showing a link that includes the word
"Typography", which has an underline so broken up and interrupted that it's
distracting (which devindotcom also pointed out). It's linked, then it's not,
then it's linked, then it's not!

So yeah, I have to give them credit for a good idea and a clever
implementation, but it just doesn't work out in the end.

~~~
adamschwartz
I appreciate your feedback. No doubt on some level this comes down to
aesthetic preference. I’m curious though, on the before-and-after examples on
the homepage [1] do you feel that _all_ of the afters are worse?

You and devindotcom did indeed bring up some good points, particularly about
descender-heavy links, something I plan to take a crack at [2]. But I’m
curious if you feel the entire strategy is flawed or if there’s just more work
to be done. On a related note: if you’ve used/seen it, how do you feel about
links in iOS 8 Safari? How do you feel about this before-and-after [3]
(screenshot of the first paragraph of the blog post)?

[1]:
[https://eager.io/showcase/SmartUnderline/](https://eager.io/showcase/SmartUnderline/)

[2]:
[https://github.com/EagerIO/SmartUnderline/issues/1](https://github.com/EagerIO/SmartUnderline/issues/1)

[3]:
[http://postimg.org/image/rgfx5icq9/](http://postimg.org/image/rgfx5icq9/)

~~~
lstamour
Well, I realised what was bugging me and why I prefer the iOS implementation
for now -- the tighter underline, both a pixel closer to the baseline and a
hair closer to each descender, helps ensure the underline feels continuous
even when it's broken this way. I do prefer this approach for headlines or
animated effects, but perhaps (as was suggested elsewhere) changing the
underline colour and/or tightening the spacing would help. A neat
implementation though. Seeing links here, it's true, the "g"s just seem to get
demolished by the underline. I wonder, if I linked to qithub.com, would you
see the difference? ;-)

Oh and if there's a way to apply this without requiring a background color, I
suspect this might be a popular add-on or browser setting for some folks.

~~~
adamschwartz
See my comment above [1]. I think you’ll find that the iOS 8 and
SmartUnderline implementations are closer than you think.

[1]:
[https://news.ycombinator.com/item?id=8588492](https://news.ycombinator.com/item?id=8588492)

------
devindotcom
To me, it actually adds visual complexity while eliminating the useful visual
cue of a single line being a single link. Here, there are many lines, which to
me indicate many links. In some cases, the line may present as dotted or
dashed (the word "piggy" randomly came to mind) — things that signify
something other than a link to me.

I would rather descenders weren't subsumed by the line either, but
interrupting the element itself instead seems like as much as a problem as it
is a solution.

~~~
gojomo
You can also see some dotting/dashing in the link on the page to the Butterick
book.

I have a hunch using a faded color for the (possibly-then-thicker) underline
would work better - the foreground descenders would retain distinction,
without the noise of dotty/dashy line-ends.

~~~
adamschwartz
Thanks for the suggestion. We’ll be taking a crack at descender-heavy links
[1], so this may come in handy!

[1]:
[https://github.com/EagerIO/SmartUnderline/issues/1](https://github.com/EagerIO/SmartUnderline/issues/1)

------
adamschwartz
In order to more accurately compare iOS 8 Safari’s text-decoration underline
implementation to SmartUnderline, I created a test page. [1] It contains five
links to the words gesture, quitting, discovery, piggy, and eager, set in
Helvetica.

To produce the iOS 8 version, I opened the page in Safari on iOS 8.1 pinched
zoomed to the maximum amount while keeping all five links within the frame,
and took a screenshot.

To produce the SmartUnderline version, I visited the SmartUnderline install
page [2] in Google Chrome on Mac OS X, entered the test page URL, and clicked
“Preview in a separate window”. With the screenshot from my iPhone opened next
to the browser, I used Command+[+/-] to zoom the browser until the font sizes
were the same size, then took a screenshot.

Here are the results: [3].

To summarize, I believe iOS 8 has some advantages and some disadvantages, but
to me there is no clear winner.

Some specific points in no particular order:

\- iOS underline breaks are always vertical cuts. Since SmartUnderline uses
text-shadow to “white-out” the underline, the cut-outs are in the shape of the
glyph. To me, this looks better in the “g” in “eager”, but worse in the “q” in
“quitting”.

\- iOS 8 shows a line between a “g” and ”y” (as in ”piggy”) and SmartUnderline
does not.

\- SmartUnderline’s underline extends less far to the left of the first letter
and right of the last letter. This looks better in “quitting” and potentially
worse in ”discovery”.

\- In general, SmartUnderline sets a little more space around each descender.

\- Both implementations show no underline before or after a leading or
trailing “g”.

\- Both implementations show the underline very close to the left side of the
“y” descender. I think improvements could be made here with both
implementations.

[1]:
[http://jsfiddle.net/adamschwartz/hyyerbq4/show/light/](http://jsfiddle.net/adamschwartz/hyyerbq4/show/light/)

[2]:
[https://eager.io/app/eA9ULux0UOJP/install](https://eager.io/app/eA9ULux0UOJP/install)

[3]:
[http://postimg.org/image/nf9b2ahd1/](http://postimg.org/image/nf9b2ahd1/)
(@2x
[http://postimg.org/image/688ricy2v/](http://postimg.org/image/688ricy2v/))

~~~
maaaats
Fyi: Postimg.com gives me a popup with "watch free hd movies now" and
redirects me to some gambling page. When going back, I can see your image
between some half naked guys. You may want to use something a bit more serious
in the future.

~~~
zackbloom
Imgur mirror of the 2x:
[http://i.imgur.com/KD7k0Rz.png](http://i.imgur.com/KD7k0Rz.png)

------
heycam
This kind of underline painting behaviour is proposed in
[http://dev.w3.org/csswg/css-text-decor-3/#text-decoration-
sk...](http://dev.w3.org/csswg/css-text-decor-3/#text-decoration-skip-
property) as text-decoration-skip:ink. Not yet implemented anywhere though.

------
Semiapies
Neat, though I don't actually think I like the look of it. I think I'd rather
have an underline further down, so that it's below the descenders.

~~~
adamschwartz
No doubt, at a certain point it does come down to aesthetic preference.

Using a border-bottom to achieve the look you’re describing is totally a valid
preference. One potential advantage to the border-bottom technique is the way
it can be used to make a link stand out. In fact, I use this link styling on
my personal website for that reason [1].

(Note: when using a border-bottom, I’d recommend using a slightly larger line-
height so that the line still seems associated with the text above it and not
the text below it. This is one of the pitfalls described in the original
Medium post [2].)

Unfortunately, aside from iOS 8, normal text-decoration underline links have
the descender crossing problem.

I absolutely took this into consideration when designing SmartUnderline.
SmartUnderline literally only applies itself to links with text-decoration
underline, nothing else. It even tries to ensure other conditions which make
the transformation favorable (display inline, solid background color, etc.).

Ultimately I think the before-and-after on the SmartUnderline website tells
the best story [3]. No doubt one may appreciate other, very different link
styles. (For example, just using a different text color to denote _link_ is a
perfectly valid and commonly used technique.) But if you’re using text-
decoration underline already, this just makes those links look better.

I think blogs, news articles and wikis are some of the primary examples of
where these links look best. Anywhere where text is heavy and the links are
_not_ the primary focus.

[1]: [http://adamschwartz.co](http://adamschwartz.co)

[2]: [https://medium.com/designing-medium/crafting-link-
underlines...](https://medium.com/designing-medium/crafting-link-underlines-
on-medium-7c03a9274f9)

[3]:
[https://eager.io/showcase/SmartUnderline/](https://eager.io/showcase/SmartUnderline/)

~~~
sopooneo
I think this is very clever and I appreciate the work you've done to make it
so robust. I'm not a designer, but I like to think I can appreciate at least
some of really good work. Your pages qualify there.

One note on your before and after, it's cool that you included arabic, but the
right to left nature makes it look like the examples are reversed. Though I
realize perhaps that was intentional.

~~~
adamschwartz
Thanks!

Ha! Yeah, my co-founder and I debated that one... (he thought I should reverse
it). I can see it both ways, but your comment certainly puts another vote in
the reverse-it column. Thanks again :)

~~~
ygra
I was about to send a PR for the reverse; then I realised what language it is.
Perhaps having the columns not centered but reading-direction-aligned would
make it clearer. Not sure there. But I'd keep it that way, it's rare enough
that people treat RTL languages properly when they don't know them ;)

------
blt
_> First we define a helper mixin textShadowToCropUnderline which draws 12
text-shadows, half to the left, half to the right, spaced every .03em._

This seems like a big waste of CPU and memory. I don't want to drain my
phone's battery rendering these underlines.

~~~
adamschwartz
In our tests (scrolling an older iPhone on a page with 300 links), we found
that it’s actually not as much an issue as you might think, particularly
because none of the shadows use a spread value. I’d definitely be interested
to see if you have evidence to the contrary.

That being said, it’s definitely something worth considering, particularly
since iOS 8 now implements descender-aware link underlines now. If there were
a way to duck type for this feature, we’d definitely disable the JS anywhere
we detect it working. Drawing an underlined “g” on a canvas and then reading
the pixels at a certain location may work, but we haven’t tried it yet.

------
hftf
I had seen this effect about two years ago on the website of Roman Komarov and
was impressed by it at the time:
[http://kizu.ru/en/fun/](http://kizu.ru/en/fun/)

~~~
adamschwartz
I really like how he applies the styles on hover. I wanted to do something
like that with SmartUnderline but unfortunately there is no way to call
getComputedStyle with the :hover pseudo-class applied. (This is necessary
because SmartUnderline only applies to links which have text-decoration
underline.)

Traversing the enter style ruleset is possible but didn’t seem worth it for a
library like this.

Another way is through a configuration option. Something like
`SmartUnderline.init({ '.content a': 'hover' });` perhaps.

------
crystaln
While I admire the attention to detail, it is all in vain for me. I much
prefer the simplicity of a solid line to the awkward fragments dodging
descenders. My brain continuously tries to make sense of the incomplete line,
and some words no doubt will add to the confusion with long stretches of
characters having minimal expression of the underline.

Case in point, the word giggly has what appear to be specs of dust underneath.

------
spc476
Why limit yourself to just underlining links? Why not some other convention? I
played around with this a bit over a decade ago:
[http://www.conman.org/people/spc/writings/hypertext/fragment...](http://www.conman.org/people/spc/writings/hypertext/fragment/)
(note: In the twelve years since I wrote that, most of the links offsite are
now dead, which is another issue with links).

At first, the links in the "fragment" are invisible. You can toggle among
that, single angle quotes (not used in English, which is why I picked that
option), small bullet points on either end, and the default HTML underline.

~~~
cgriswald
FWIW, my experience with your link:

The lack of any indicators at all was frustrating. I had to take physical
action to determine whether something was a link. In practice I think I would
just stop using the links. I think some kind of indication is needed.

The default underline was the best for me. I don't rule out that this is
because I am used to the underlines. Going in I thought the dots would be
bets, but I found them distracting. With practice they might be the best.

The angle brackets were by far the worst. It could be because I have seen
enough HTML for angle brackets to have singificance, but I think it has more
to do with parantheses and how we use them in text. I just found them
distracting and they really took me out of the work.

Of the cuff thought... small superscripted dot or something? I'm used to
seeing footnote or citation indicators in the corners and they generally don't
take me out of whatever I'm reading.

~~~
spc476
The dots are small to begin with, any smaller and they might not be seen.
There might be other, visible but not underlined techniques.

------
ddebernardy
The library's showcase page has the key bits imo:

> \- It makes an assumption about selection color, which is OS- and browser-
> dependent.

> \- Each smart-underlined link has 12 text-shadows drawn underneath it, which
> could potentially have performance penalties on mobile or older devices.

[https://eager.io/showcase/SmartUnderline/](https://eager.io/showcase/SmartUnderline/)

(Imho, the two points introduce enough risks and reasons to not use it and
wait for OS- or browser-level updates instead.)

------
WiseWeasel
This seems like something user agents should apply to all 'underline' text-
decoration by default in order to improve readability. Is there any reason not
to?

~~~
adamschwartz
iOS8 Safari agrees with you. :) (As do I fwiw.)

Unfortunately I imagine this is easier-said-than-done and may have to do more
with the underlying typographical engines of OS-s than browsers. (I’m just
guessing though.)

~~~
WiseWeasel
Ah, an excellent point. The TrueType font format apparently does specify an
underline position and height [1], though there's no mention of any allowance
for this descender-dodging feature. The fact that font formats defer the
actual drawing of the underline to the renderer gives me some hope. This seems
to highlight the issue of web browsers having different font rendering needs
from other apps, since underlining is so much more prevalent.

[edit] Obviously, it's a lot easier to fix this issue with a single font, as
Apple has done in Messages, than to fix it well in every font.

With regards to this implementation, I'd rather not have to worry about the
background, font and select background colors for every link. Applying text
shadows over gradient-drawn underlines is an inspired hack that I'll have to
remember, just in case, but I really wish there were a better way.

Maybe we should push for a 'text-mask-underline' CSS property that accepts
radius, hardness and opacity values, in order to apply a fade to the underline
around text descenders. [/edit]

[1]
[http://fontforge.github.io/fontinfo.html](http://fontforge.github.io/fontinfo.html),
[http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=...](http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=IWS-
Chapter08#05931f9d)

~~~
adamschwartz
Thanks for that information re:TrueType! My knowledge of these things tends to
end at the browser, but I too hold hope for better type in future OS-s.

The fact that Apple decided to tackle this on iOS, an OS used on handheld
devices which are typically viewed at closer distances, tells me that it’s
something they feel is worth doing when you have the display resolution to do
it right.

SmartUnderline makes a similar assumption, not applying itself to links with a
small-enough font-size computed style.

With respect to your [edit] block:

> Obviously, it's a lot easier to fix this issue with a single font, as Apple
> has done in Messages.

Apple has implemented this throughout iOS 8, not just in Messages. Here’s a
screenshot of Safari [1].

> I'd rather not have to worry about the background, font and select
> background colors for every link.

That’s actually the beauty of SmartUnderline. It figures all of these things
out for you, automatically [2]. Please let us know if you run into any trouble
though. :)

[1]:
[http://postimg.org/image/4ncgrezxr/](http://postimg.org/image/4ncgrezxr/)

[2]: [http://git.io/9YNfgg](http://git.io/9YNfgg)

~~~
WiseWeasel
Re: [2], nicely done! For a dirty hack around browser limitations, it is well
implemented. It's a good thing gradient backgrounds behind text are out of
style. : P

~~~
adamschwartz
Thanks!

If a background-image is specified, we abort [1]. (This would apply to CSS
gradients as well.) Of course we’d like to support non-solid backgrounds at
some point, but short of a true HTML-to-canvas solution, there’s not really
that much better you can do without wreaking lots of havoc.

[1]: [http://git.io/1WqsAA](http://git.io/1WqsAA),
[http://git.io/n4tRrw](http://git.io/n4tRrw)

~~~
WiseWeasel
Is this only getting the first container's background? If so, what happens
when a layer below that has an image or gradient bkg?

~~~
adamschwartz
Nope, it traverses up the DOM until it finds an element which has any non-
transparent background. If the first thing it finds has a background-image, it
aborts. If it’s a solid color, it returns that container. [1]

This absolutely still is prone to bugs when `position` or other properties are
used to move elements visually outside of their parents, but it’s about as
good as you can do without a true HTML-to-canvas implementation.

[1]: [http://git.io/ChvO3Q](http://git.io/ChvO3Q)

------
amelius
This example shows once again that CSS is not a good declarative language: it
provokes hacking. In this case, a hack has to be applied in every instance
where this is needed.

Instead, if CSS were developed by actual language designers, it would have
been possible to write this as a modularized thing, completely hiding the
actual implementation.

------
bshimmin
Aside from the many other criticisms raised in the comments, this seems like
something of a deal-breaker to me: "It requires that the text be on top of a
solid background color."

~~~
ygra
It's a restriction, yes, but far from a deal-breaker, I'd say. There are very,
very many websites out there that have text on solid-coloured backgrounds.

------
stonogo
This seems like a hell of a lot of client-side processing just to enforce a
trivial (and arguably bad) typography preference.

------
transfire
Web 1.0 called and they want their underlined links back.

~~~
lelandbatey
I'm confused, is there some other way we're supposed to indicate something is
a link now? I thought was considered bad practice to mess with link styling
too much for usability reasons.

------
shetter
That's nice in theory, but it's also yet another example of Apple innovating
and getting it right, and people implementing a quick copy without going
through nearly as much _necessary_ design thinking as Apple did. The end
result is that only Apple's implementation is better than the default one. Of
course I'm not blaming you personally for that, I mean, even Microsoft has
fallen prey to this phenomenon (and on a vastly larger scale). But it would
nice if people were more observant.

~~~
adamschwartz
I appreciate your feedback. There are always ways of improving something, even
in the case of Apple’s implementations.

Are there particular aspects of this implementation you feel make it worse
than Apple’s?

Ultimately we see this as an incremental improvement to the default text-
decoration underline styling provided by most operating systems and browsers.
However, we’re eager to work with OS community to improve this even further.
Thanks again!

~~~
shetter
Sorry somehow I thought that was obvious. Basically they cut the line very
close to the letter, that way it doesn't break the line visually, which is
what the other comments here on HN seem to criticize. It's a very simple and
subtle thing but that's what makes the difference. My point was that sometimes
the incremental steps between the default design and Apple's design are worst
than if you just kept to the default design. You have to make a big step
before perceiving benefits. Sorry for the pigeonholding though, that was more
of a general rant.

~~~
adamschwartz
See my comment above [1]. I think you’ll find that the iOS 8 and
SmartUnderline implementations are closer than you think.

[1]:
[https://news.ycombinator.com/item?id=8588492](https://news.ycombinator.com/item?id=8588492)

~~~
micampe
You keep repeating that comment but no, they are not. The idea is clever and
the result is pretty good, but what the parent is saying – that in your
implementation the line looks more broken up because it's more separated from
the glyphs – is true.

You may be able to fix that by tweaking the shadows but as it is currently
implemented it works pretty well for larger display text but not so much for
smaller body text.

