In order to satisfy WCAG 2.1 1.4.3 Contrast (Minimum) (Level AA) text links must a) have at least a 3:1 contrast ratio with surrounding text, and b) have a 4.5:1 contrast ratio against the background.
As it relates to using color alone as the differentiator, the available palette that satisfies the requirements is extremely limited, so there has to be another non-color indicator for these links.
Solution
Underline text links.
Underlines don’t have to simply use text-decoration: underline either. The following gif from this CodePen example explores a few different methods.
Here are examples using the default underline.
Before
After
What user problem(s) does this solve?
Highlights actionable items and references within issuable descriptions, discussions, and wikis.
Allows links to stand out for users who may have trouble seeing them due to small text and/or low contrast. This isn’t always related to a visual deficiencies either. It can be from viewing the screen outside or with glare, or when the user has high-contrast mode on in their system.
Satisfies WCAG 2.1 1.4.3 Contrast (Minimum) (Level AA) which moves the product closer to fuller compliance.
Out of scope
Content and elements or components not created with markdown.
Inline elements that already have different styles. For example, linked usernames or inline code blocks that contain links.
Inline labels.
Current limitations
The typography styles and typescales from Pajamas are not implemented into the product. Doing so will be a large undertaking so a possible solution would be to include this change in Pajamas, and separately address in the product’s current state.
I prefer these two methods because I think the slight transition is classy, and there’s more statefulness.
This doesn’t conflict with our more global use of text-decoration: none as a default, making this more opt-in.
It does involve more styles, maybe… because the cost of opt-in could be less than the cost of using the default underline and overriding it for other elements.
The lighter underline created with the border can be visually less strong than the default underline. As far as I’ve read there’s no requirements applied to the underline itself, although I’d aim for at least a 3:1 contrast ratio against the background. In the CodePen example the transparency of the underline is 60%, which achieves a 3.19:1 contrast ratio.
One caveat with the border method, you’ll notice that it’s offset further from the text than the default, which is because the border is at the edge of the container. This may or may not be less of a collision with descenders than the default. Personally, I find the border to help with descender clarity.
@jeldergl I like the border link as well, the space below gives it a little space to breathe, plus it fixes that breakage between some letters, like you mentioned.
The background color on hover is interesting, but wondering if it will feel too disjointed from how we treat other links, outside of the markdown. I have no concern with the first option (no background color animation).
They can’t differentiate by color alone for any state, so all states are applicable. The principle is that a user should understand the purpose of the element based on its affordance before interacting with it.
@pslaughter, wouldn't the styles be inlined or otherwise part of the email generation? In other words, if the direction is to have inline links underlined, then that could proceed in the email styles aside from anything else.
If it's for sure blocking though, I can see what could be done to escalate the other issue!
@jeldergl I think it's a bit of a Gray-Area to say that this issue blocks the other.
The concern is that some email clients will automatically link-ify and style (using some default blue and underline) anything that looks like a link. It seems that @smokris found a way to work around this, but we wanted to get UX's first. WDYT?
@pslaughter Since the automatically linked text could be anywhere, I think it should be underlined and a blue could be prescribed. I'm not too concerned about overriding the blue though considering it could be related to system settings, which would take into account light/dark UI, and other system contrast settings.
@anna_vovchenko what do you think of this issue as a candidate for beautifying the UI? This idea was number 16 in our RICE sheet. It starts to address the lack of underlines without drastically breaking the UI
If you ever have any spare capacity @anna_vovchenko I'm happy to collaborate with you on this. Otherwise hopefully it gets picked up in a future beautifying the UI
I think the most important thing to document is the -thickness and -offset values.
@danmh where would you document this? I don't know about Pajamas since we try to avoid specific specs like this when there's a live example. I agree though, we need to capture it somewhere.
The text-decoration-thickness property does not work unless either text-underline-offset is set to something other than auto or text-decoration-color is set to something other than currentColor (source)
I saw that there's a bug in Chromium for text-decoration-thickness, but I think we avoid its impact by having the thickness set to 1px as you've done.
Overall how are you feeling about these changes? While I like the thought of a 1.5px thickness to match regular character and icon weight, I think it can start to draw attention away from the text, especially in the case of descenders and skip-ink breaks.
@jeldergl right now, I think in this issue. Later in the code! I just wanted these thoughts and explorations not to get lost.
I saw that there's a bug in Chromium for text-decoration-thickness, but I think we avoid its impact by having the thickness set to 1px as you've done.
I'll take another look. See some hover explorations above
Overall how are you feeling about these changes? While I like the thought of a 1.5px thickness to match regular character and icon weight, I think it can start to draw attention away from the text, especially in the case of descenders and skip-ink breaks.
Feeling pretty good. Another potential reason to say away from 1.5px thickness is non-retina screens. Right now my focus is thinking through the Figma and roll out experience.
The only states that are essential, as I understand it, are default (rest) and focus. The cursor change on hover is enough of an indicator (as long as we aren't changing that, which we're not). I do like the concept of animating the thickness or offset on hover, but that could come with extra code to address reduced motion and I'm not certain of the performance impact, although it's possibly less than animating a box-shadow.
Right now my focus is thinking through the Figma and roll out experience.
On this note, anything we do to tap into CSS properties that can't easily be replicated in Figma, or done with text styles there, will pose a challenge.
I think I'll leave the hover states just with a colour change for now. But I think the exploration shows there are some good opportunities to add some refinement in the future.
On this note, anything we do to tap into CSS properties that can't easily be replicated in Figma, or done with text styles there, will pose a challenge.
All SUS-impacting issues need to have a proper severity label set.
Please add a severity label, remove the automation:ux-missing-labels label, and then reply to this comment briefly explaining your reasoning for providing this severity.
If you are not the DRI for this area and would like help determining the best severity, please @ the appropriate person for assistance.