Using CSS, when text has text-decoration:underline
applied, is it possible to increase the distance between the text and the underline?
-
2This is not exactly what you were asking for, but it was an interesting read on the subject: [CSS Design: Custom Underlines](http://www.alistapart.com/articles/customunderlines/) – Peter Rowell Nov 14 '09 at 15:53
-
The distance is determined by a font used. Try web-safe fonts. – Alexei Danchenkov Sep 12 '14 at 04:22
-
5CSS3 has a lot of new text-decoration properties these days. Please check out alligator.io/css/text-decoration Example: `text-underline-position: under;` and `text-decoration-skip: ink;` Please note that this is probably not backward compatible with older browsers. – chocolata Oct 24 '17 at 14:08
-
2Another [good solution](https://stackoverflow.com/a/8037837/3452348) – w3spi Jul 14 '18 at 12:35
-
6Vote for `text-underline-offset` here: https://bugs.chromium.org/p/chromium/issues/detail?id=785230&q=text-underline-offset&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified – Mark Fisher Dec 03 '19 at 14:04
-
Just add `text-underline-position: under;` – Parth Developer Dec 06 '22 at 19:50
-
1`text-underline-offset` now works. – manojadams Apr 08 '23 at 07:20
18 Answers
No, but you could go with something like border-bottom: 1px solid #000
and padding-bottom: 3px
.
If you want the same color of the "underline" (which in my example is a border), you just leave out the color declaration, i.e. border-bottom-width: 1px
and border-bottom-style: solid
.
For multiline, you can wrap you multiline texts in a span inside the element. E.g. <a href="#"><span>insert multiline texts here</span></a>
then just add border-bottom
and padding
on the <span>
- Demo
-
3My only problem with this trick is when I am using line-height equal to the div height and then vertical-align: middle; to get it centered, then i can't use this trick because then the underline ends up below the div. – deweydb Nov 16 '12 at 23:55
-
@deweydb: How about adding the padding-bottom to the container div as well? http://jsfiddle.net/dYfjc/1/ – chelmertz Nov 17 '12 at 15:32
-
+1 I didn't know about leaving off the color property to inherit the font's color - that'll save much sweat and tears in future! – Larry Jul 08 '13 at 12:52
-
-
border-bottom sometimes expands beyond the width of the text. you can add display: inline-block to your anchor element to fix this. – Leandri Jul 18 '14 at 14:23
-
26I am pretty not sure why this answer has so many upvotes. This doesn't completely work with multiline texts. – Jul 17 '15 at 15:46
-
It also works badly if you already have a padding in the tag and has no freedom to modify it. – Anders Lindén Dec 02 '15 at 15:26
-
-
The text-shadow is not applied to the border, which is an issue for me. – Etienne Dupuis May 18 '16 at 17:29
-
3For multiline, you can wrap you multiline texts in a span inside the element. E.g. `insert multiline texts here` then just add border-bottom and padding on the ``. https://jsfiddle.net/Aishaterr/vrpb2ey7/1/ – Daniel Hernandez Nov 08 '16 at 11:42
-
@Aishaterr very nice, I think your code is much prettier than the others. If you wish, you could edit this answer to include your exact comment (the jsfiddle helps a lot when conveying people :)) – chelmertz Nov 08 '16 at 14:16
-
To look more like under line, we can add padding-left:2px and padding-right:2px So that line get extra width under the text. Thanks to the author for solution. – zawhtut Dec 16 '21 at 03:50
Update 2021:
text-underline-offset
now works in almost all major and newest versions of browsers (IE11 is a no-go): https://caniuse.com/?search=text-underline-offset
Update 2019: The CSS Working Group has published a draft for text decoration level 4 which would add a new property text-underline-offset
(as well as text-decoration-thickness
) to allow control over the exact placement of an underline. As of this writing, it's an early-stage draft and has not been implemented by any browser, but it looks like it will eventually make the technique below obsolete.
Original answer below.
The problem with using border-bottom
directly is that even with padding-bottom: 0
, the underline tends to be too far away from the text to look good. So we still don't have complete control.
One solution that gives you pixel accuracy is to use the :after
pseudo element:
a {
text-decoration: none;
position: relative;
}
a:after {
content: '';
width: 100%;
position: absolute;
left: 0;
bottom: 1px;
border-width: 0 0 1px;
border-style: solid;
}
By changing the bottom
property (negative numbers are fine) you can position the underline exactly where you want it.
One problem with this technique to beware is that it behaves a bit weird with line wraps.

- 10,865
- 2
- 33
- 44

- 4,481
- 1
- 21
- 19
-
2
-
13Good work around, but this will not work for anchors that span multiple lines – Willster May 13 '13 at 15:53
-
@last-child This one is better than underline, but with text wrap this would not work for every line – Nishantha Apr 18 '15 at 04:20
-
One problem is that a border-bottom and underlining are two different things. For instance should part of the text extend below the underline. If you style a-tags as buttons, you have no freedom of using border-bottom as underlining. – Anders Lindén Dec 02 '15 at 15:28
-
-
33Imagine telling someone who is either new to web development, a graphic designer, an average user, or your mom, that this is what's required to add some controlled space between text and it's underline and they will wonder what you're doing with your life. – MarcGuay May 26 '16 at 21:45
-
I was able to control the distance of the border by using `line-height`. It was on a `
` so I used `inline-block` as well
– Eoin Dec 08 '18 at 00:44 -
3Thanks for the update. As of August 2020, `text-underline-offset` works beautifully in Safari and Firefox. (Chrome didn't get the memo apparently.) – Kal Aug 06 '20 at 02:16
-
10`text-underline-offset` has been recently added to Chrome and Edge. What a time to be alive! – MrSegFaulty Jan 29 '21 at 12:31
You can use this text-underline-position: under
See here for more detail: https://css-tricks.com/almanac/properties/t/text-underline-position/
See also browser compatibility.

- 142,137
- 41
- 261
- 360

- 1,467
- 1
- 9
- 12
-
2Thanks! If you are trying to do a dashed underline and see that it is drawn without space between the bottom of the text and the line, then this fixes the issue. – Jonathan Cross May 12 '17 at 18:36
-
7This is the correct answer for modern browsers without any workaround. – Paras Shah Sep 28 '17 at 13:36
-
2It does not work in Firefox, not even with vendor-prefix - but it IS in a W3C spec: https://www.w3.org/TR/css-text-decor-3/#text-underline-position-property. Other relevant resource: https://www.quackit.com/css/css3/properties/css_text-underline-position.cfm – rosell.dk Feb 23 '18 at 07:43
-
Great find! I look at this as that we should use it now until the other browsers catch up on the spec. For those who don't have it, they'll just get a less than desirable appearance, but not too terribly bad. – Volomike Feb 23 '18 at 21:45
-
This is the real answer. Using `borders` will only work on one-lines, you will see the problem with multilines. – JohnnyQ Mar 05 '18 at 03:44
-
4As of this moment, this only really works in the chrome browser, and is not a solution for other browsers. – miir Mar 08 '18 at 00:13
-
Unfortunately only Chrome supports this https://caniuse.com/#search=text-underline-position – Oleg Dec 10 '19 at 13:42
-
5Well, as of the date of this comment, I see this **works in Firefox** too. – Jarad May 01 '20 at 02:50
-
Chrome is having issues rendering this in some instances *for me*. Looks like it's generally poorly tested. Yes it works initially, but with additional hover styling, the underline will sometimes get cut in half or disappear completely, seemingly undeterministically. – Filip Kilibarda Oct 12 '20 at 22:48
-
1Perfect, Other answers are far too cumbersome.This should be marked as correct answer. – user3286381 May 03 '21 at 22:30
Use
{
text-decoration: underline;
text-underline-offset: 2px;
}
Here, text-underline-offset: 2px; is used to define the distance of the underline from the text, where "2px" is the distance.
Note: text-underline-offset: 2px; can only be used after
text-decoration: underline;
You can also change the thickness of underline by writing
text-decoration: underline 5px;
where "5px" is the thickness.
Refer this link for further query: https://developer.mozilla.org/en-US/docs/Web/CSS/text-underline-offset

- 101
- 6

- 747
- 6
- 5
-
4Welcome to Stack Overflow. Code-only answers are discouraged on Stack Overflow because they don't explain how it solves the problem. Please edit your answer to explain what this code does and how it improves on the many other upvoted answers this question has already, so that it is useful to other users with similar issues – FluffyKitten Aug 27 '20 at 02:14
-
3There's no chrome support for this. https://caniuse.com/?search=text-underline-offset – john-raymon Oct 15 '20 at 10:12
-
errrr yes - as explanation .... `text-underline-offset: 2px` sets the text underline to an offset of 2px... in case someone doesn't understand. Chrome supports as well now. – Toskan Jan 13 '21 at 03:31
-
This should be the accepted answer because it works well even in 2022. It is currently supported by Chrome, Edge, Opera. – AnatuGreen Jun 05 '22 at 09:03
Here is what works well for me.
<style type="text/css">
#underline-gap {
text-decoration: underline;
text-underline-position: under;
}
</style>
<body>
<h1 id="underline-gap"><a href="https://Google.com">Google</a></h1>
</body>

- 1,069
- 1
- 12
- 20

- 740
- 1
- 7
- 18
-
2It is important to note that `text-underline-position` is not supported under Firefox as per https://developer.mozilla.org/en-US/docs/Web/CSS/text-underline-position#Browser_compatibility – Floran Gmehlin Jun 05 '19 at 10:04
-
-
1
Getting into the details of the visual style of text-decoration:underline
is pretty much futile, so you're going to have to go with some kind of hack the removes text-decoration:underline
and replaces it with something else until a magical far-distant future version of CSS gives us more control.
This worked for me:
a {
background-image: linear-gradient(
180deg, rgba(0,0,0,0),
rgba(0,0,0,0) 81%,
#222222 81.1%,
#222222 85%,
rgba(0,0,0,0) 85.1%,
rgba(0,0,0,0)
);
text-decoration: none;
}
<a href="#">Lorem ipsum</a> dolor sit amet, <a href="#">consetetur sadipscing</a> elitr, sed diam nonumy eirmod tempor <a href="#">invidunt ut labore.</a>
- Adjust the % values (81% and 85%) to change how far the line is from the text
- Adjust the difference between the two % values to change the line thickness
- adjust the color values (#222222) to change the underline color
- works with multiple line inline elements
- works with any background
Here's a version with all the proprietary properties for some backwards compatibility:
a {
/* This code generated from: http://colorzilla.com/gradient-editor/ */
background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 81%, rgba(0,0,0,1) 81.1%, rgba(0,0,0,1) 85%, rgba(0,0,0,0) 85.1%, rgba(0,0,0,0) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(81%,rgba(0,0,0,0)), color-stop(81.1%,rgba(0,0,0,1)), color-stop(85%,rgba(0,0,0,1)), color-stop(85.1%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 81%,rgba(0,0,0,1) 81.1%,rgba(0,0,0,1) 85%,rgba(0,0,0,0) 85.1%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 81%,rgba(0,0,0,1) 81.1%,rgba(0,0,0,1) 85%,rgba(0,0,0,0) 85.1%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 81%,rgba(0,0,0,1) 81.1%,rgba(0,0,0,1) 85%,rgba(0,0,0,0) 85.1%,rgba(0,0,0,0) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 81%,rgba(0,0,0,1) 81.1%,rgba(0,0,0,1) 85%,rgba(0,0,0,0) 85.1%,rgba(0,0,0,0) 100%); /* W3C */
text-decoration: none;
}
Update: SASSY version
I made a scss mixin for this. If you don't use SASS, the regular version above still works great...
@mixin fake-underline($color: #666, $top: 84%, $bottom: 90%) {
background-image: linear-gradient(
180deg, rgba(0,0,0,0),
rgba(0,0,0,0) $top,
$color $top + 0.1%,
$color $bottom,
rgba(0,0,0,0) $bottom + 0.1%,
rgba(0,0,0,0)
);
text-decoration: none;
}
then use it like so:
$blue = #0054a6;
a {
color: $blue;
@include fake-underline(lighten($blue,20%));
}
a.thick {
color: $blue;
@include fake-underline(lighten($blue,40%), 86%, 99%);
}
Update 2: Descenders Tip
If you have a solid background color, try adding a thin text-stroke
or text-shadow
in the same color as your background to make the descenders look nice.
Credit
This is simplified version of the technique I originally found at https://eager.io/app/smartunderline, but the article has since been taken down.

- 525
- 1
- 6
- 25

- 4,894
- 3
- 34
- 45
-
Unfortunately the eager.io link doesn't work anymore. Do you recall what was the hack to make descenders look nicer? – kano May 21 '17 at 11:02
-
1@Kano - I believe it was using text-shadow in the same color as a solid background. – squarecandy May 21 '17 at 15:54
-
Also, with the technique above you can set the color of the underline different from the text, so sometimes I set it to be lighter than the text, which makes collisions with the descenders less of a problem for readability. – squarecandy May 21 '17 at 16:00
There is a easy very answer for this:
text-decoration: underline;
text-underline-offset: 3px;
text-underline-offset
is css it's own method.
Here is more about text-underline-offset

- 15,447
- 5
- 79
- 98

- 327
- 3
- 4
I know it's an old question, but for single line text setting display: inline-block
and then setting the height
has worked well for me to control the distance between a border and the text.

- 2,284
- 2
- 27
- 46
-
1I didn't need to set the height. I just wrapped it in another div and as I wanted it to be centered I just set the text-align on the out div. – Guy Lowe Feb 09 '15 at 02:26
@last-child's answer is a great answer!
However, adding a border to my H2 produced an underline longer than the text.
If you're dynamically writing your CSS, or if like me you're lucky and know what the text will be, you can do the following:
change the
content
to something the right length (ie the sametext) set the font color to
transparent
(orrgba(0,0,0,0)
)
to underline <h2>Processing</h2>
(for example),
change last-child's code to be:
a {
text-decoration: none;
position: relative;
}
a:after {
content: 'Processing';
color: transparent;
width: 100%;
position: absolute;
left: 0;
bottom: 1px;
border-width: 0 0 1px;
border-style: solid;
}

- 410
- 4
- 10
-
9H2s are block elements which might explain why the underline was longer than the text. Maybe `display: inline-block` would fix it. Replacing the text with `content` looks like a hack that could break in many ways. – last-child Jun 17 '13 at 10:54
See my fiddle.
You would need to use the border width property and the padding property. I added some animation to make it look cooler:
body{
background-color:lightgreen;
}
a{
text-decoration:none;
color:green;
border-style:solid;
border-width: 0px 0px 1px 0px;
transition: all .2s ease-in;
}
a:hover{
color:darkblue;
border-style:solid;
border-width: 0px 0px 1px 0px;
padding:2px;
}
<a href='#' >Somewhere ... over the rainbow (lalala)</a> , blue birds, fly... (tweet tweet!), and I wonder (hmm) about what a <i><a href="#">what a wonder-ful world!</a> World!</i>

- 7,681
- 17
- 73
- 127

- 999
- 3
- 12
- 24
If you want:
- multiline
- dotted
- with custom bottom padding
- without wrappers
underline, you can use 1 pixel height background image with repeat-x
and 100% 100%
position:
display: inline;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAAEUlEQVQIW2M0Lvz//2w/IyMAFJoEAis2CPEAAAAASUVORK5CYII=') repeat-x 100% 100%;
You can replace the second 100%
by something else like px
or em
to adjust the vertical position of the underline. Also you can use calc
if you want to add vertical padding, e.g.:
padding-bottom: 5px;
background-position-y: calc(100% - 5px);
Of course you can also make your own base64 png pattern with another color, height and design, e.g. here: http://www.patternify.com/ - just set square width & height at 2x1.
Source of inspiration: http://alistapart.com/article/customunderlines

- 1,389
- 15
- 32
This is what i use:
html:
<h6><span class="horizontal-line">GET IN</span> TOUCH</h6>
css:
.horizontal-line { border-bottom: 2px solid #FF0000; padding-bottom: 5px; }
An alternative for multiline texts or links, you can wrap your texts in a span inside a block element.
<a href="#">
<span>insert multiline texts here</span>
</a>
then you can just add border-bottom and padding on the <span>
.
a {
width: 300px;
display: block;
}
span {
padding-bottom: 10px;
border-bottom: 1px solid #0099d3;
line-height: 48px;
}
You may refer to this fiddle. https://jsfiddle.net/Aishaterr/vrpb2ey7/2/

- 229
- 1
- 8
I was able to Do it using the U (Underline Tag)
u {
text-decoration: none;
position: relative;
}
u:after {
content: '';
width: 100%;
position: absolute;
left: 0;
bottom: 1px;
border-width: 0 0 1px;
border-style: solid;
}
<a href="" style="text-decoration:none">
<div style="text-align: right; color: Red;">
<u> Shop Now</u>
</div>
</a>

- 3,868
- 8
- 27
- 32

- 9,489
- 8
- 74
- 87
What I use:
<span style="border-bottom: 1px solid black"> Enter text here </span>

- 27,060
- 21
- 118
- 148

- 71
- 1
- 3
There are some great solutions here but each one has some issues. The text-underline-offset is different for each browser. The answer by squarecandy also works, however is a little complicated. Using the border-bottom changes the layout of the text and will shift things over.
One solution for adding a custom underline is to make the underline a background image, that is sized relevant to the text size.
a {
/* Change the source image to account for changes to the text colour. It should be a single column. */
background-image: url(data:image/png;base64,iVBORw__EDITED_OUT___0KGgYII=);
/*background-image: url('underlineImage.png');*/
background-size: 1px 1.1em;
background-repeat: repeat-x;
display: inline;
cursor: pointer;
text-decoration: none;
}
As the text increases, the position remains relative to the text size. With this, you can have any underline image you want such as "a row of stars", or just a line.
The example above does not include the full base64 information to create the effect. This works great across all the browsers since it's a fundamental thing and is pretty compatible with older browsers.
<a href="#">This _____ is the link</a>
If the background image is a png with transparency, it works great on top of other elements.

- 1,773
- 1
- 14
- 18
You can do that by using :
text-underline-position: under;
text-underline-offset: {value(px)};
This property will shift the underline, that's below your link by the value of offset that you provided.
For more references, visit: text-underline-offest | developer.mozilla.org

- 167
- 2
- 9