Styling Underlines on the Web

rfp-robotRFP ROBOT: Website Request for Proposal Generator

The time has come for a new website (or website redesign), which means you need to write a website request for proposal or web RFP. A Google search produces a few examples, but they vary wildly and don’t seem to speak really to your goals for developing or redesigning a new website. You need to write a website RFP that will clearly articulate your needs and generate responses from the best website designers and developers out there. But how?

Have no fear, RFP Robot is here. He will walk you through a step-by-step process to help you work through the details of your project and create a PDF formatted website design RFP that will provide the information vendors need to write an accurate bid. RFP Robot will tell you what info you should include, point out pitfalls, and give examples.


Styling the underlines that sit beneath links can be a tricky business, and I constantly forget what’s the best approach depending on the situation. Thankfully however, John Jameson gets us up to speed in this guest post.

There are a bunch of different ways to style underlines. Maybe you remember the article Crafting link underlines on Medium. Medium wasn’t trying to do anything crazy; they just wanted to create a pretty normal-looking line below their text.

A thin, black underline with space around descenders—via Marcin Wichary, Crafting link underlines on Medium

It’s a pretty basic underline, but it’s a good size and it skips descenders too. Definitely nicer than most browsers’ default. Well, it turns out Medium had to go through a lot of trouble to get that style on the web. Two years later, it’s still just as hard to style a good-looking underline.
Goals
What’s wrong with just using text-decoration: underline? If we’re talking about the ideal scenario, an underline should be able to do the following:

Position itself below the baseline
Skip descenders
Change color, thickness, and style
Repeat across wrapped text
Work on any background

I think these are all pretty reasonable things to ask for, but as far as I know, there’s no intuitive way to achieve all of them in CSS.
Approaches
So what are all the different ways we can underline text on the web?
Here are the ones I can think of:

text-decoration
border-bottom
box-shadow
background-image
SVG filters
Underline.js (canvas)
text-decoration-*

Let’s go down the list one by one and talk about the good and bad parts of each approach.
text-decoration
text-decoration is the most straightforward way to underline text. You apply a single property and that’s all there is to it. At smaller sizes, it can look pretty decent, but increase the font size and the same line starts to feel clumsy.
See the demo.
The biggest problem with text-decoration is its lack of customizability. It uses the color and font size of whatever text its applied to and there’s no cross-browser way to change the style. More on that later.
Good

Easy to use
Positioned below the baseline
Skips descenders by default in Safari and iOS
Wraps across lines
Works on any background

Bad

Can’t skip descenders in other browsers
Can’t change color, thickness, or style

border-bottom
border-bottom offers a good balance between being quick and customizable. This approach uses a tried-and-true CSS border, which means you can change color, thickness, and style with ease.
This is what border-bottom looks like on inline elements:
See the demo.
The big gotcha is how far away the underline is from the text — it’s completely below the descenders. You can address that by making elements inline-block and reducing line-height, but then you lose the ability to wrap text. Good for single lines, but not much else.
See the demo.
Additionally, you can use text-shadow to cover up parts of the line near descenders, but you have to fake it by using the same color as whatever background it’s on. That means it works only for solid-color backgrounds and not gradients or images.
See the demo.
At this point, there are four properties styling a single underline. That’s a lot more work than text-decoration.
Good

Can skip descenders using text-shadow
Can change color, thickness, and style
Can transition and animate color and thickness
Wraps by default unless it’s an inline-block
Works on any background unless using text-shadow

Bad

Positioned far away and difficult to reposition
A lot of unrelated properties to get it just right
Janky text selection when using text-shadow

box-shadow
box-shadow draws an underline with two inset box shadows: one to create a rectangle and a second to cover it up. That means you’ll need a solid background for this to work.
See the demo.
You can use the same text-shadow trick to fake gaps between the underline and the text’s descenders. But if the line is a different color from the text — or even just thin enough — it doesn’t really clash like text-decoration does.
Good

Can be positioned below the baseline
Can skip descenders using text-shadow
Can change color and thickness
Wraps across lines

Bad

Can’t change style
Doesn’t work on any background

background-image
background-image comes the closest to everything we want and with the fewest gotchas. The idea is that you use linear-gradient and background-position to create an image that repeats itself horizontally across lines of text.
You’ll have to display: inline; this approach too.
See the demo.
This approach doesn’t have to use linear-gradient either. You can bring your own background image for some cool effects.
See the demo.
Good

Can be positioned below the baseline
Can skip descenders using text-shadow
Can change color, thickness (allows half pixels), and style
Works with custom images
Wraps across lines
Works on any background unless using text-shadow

Bad

The image can resize differently across resolutions, browsers, and zoom levels

SVG filters
Here’s an approach I’ve been toying around with: SVG filters. You can create an inline SVG filter element that draws a line and then expands the text to mask out parts of the line we want to be transparent. Then you can give the filter an an id and reference it in CSS with something like filter: url(‘#svg-underline’).
The advantage here is that the filter adds transparency without relying on text-shadow. That means you can skip descenders on top of any background, including gradients and background images! This one works only on a single line of text though, so heads-up on that.
See the demo.
Here’s what it looks like in Chrome and Firefox:

Browser support in IE, Edge, and Safari is problematic. It’s hard to test for SVG filter support in CSS. You can use @supports with filter, but that only tests if the reference works — not the applied filter itself. My approach ends up doing some pretty gross browser sniffing, so double heads-up on that too.
Pros

Positioned below the baseline
Skips descenders
Able to change color, thickness, and style
Works on any background

Cons

Doesn’t wrap across lines
Doesn’t work in IE, Edge, or Safari, but you can fall back to text-decoration. Safari’s underlines look good anyway.

Underline.js (Canvas)
Underline.js is fascinating. I think it’s super impressive what Wenting Zhang was able to do with JavaScript and some attention to detail. If you haven’t seen the Underline.js tech demo before, definitely stop reading for a minute and check it out. There’s a fascinating nine-minute-long talk on how it works, but I’ll give you the short version: it draws underlines with <canvas> elements. It’s a novel approach that works surprisingly well.
Despite the catchy name, Underline.js is a tech demo only. That means you won’t be able to drop it into any projects without modifying it a whole bunch first.
It’s worth bringing it up here as a proof of concept. <canvas> has the potential to create beautiful, interactive underlines, but you’ll have to write some custom JavaScript to get them working.
text-decoration-* properties
Remember the “more on that later” part? Well, here we are.
text-decoration works fine by itself, but you can add a few experimental properties to customize the way it looks:

text-decoration-color
text-decoration-skip
text-decoration-style

Just don’t get too excited. You know, browser support.
text-decoration-color
text-decoration-color lets you change an underline’s color separately from its text color. The property even has better-than-expected browser support — it works in Firefox and prefixed in Safari. Here’s the catch: If you’re not clearing descenders, Safari puts the line on top of the text. 🙃
Firefox:

Safari:

text-decoration-skip
text-decoration-skip toggles skipping descenders in underlined text.

This property is non-standard and works only in Safari right now, so you need the -webkit- prefix to use it. Safari enables this property by default though, which is why underlines skip descenders even on websites that don’t specify it.
If you’re using Normalize, know that recent versions disable the property to keep things consistent between browsers. You need to flip it back on if you want those dreamy underlines.
text-decoration-style
text-decoration-style offers the same sorts of lines you’d expect from border-style, but adds in wavy lines too.
Here are the different values you can use:

dashed
dotted
double
solid
wavy

Right now, text-decoration-style works only in Firefox, so here’s a screenshot:

An assortment of solid-color underline styles

Look familiar?
What’s missing?
The text-decoration-* properties are far more intuitive than using other CSS properties to style underlines. But if we take another look at our earlier requirements, these properties don’t offer a way to specify line thickness or position.
After doing a little research, I came across these two properties:

text-underline-width
text-underline-position

It looks like they were pitched in earlier drafts of CSS, but never implemented due to lack of interest. Hey, don’t blame me.
Takeaways
So what’s the best way to underline text?
It depends.
For small text, I recommend using text-decoration and then optimistically applying text-decoration-skip on top. It looks a little bland in most browsers, but underlines have looked that way forever and people don’t seem to mind. Plus there’s always the chance that if you’re patient enough, all your underlines will look awesome later on without you having to change a thing.
For body text, probably use the background-image approach. It works, it looks great, and there are Sass mixins for it. You can probably omit text-shadow it if the underline is thin or in a different color from the text.
For single lines of text, use border-bottom and whatever other properties you want to go with it.
And for skipping descenders on top of a gradient or background image, try using SVG filters. Or just avoid using an underline altogether.
In the future when browser support is better, the answer is text-decoration-* all the way.

Styling Underlines on the Web is a post from CSS-Tricks
Source: CssTricks

Posted on October 10, 2016 in Austin Web Designer, browser, business, css, custom, drupal design,, Drupal Developer, drupal developer austin, Drupal Development, Drupal Development Austin, Drupal Support, Expert Drupal Development, firefox, interactive, iOS, javascript, Safari, The, web, Web Design Services, webkit

Share the Story

Back to Top