Hover effect : expand bottom border

CssBorderCss TransitionsCss Transforms

Css Problem Overview


I'm trying to get a transition hover effect on border that the border expands on hover.

h1 {
  color: #666;
}

h1:after {
  position: absolute;
  left: 10px;
  content: '';
  height: 40px;
  width: 275px;
  border-bottom: solid 3px #019fb6;
  transition: left 250ms ease-in-out, right 250ms ease-in-out;
  opacity: 0;
}

h1:hover:after {
  opacity: 1;
}

<h1>CSS IS AWESOME</h1>

I've tried this on Jsfiddle

Css Solutions


Solution 1 - Css

To expand the bottom border on hover, you can use transform:scaleX'(); (mdn reference) and transition it from 0 to 1 on the hover state.

Here is an example of what the border hover effect can look like : Expand border hover effect

The border and transition are set on a pseudo element to prevent transitioning the text and avoid adding markup.
To expand the bottom border from left or right, you can change the transform-origin property to the left or right of the pseudo element:

h1 { color: #666;display:inline-block; margin:0;text-transform:uppercase; }
h1:after {
  display:block;
  content: '';
  border-bottom: solid 3px #019fb6;  
  transform: scaleX(0);  
  transition: transform 250ms ease-in-out;
}
h1:hover:after { transform: scaleX(1); }
h1.fromRight:after{ transform-origin:100% 50%; }
h1.fromLeft:after{  transform-origin:  0% 50%; }

<h1 class="fromCenter">Expand from center</h1><br/>
<h1 class="fromRight">Expand from right</h1><br/>
<h1 class="fromLeft">Expand from left</h1>

Note : You need to add vendor prefixes to maximize browser support (see canIuse).

Expand bottom border on hover with 2 lines

You can achieve this effect when the text spans on 2 lines. The before pseudo element is absolutely positioned to make underline of the first line with bottom:1.2em;:

h1 { position:relative;color: #666;display:inline-block; margin:0;text-transform:uppercase;text-align:center;line-height:1.2em; }
h1:after, h1:before {
  display:block;
  content: '';
  border-bottom: solid 3px #019fb6;  
  transform: scaleX(0);  
  transition: transform 250ms ease-in-out;
}
h1:before{
  position:absolute;
  bottom:1.2em; left:0;
  width:100%;
}
.ef2:hover:after {
  transition-delay:150ms;
}
  
h1:hover:after, h1:hover:before { transform: scaleX(1); }

<h1>Expand border<br/>on two lines</h1>
<br/>
<br/>
<h1 class="ef2">Expand border<br/>effect two</h1>

Different transition direction on hover in and out :

The point is to change the transform-origin position from one side to the other on the hover state. This way the bottom boder enters from one side on hover and exits on the other when the element isn't hovered anymore.
Here is a demo :

h1 { color: #666;display:inline-block; margin:0;text-transform:uppercase; }
h1:after {
  display:block;
  content: '';
  border-bottom: solid 3px #019fb6;  
  transform: scaleX(0);  
  transition: transform 250ms ease-in-out;
}
h1.fromLeft:after{ transform-origin: 100% 50%; }
h1.fromRight:after{  transform-origin:   0% 50%; }
h1.fromLeft:hover:after{ transform: scaleX(1); transform-origin:   0% 50%; }
h1.fromRight:hover:after{ transform: scaleX(1); transform-origin: 100% 50%; }

<h1 class="fromRight">Expand from right</h1><br/>
<h1 class="fromLeft">Expand from left</h1>

Solution 2 - Css

We can do this with only background. No pseudo-element needed. This is more flexible.

h1 {
  /* you can change these variables to control the border */
  --border-color: purple;
  --border-width: 5px;
  --bottom-distance: 0px; /* you can increase this */
  
  color: #666;
  display: inline-block;
  background-image: linear-gradient(var(--border-color), var(--border-color));
  background-size: 0% var(--border-width);
  background-repeat: no-repeat;
  transition: background-size 0.3s;
  margin: 5px 0;
}

.fromCenter {
  background-position: 50% calc(100% - var(--bottom-distance));
}

.fromRight {
  background-position: 100% calc(100% - var(--bottom-distance));
}

.fromLeft {
  background-position: 0 calc(100% - var(--bottom-distance))
}

h1:hover {
  background-size: 100% var(--border-width);
}

<h1 class="fromCenter">Expand from center</h1><br/>
<h1 class="fromRight">Expand from right</h1><br/>
<h1 class="fromLeft">Expand from left</h1>

enter image description here

Multiple line animation:

h1 {
  /* you can change these variables to control the border */
  --border-color: purple;
  --border-width: 5px;
  --bottom-distance: 0px; /* you can increase this */
  
  color: #666;
  display: inline; /* should be 'inline' for multiple line animation */
  background-image: linear-gradient(var(--border-color), var(--border-color));
  background-size: 0% var(--border-width);
  background-repeat: no-repeat;
  transition: background-size 0.5s;
}

.fromCenter {
  background-position: 50% calc(100% - var(--bottom-distance));
}

.fromRight {
  background-position: 100% calc(100% - var(--bottom-distance));
}

.fromLeft {
  background-position: 0 calc(100% - var(--bottom-distance))
}

h1:hover {
  background-size: 100% var(--border-width);
}

<h1 class="fromLeft">Expand from <br>left with <br>multiple line</h1>

enter image description here

Solution 3 - Css

simple and lightweight version

li {
    margin-bottom: 10px;
}

.cool-link {
    display: inline-block;
    color: #000;
    text-decoration: none;
}

.cool-link::after {
    content: '';
    display: block;
    width: 0;
    height: 2px;
    background: #000;
    transition: width .3s;
}

.cool-link:hover::after {
    width: 100%;
    //transition: width .3s;
}

<ul>
    <li><a class="cool-link" href="#">A cool link</a></li>
    <li><a class="cool-link" href="#">A cool link</a></li>
    <li><a class="cool-link" href="#">A cool link</a></li>
</ul>

Solution 4 - Css

I know this is an old post and it is already answered but you might like the following effect too.

<div class="cd-single-point">
	<a class="cd-img-replace" href="#0"></a>
</div>

   .cd-single-point {
    position: absolute;
    list-style-type: none;
    left: 20px;
    top: 20px;
  }

  .cd-single-point>a {
      position: relative;
      z-index: 2;
      display: block;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: #0079ff;
      -webkit-transition: background-color 0.2s;
      -moz-transition: background-color 0.2s;
      -o-transition: background-color 0.2s;
      transition: background-color 0.2s;
  }

  .cd-single-point::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    animation: cd-pulse 2s infinite;
  }
   
  @keyframes cd-pulse
  {
  0%  {box-shadow:0 0 0 0 #0079ff}
  100%{box-shadow:0 0 0 20px rgba(255,150,44,0)}
  }

DEMO

Solution 5 - Css

h1 {
  color: #666;
  display:inline-block;
  margin:0;
  text-transform:uppercase;
 }
h1:after {
  display:block;
  content: '';
  border-bottom: solid 3px #92a8d1;  
  transform: scaleX(0);  
  transition: transform 800ms ease-in-out;
}
h1:hover:after {
 transform: scaleX(1);
}

<h1 class="fromCenter">Hover Over Me</h1><br/>

Solution 6 - Css

we can do using simple transition effect.

HTML

<h1>CSS IS AWESOME</h1>

CSS

h1 {
	color: #666;
    position: relative;
    display: inline-block;
}

h1:after {
	position: absolute;
    left: 50%;
	content: '';
	height: 40px;
	height: 5px;
    background: #f00;
    transition: all 0.5s linear;
    width: 0;
    bottom: 0;  
}

h1:hover:after {
	width: 270px;
    margin-left: -135px;
}

Link to Fiddle

Solution 7 - Css

transition: all 1000ms ease-in-out;	

Demo

or are you looking for this

Demo2

Solution 8 - Css

h1 {
  color: #666;
}

h1:after {
  position: absolute;
  left: 10px;
  content: '';
  height: 40px;
  width: 275px;
  border-bottom: solid 3px #019fb6;
  transition: all 550ms ease-in-out;
  border-bottom-width: 0px;
}

h1:hover:after {
  border-bottom-width: 5px;
}

<h1>CSS IS AWESOME</h1>

Solution 9 - Css

h1 {
  /* you can change these variables to control the border */
  --border-color: purple;
  --border-width: 5px;
  --bottom-distance: 0px; /* you can increase this */
  
  color: #666;
  display: inline-block;
  background-image: linear-gradient(var(--border-color), var(--border-color));
  background-size: 0% var(--border-width);
  background-repeat: no-repeat;
  transition: background-size 0.3s;
  margin: 5px 0;
}

.fromCenter {
  background-position: 50% calc(100% - var(--bottom-distance));
}

.fromRight {
  background-position: 100% calc(100% - var(--bottom-distance));
}

.fromLeft {
  background-position: 0 calc(100% - var(--bottom-distance))
}

h1:hover {
  background-size: 100% var(--border-width);
}

<h1 class="fromCenter">Expand from center</h1><br/>
<h1 class="fromRight">Expand from right</h1><br/>
<h1 class="fromLeft">Expand from left</h1>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVivekraj K RView Question on Stackoverflow
Solution 1 - Cssweb-tikiView Answer on Stackoverflow
Solution 2 - CssdoğukanView Answer on Stackoverflow
Solution 3 - CssLevan JintcharadzeView Answer on Stackoverflow
Solution 4 - CssPhilip EncView Answer on Stackoverflow
Solution 5 - CssMohammad Ayoub KhanView Answer on Stackoverflow
Solution 6 - CssrajuView Answer on Stackoverflow
Solution 7 - CsshimanshuView Answer on Stackoverflow
Solution 8 - CssMohammad Ayoub KhanView Answer on Stackoverflow
Solution 9 - CssAnnaPshenichnikovaView Answer on Stackoverflow