Text decoration underline. Underlining links and text via CSS, text-decoration property

We continue to do tricks on pure css. Today I will tell you how to make a beautiful one using css dividing line in the form of a wave Online. It can be used, for example, to visually separate blog posts or separate blocks in a sidebar.

Once upon a time I already talked about. But it used the hr dinosaur tag with a couple of tricky style rules that allowed you to play with the shadow.

Today the situation is completely different. To display a line as a wave, you will have to add much more to the rules more tricks and use not just css, but css3. Welcome!

To begin with, the usual html code. We will display the lines as empty div blocks with special sets of rules. Empty blocks are, of course, evil. But sometimes you have to put up with it.
















Here we have shown 4 types of lines. And this is what a set of css styles for them will look like:

Wave (
overflow: hidden;
position: relative;
width: 630px;
height: 50px;
}
.line(
position: absolute;
width: 630px;
height: 26px;
}
.line1 (

}
.line2 (

}
.line(
background-size: 50px 50px;
}
.smallLine(
position: absolute;
width: 630px;
height: 5px;
}
.smallLine1(
background: linear-gradient(45deg, transparent, transparent 49%, black 49%, transparent 51%);
}
.smallLine2(
background: linear-gradient(-45deg, transparent, transparent 49%, black 49%, transparent 51%);
}
.smallLine(
background-size: 10px 10px;
}
.circle(
position: absolute;
width: 630px;
height: 20px;
background: radial-gradient(16px, transparent, transparent 4px, black 4px, black 10px, transparent 11px);
background-size: 30px 40px;
}
.circle2 (
top: 20px;
left: 15px;

}
.ellipse(
position: absolute;
background: radial-gradient(ellipse, transparent, transparent 7px, black 7px, black 10px, transparent 11px);
background-size: 36px 40px;
width: 630px;
height: 20px;
}
.ellipse2 (
top: 20px;
left: 18px;
background-position: 0px -20px;
}

Here we used such features as linear-gradient and radial-gradient from the css3 arsenal.
There is another option for using a dividing line in the form of a wave (the lowest one in the illustration at the beginning of the post). It can be used at the end of a block, like bottom decoration. The code is quite simple. First html:

IN css rules Let's use the pseudo-elements:before and:after . You can read about them. This is what the code will look like:

Wave(
width: 630px;
background: #333;
height: 30px;
position: relative;
}
.wave::before(
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
background-repeat: repeat;
height: 10px;
background-size: 20px 20px;
background-image:
radial-gradient(circle at 10px -5px, transparent 12px, #19d1ff 13px);
}
.wave::after(
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
background-repeat: repeat;
height: 15px;
background-size: 40px 20px;
background-image:
radial-gradient(circle at 10px 15px, #19d1ff 12px, transparent 13px);
}

That's all! Go for it!

From the author: Styling link underlines is quite tricky, and I keep forgetting which method is best in which situation. Fortunately, John Jameson will help us quickly understand this in his article.

There are many ways to style underlines. You may remember the article “Creating Link Underlines on Medium”. Medium wasn't trying to do anything out of the ordinary, they just wanted to create attractive underlines in the text.

Thin, black underlines with spaces around letters with bottom callouts – work by Marcine Witchery from the article Creating Link Underlines on Medium.

A good standard underline that is also a good size and allows for descenders. Much better than most browsers default. As it turns out, Medium faced a lot of challenges along the way. And even two years later, good underline styling still causes a lot of problems.

Goals

Why not just use text-decoration: underline? If we're talking about an ideal scenario, the underscores should:

be located below the baseline;

skip lower letters;

change color, thickness and styles;

go to new line;

work with any background.

I think it's entirely possible for us to require all of these things from underscores, but as far as I know there is no intuitive way to do all of these things in CSS.

Approaches

So what methods do we have at our disposal to underline text? I remembered the following:

text-decoration;

background-image;

SVG filters;

Underline.js(canvas);

text-decoration-*

Let's go through the entire list and consider all the pros and cons of each approach.

text-decoration property

The text-decoration property is the simplest way to underline text. You only need to apply one property. On small text, such a line will look fine, but if you increase the font size, it will look awkward.

The biggest problem with the text-decoration property is the lack of customization. The line uses the color and font size of the text it is applied to, and there is no cross-browser way to change styles. We'll talk in more detail about this property a little later.

pros

easy to use;

located below the baseline;

skips descenders by default in Safari and iOS;

jumps to a new line;

works with any background.

Minuses

does not skip descenders of letters in other browsers;

Color, thickness and styles cannot be changed.

border-bottom property

The border-bottom property is a good balance of speed and customization. This approach uses proven CSS frames, which means you can easily change colors, thicknesses and styles. This is what the border-bottom property looks like on inline elements:

The biggest downside is how far the underline is from the text. The underline is located below the descenders of the letters. This problem It can be solved if you make the element inline-block and reduce the line-height, but then you lose the ability to jump to new lines. Good for single lines, but no more.

You can also use text-shadow to hide parts of the line around the bottom callouts. In this case, you will have to imitate the background color, which means that the method only works on uniform backgrounds. Gradients and images will not work.

On this moment There are 4 properties for styling underline. Much better than just text-decoration.

pros

you can use the transition property and animate the color and thickness;

jumps to new lines by default if the element is not inline-block;

Minuses

the line is located very far away and is difficult to move;

too many unnecessary properties need to be used to make the underline look good;

Poor text highlighting when using text-shadow.

box-shadow property

The box-shadow property draws an underline using two inner shadows: one that creates the rectangle, and one that hides it. This means that for the method to work correctly, a uniform background is needed.

The same text-shadow trick can be used to simulate skipping around the bottom callouts of letters. If the line color is different from the text, or it is thin enough, then there should be no problems, as is the case with text-decoration.

pros

can be placed below the baseline;

you can skip callouts using text-shadow;

you can change the color and thickness;

jumps to new lines.

Minuses

styles cannot be changed;

Doesn't work with all backgrounds.

background-image property

The background-image property solves our problems best of all, and it has very few disadvantages. The idea is that you create an image using linear-gradient and background-position that repeats on a horizontal axis along lines of text. The element must be display: inline;.

The demo below does not use linear-gradient. To create a cool effect, you can use your own image.

pros

can be positioned below the baseline;

you can skip bottom callouts using text-shadow;

you can change color, thickness (even by half a pixel) and styles;

works with custom images;

jumps to new lines;

works with any background as long as you don't use text-shadow.

Minuses

Image size may vary depending on resolution, browser and zoom level.

SVG filters

This is the method I played with. You can create an inline SVG filter element that will draw the line, and expand the text to mask out parts of the line that should be transparent. The filter can be given an id and referenced in CSS using filter: url(‘#svg-underline’).

What's great about this is that the filter adds transparency without relying on text-shadow. This means you can skip letter balloons on any background, including gradients and images! The example below only works with one line of text, so be careful.

And this is how it looks in Chrome and Firefox:

There are support issues in IE, Edge and Safari. It's difficult to test support for SVG filters in CSS. You can use the @supports rule on filter, but this will only check whether the link itself works, and not whether the filter is applied or not. My method is quite rough on browsers, so be doubly careful.

pros

located below the baseline;

skips bottom leaders;

You can change color, thickness and styles;

works on any background.

Minuses

does not jump to new lines;

does not work in IE, Edge and Safari, but you can specify text-decoration as a fallback. Underlines in Safari look great on their own.

Underline.js (Canvas)

Underline.js is an amazing library. I'm impressed with what Wenting Zhang were able to do with JS and attention to detail. If you haven't seen the Underline.js tech demo yet, stop for a minute and take a look. There is a wonderful nine-minute speech online on the principles of work, I’ll quickly retell it to you now. The underlines are drawn using canvas. A completely new approach that works surprisingly well.

Despite the attractive name, this is just a technical demo. That is, you won't be able to immediately put the library into the project without a whole bunch of changes.

This library is worth mentioning only as a proof of concept. Canvas has the potential to create beautiful, interactive highlights, but you'll have to write extra JS code to get it to work properly.

Properties text-decoration-*

Remember when I said we'd go into more detail on something a little later? Now let's do this. The text-decoration property works well on its own, but we can add a couple of experimental properties for added value. best view:

text-decoration-color

text-decoration-skip

text-decoration-style

Don’t rejoice ahead of time, you know about browser support.

text-decoration-color property

The text-decoration-color property allows you to change the underline color separately from the text color. The property even has good browser support. It works in Firefox and prefixed in Safari. There is a downside - if you don't clear the line around the callouts, in Safari it will lie on top of the text. Firefox:

text-decoration-skip property

The text-decoration-skip property is responsible for skipping footer balloons in underlined text.

The property is non-standard and currently only works in Safari. To work in other browsers you need to use the –webkit- prefix. In Safari, this property is enabled by default, which is why underscores skip footers even on sites where this property is not specified.

If you are using Normalize, you need to know that latest versions disable the property for normal operation in all browsers. If you want those almost magical underscores back, you need to enable this property.

text-decoration-style property

The text-decoration-style property offers the same set of underlines as the border-style property, but also adds the new kind– wavy. Possible values:

Right now the text-decoration-style property only works in Firefox, below is a screenshot:

Set of monochromatic underlines Look similar?

What's wrong?

The text-decoration-* properties are more intuitive than other properties for styling underlines. However, if you take a different look at the requirements that we presented earlier, you will notice that using these properties you cannot change the thickness and position. After a little research I found these two properties:

text-underline-width

text-underline-position

It looks like these properties were dropped from an early version of CSS due to lack of interest in them. They were never used. Hey, it's not my fault.

conclusions

So what's the best way to underline text? It all depends on various factors.

For small text, I recommend using text-decoration and the experimental text-decoration-skip property, hoping it will work. In most browsers it looks so-so, but it has always been like this, and people did not pay attention to it. If you're patient enough, chances are that soon all your underlines will look good without you having to change a thing.

For body text, use background-image. The method works, looks beautiful, and there are Sass mixins for it. If the underline is thin, or the color is different from the text, you can likely skip the text-shadow method. For text on one line, use border-bottom and any other properties.

And to skip letter callouts on gradient backgrounds or images, try using an SVG filter. Or just don’t mix such backgrounds with underlines. In the future, when browser support improves, it will be possible to use the text-decoration-* properties.

There is underlining different types, accordingly, the methods of its creation differ. Listed below are a few popular ones.

Using text-decoration

The text-decoration property with the value underline adds an underline to the text; This kind of underlining can be observed for default links. The line created in this way is equal to the width of the text and will be the same color as the title itself. You can change the line color through the text-decoration-color property. Example 1 shows applying text-decoration to an element

.

Example 1: Using text-decoration

Underscore

Result this example shown in Fig. 1.

Rice. 1. View of a line created via text-decoration

IE and Edge browsers do not support the text-decoration-color property.

Using border-bottom

Property border-bottom adds a line of specified thickness, color, and style to the element below. Such a line occupies the entire available width, despite the length of the title text (Fig. 2).

Rice. 2. View of a line created with border-bottom

The distance from the line to the text can be adjusted using the property padding-bottom, as shown in example 2.

Example 2: Using border-bottom

Underscore

Cultural speech act in the 21st century

Indeed, myth-generating text device illustrates the discourse, and this gives it its own sound, its own character.

To make the line the width of the text, just turn the title into an inline block element by adding the h2 property to the selector display with the value inline-block .

Using::after and content

You can also make an artificial line through a property combination content and pseudo element ::after. They will only display an empty pseudo-element after the title, and the appearance of this pseudo-element is determined by other properties. In Fig. 3 shows a similar line.

Rice. 3. Line created via::after

The position of such a line relative to the text is specified through the property bottom with a negative value, line color via property background. In fact, this is not a line, but a rectangular block, so we use a background fill (example 3).

Example 3: Using::after

Underscore

Cultural speech act in the 21st century

Indeed, the myth-generating textual device illustrates the discourse, and this gives it its own sound, its own character.

There is a bunch different ways underlining design. You may remember Marcin Vichari's article “Crafting link underlines” on Medium. The Medium developers aren't trying to do anything crazy, they just want to create a nice line under the text.

This is the simplest underscore, but it has right size and it does not overlap letter extensions. And it is definitely better than the default underscore in most browsers. Medium had to face challenges to achieve its style on the web. Two years later, we still find it difficult to create beautiful underlining.

Goals

What's wrong with the usual text-decoration: underline ? In an ideal scenario, the underscore should do the following:

  • position below the baseline;
  • skip callouts;
  • change the color, thickness and style of the line;
  • to Work with multiline text;
  • work on any background.

I believe these are all reasonable requirements, but as far as I know there is no intuitive way to achieve this with using CSS.

Approaches

So what is this various ways, which we can use to implement underlining on the web?

Here are the ones I'm considering:

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

Let's look at these methods one by one and talk about the pros and cons of each of them.

text-decoration

text-decoration is the most obvious way to underline text. You apply one property and that's enough. At small font sizes this may look fine, but increase the font size and the underlining starts to look awkward.

The biggest problem with text-decoration is the lack of customization. You are limited to the color and font size of the text and there is no cross-browser way to change this. We'll talk about this in more detail later.

  • easy to use;
  • positioned below the baseline;
  • skips callouts by default in Safari and iOS;
  • emphasizes multiline text;
  • works on any background.
  • does not skip footers in all other browsers;
  • does not allow you to change the color, thickness or style of the line.

border-bottom

border-bottom strikes a good balance between simplicity and customizability. This approach uses the good old CSS border property, meaning you can easily change the color, thickness, and style.

This is what border-bottom looks like for inline elements.

Main disadvantage- this is the distance of the underline from the text, it is entirely below the callout elements. You can fix this by setting the elements to inline-block and decreasing the line-height , but then you'll lose the ability to wrap text. Good for individual lines, but not suitable anywhere else.

Additionally, we can use text-shadow to obscure the portion of the line next to the inline elements, simulating this by using the same color as the background. That is, this technique only works on a simple single-color background, without gradients, patterns or images.

At the moment, we are already using as many as four properties to design one line. It's a lot more work than just adding text-decoration.

  • can skip callouts using text-shadow ;
  • can change color, weight and line style;
  • allows you to use transitions and animations of color and boldness;
  • works with multiline text unless inline-block is applied;
  • Works on any background as long as you don't use text-shadow .
  • positioned too low and moves in a complicated way;
  • many additional properties are used for proper operation;
  • when using text-shadow, highlighting text looks ugly.

box-shadow

box-shadow draws a subline using two inner shadows: one creates a rectangle, and the second hides part of it. This means you need a solid color background for this to work.

You can use the same trick with text-shadow to fill in the gaps between underlines and callouts. But if the underline color is different from the text color - or it's just thin enough - the line won't collide with callouts as much as it would with text-decoration .

  • allows you to change the color and thickness of the line;
  • works with multiline text.
  • does not allow you to change the underline style;
  • Doesn't work on any background.

background-image

The background-image method is closest to what we want and has the least amount of drawbacks. The idea is to use linear-gradient and background-position to create an image that repeats under lines of text.

For this approach to work, the text must be in standard display: inline; .

The next option does without linear-gradient , for effects you can add your own background image.

  • can be positioned below the baseline;
  • can skip callout elements using text-shadow ;
  • works with custom images;
  • wraps multiple lines of text;
  • Works on any background as long as you don't use text-shadow .
  • Image size may vary depending on screen resolution, browser and magnification.

SVG filters

I've played with this method quite a bit. You can create an SVG line filter that draws a line and then expands the text to mask out the part of the line that we want to be transparent. You can then give the filter an id and reference it in CSS something like filter: url('#svg-underline') .

The benefit of this approach is that transparency is achieved without using text-shadow , meaning we let callouts appear on any background, including gradients and background images! This only works on a single line of text, so keep that in mind.

Here's what it looks like in Chrome and Firefox:

Support in IE, Edge and Safari is problematic. It's difficult to test SVG filter support in CSS. You can use the @supports directive with filter , but this will only check the functionality of the filter reference, not the functionality of the filter itself. My attempts ended in a tedious determination of the browser's capabilities; this is a noticeable drawback of the method.

  • can be positioned below the baseline;
  • can skip extension elements;
  • allows changes in line color, thickness and style;
  • works on any background.
  • does not work with multiline text;
  • doesn't work in IE, Edge and Safari, but you can use text-decoration as a fallback, it looks decent in Safari.

Underline.js (Canvas)

Underline.js is fascinating. I find it impressive what Wenting Zhang has accomplished with her command of JavaScript and attention to detail. If you haven't seen the Underline.js tech demo, stop reading and give it a minute. There's also a nine-minute talk from her on how it works, but I'll keep it short: The underline is drawn using elements . This is a new approach that works surprisingly well.

Despite the catchy name, Underline.js is just a technical demo. This means that you can't just plug it into your project without changing the code.

I thought I'd mention this as a proof of concept that has the potential to create great interactive underlines, but you need to write your own JavaScript to make it work.

New text-decoration properties

You remember that I promised to talk more about text-decoration. The time has come.

This property works great on its own, but you can add some experimental properties to customize the appearance of the underline.

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

But don't get too excited... Browser support is as always. So it goes.

text-decoration-color

The text-decoration-color property allows you to change the underline color separately from the text color. Support for this property is better than you might expect - it works in Firefox and with the prefix in Safari. Here's the catch: if you have callouts, Safari will place an underline on top of the text.

text-decoration-skip

The text-decoration-skip property enables skipping of callouts in underlined text.

This property is non-standard and currently only works in Safari, with the -webkit- prefix. Safari enables this property by default, so callouts are not always struck through.

If you use Normalize, please note that recent versions disable this property for the sake of consistent browser behavior. And if you want the underline to not affect callouts, you need to manually activate it.

text-decoration-style

The text-decoration-style property offers the same styling options as the border-style property, with the addition of a wavy style.

Here is a list of available values:

  • dashed
  • dotted
  • double
  • solid

Currently the text-decoration-style property only works in Firefox, here is a screenshot from it:

What is missing

The text-decoration-* series of properties are much more intuitive to use than other CSS underline decoration properties. But if we take a closer look, there are not enough ways to set the thickness or position of the line to satisfy our needs.

After a little research, I found a couple more properties:

  • text-underline-width
  • text-underline-position

These appear to be early drafts of CSS, but were never implemented in browsers due to lack of interest.

conclusions

So what's the best way to underline?

For small text, I recommend using text-decoration with optimistically adding text-decoration-skip . It looks a little tacky in most browsers, but underlining has always been like this in browsers and people just won't notice. Plus, there's always a chance that, if you have patience, that underline will look good someday without you having to change anything the way browsers do.

For body text it makes sense to use background-image . This approach works, looks great, and there are Sass mixins for it. You can, in principle, skip text-shadow if the underline is thin or a different color from the text.

For single lines of text, use border-bottom along with any additional properties.

And if you need callouts to pop against a gradient or image background, try using SVG filters. Or just avoid using underscores.

In the future, when browser support gets better, the only answer will be the text-decoration-* property set.

I also recommend taking a look at Benjamin Woodroffe's article CSS Underlines Suck, which addresses the same issues.

Allows you to create different underlines in HTML: underline, overline, line-through text, etc. Let's combine this feature with the previous one and get:

The second line shows how everything is written in one row with text-decoration.

text-decoration-style — text underlining style

The option specifies appearance decorative line for /link. The new CSS guidelines have added wavy and double values, so there are now 5 of them:

  • solid - solid line;
  • double - double (from the first example above);
  • dotted - consists of a sequence of dots;
  • dashed - allows you to create a dashed CSS underline;
  • wavy - a spectacular wavy line.

text-underline-position - CSS underline positioning

Using this property, you can control the position of the line relative to the font glyph.
A total of 4 options are available:

  • auto — is located as close as possible to the text baseline;
  • under - below the lowest border of the font;
  • left and right - left/right for posts displayed vertically.

Here is a visual difference between underlining text using under and auto:

The difference, I think, is quite obvious.

text-decoration-skip - remove underlining for elements

Using the option, you can cancel (skip) the decoration of some elements in the HTML line. To better understand the acceptable values ​​of spaces, objects, box-decoration, edges, ink, I will duplicate the picture from the previous note:

That is, for example, using ink you can make an underscore in CSS that would not intersect with the characters. The value of objects allows you to skip inline elements (inline-block) - insert a span, and the solid line will break at the appropriate place:

The box-decoration, spaces, edges parameters are much less well supported by browsers, so their results sometimes differ from the expected ones. Here is the status of text-decoration compatibility/support at the time of writing:

Additional tricks for underlining links

Beginner users often ask some typical questions on the topic, so we also decided to consider them. General example is at the very bottom after the explanations.

How to remove link underline

a:hover ( text-decoration: underline; )

Both examples below allow you to understand the logic of how hover works: either you initially specify link underlining in the CSS, and then remove it in the hover, or vice versa.

If you have any other questions on the topic, ask them in the comments. We'll try to look into it later or give you some hints in the answers. The main thing in this matter is practice - try adding different properties for the text-decoration option directly in the examples or create your own test file. We hope everything has become clear on the topic of underlining text and links in CSS / HTML.