How to increase the gap between text and underlining in CSS

0 votes
asked Nov 14, 2009 by maxp

Using CSS, when text has text-decoration:underline applied, is it possible to increase the distance between the text and the underline?

11 Answers

0 votes
answered Nov 14, 2009 by chelmertz

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

0 votes
answered Nov 5, 2012 by last-child

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.

0 votes
answered Nov 16, 2013 by michael-greisman

@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:

  1. change the content to something the right length (ie the same

  2. text) set the font color to transparent (or rgba(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;
}
0 votes
answered Nov 24, 2013 by dominic-p

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.

0 votes
answered Nov 19, 2015 by stardust

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>
0 votes
answered Nov 21, 2015 by squarecandy

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;
}
  • 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.

0 votes
answered Nov 3, 2016 by mcmimik

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

0 votes
answered Nov 8, 2016 by constantinos-constan

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; }
0 votes
answered Nov 9, 2016 by daniel-hernandez

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/

0 votes
answered Nov 17, 2016 by edathadan-chief-aka-

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>
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...