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 :

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>

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>

Answer from web-tiki on Stack Overflow
๐ŸŒ
CodePen
codepen.io โ€บ martinwolf โ€บ pen โ€บ eNNdme
Animate Border Bottom - Link Hover Effect
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; }
Top answer
1 of 9
287

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 :

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>

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>

2 of 9
20

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>

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>

Discussions

animation - CSS: bottom-border-transition - expand from middle - Stack Overflow
I want to add a bit of transitions to my website. I already have that when someone is in a input-field (so :focus) the border changes color with a transition. I would like that transition to happen... More on stackoverflow.com
๐ŸŒ stackoverflow.com
How to animate a border-bottom over an existing border-bottom on hover without using pseudo-states
I want to animate a border-bottom on hover over an existing border bottom like so: Gif showing border-bottom transition I have tried doing this using pseudo states ::before and ::after and this only More on stackoverflow.com
๐ŸŒ stackoverflow.com
August 29, 2020
Border bottom on hover on mediyum screen isnt working
Can you replicate the minimum requirements to show the issue you are seeing in Tailwind Play and share it here? https://play.tailwindcss.com/ More on reddit.com
๐ŸŒ r/tailwindcss
6
1
August 14, 2023
How to stop a border hover state from moving button/div
"I usually just add a transparent border to the default state" In your example the default state doesn't have a border. This is what worked for me. The 2nd line is all the border stuff. More on reddit.com
๐ŸŒ r/tailwindcss
8
5
November 19, 2022
๐ŸŒ
CSS-Tricks
css-tricks.com โ€บ animating-border
Animating Border | CSS-Tricks
December 6, 2017 - Though there was no consensus on the best approach, I did receive some really clever ideas by some phenomenal developers. The most straightforward way to animate a border isโ€ฆ well, by animating border. .border-button { border: solid 5px #FC5185; transition: border-width 0.6s linear; } .border-button:hover { border-width: 10px; }
๐ŸŒ
Slider Revolution
sliderrevolution.com โ€บ home โ€บ awesome css border animation examples to use
Awesome CSS Border Animation Examples to Use in Your Websites
January 27, 2026 - ... Travis created this single-div ... use of CSS animation direction and timing. The hover effect reveals the border animation, creating an element of surprise that engages users....
๐ŸŒ
Steckinsights
steckinsights.com โ€บ animate-the-length-of-the-border-bottom-with-pure-css
Animate The Length Of The Border-Bottom With Pure CSS
February 6, 2019 - */ display: block; /* This will put the pseudo element on its own line. */ width: 5%; /* Change this to whatever width you want to have before hover. */ padding-top: 20px; /* This creates some space between the element and the border. */ border-bottom: 1px solid black; /* This creates the border. Replace black with whatever color you want. */ transition: .5s; /* This establishes the amount of time in seconds the animation should take from start to finish */ } .page-title:hover:after { width: 15%; /* This will be the new width of your border when on hover */ }
Call ย  (847) 687-4565
Address ย  2621 W Cucharras St,, 80904, Colorado Springs,
๐ŸŒ
No-Code Supply Co.
nocodesupply.co โ€บ item โ€บ text-bottom-border-animation-on-hover
Text Bottom Border Animation on Hover [Snippet] <> No-Code Supply Co.
Use CSS to create a simple bottom border animation on hover of links, without needing to use JS, Webflow Interactions, etc.
๐ŸŒ
CodePen
codepen.io โ€บ simjihun โ€บ embed โ€บ aMGKLL
CodePen Embed - Border bottom hover effect
h1 { color: #000; display:inline-block; margin:0; text-transform:uppercase; } h1:after { display:block; content: ''; border-bottom: solid 3px #ea2129; 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%; } This Pen is owned by jihun Sim on CodePen.
Find elsewhere
๐ŸŒ
CodePen
codepen.io โ€บ harman97 โ€บ pen โ€บ ZdEemB
Link Hover Effect: Animate Border Bottom
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; }
๐ŸŒ
Tutorialscan
tutorialscan.com โ€บ home โ€บ css โ€บ css border transition effects on hover | border hover animation
CSS Border Transition Effects On Hover | Border Hover Animation
October 15, 2019 - how to create CSS Border transition effects on hover using CSS? CSS border Animation on hover. all effect is changing border style on mouseover
๐ŸŒ
For Frontend
forfrontend.com โ€บ border-bottom-hover-effect-css
How to Create Border Bottom Hover Effect in CSS
December 17, 2023 - The transition property makes this change gradual, creating an animation effect. The speed of the hover effect can be customized by adjusting the duration of the transition. In the transition property, the 250ms value determines how long the ...
๐ŸŒ
FreeFrontend
freefrontend.com โ€บ css-border-animations
57 CSS Border Animations
2 weeks ago - ... This is an Animated Border Drawing Button. It transforms a standard call-to-action into a multi-stage micro-interaction. Upon hovering over the button, the component triggers a sequential animation where four corner dots appear, followed ...
๐ŸŒ
30 Seconds of Code
30secondsofcode.org โ€บ home โ€บ css โ€บ animation โ€บ button transitions
Button border animation - CSS
August 29, 2024 - Then, using the :hover pseudo-class, you can extend the width of those elements to 100% on hover and animate the change using transition. .button-bordered { border: none; outline: none; position: relative; } .button-bordered::before, ...
๐ŸŒ
CSS Hero
csshero.org โ€บ home โ€บ how to use css pseudo classes to build a border hover animation
How to use CSS pseudo classes to build a border hover animation - CSS Hero
August 4, 2022 - Welcome back to a new video tutorial. Today we are going to see how to make an animated line and apply it to our menu links. This line will be designed with a simple border animation, on hover. In this tutorial you will learn about important CSS tricks: 1. How to create a CSS pseudo [โ€ฆ]
๐ŸŒ
Prismic
prismic.io โ€บ blog โ€บ css-hover-effects
CSS Hover Effects: 40 Engaging Animations To Try
December 11, 2024 - This animation creates a liquid-like morphing effect on a button when hovered over. Initially, the button has a rounded rectangular shape with a dark blue background and a centered text label.
๐ŸŒ
BricksLabs
brickslabs.com โ€บ animated-border-hover-effect-buttons
Animated Border Hover Effect Buttons - BricksLabs
November 26, 2022 - .btn-animated-border { position: relative; display: inline-block; padding: 15px 30px; border: 2px solid #111; text-transform: uppercase; color: #111; text-decoration: none; font-weight: 600; font-size: 20px; background-color: transparent; } .btn-animated-border::before { content: ""; position: absolute; top: 6px; left: -2px; width: calc(100% + 4px); height: calc(100% - 12px); background: #fff; transition: 0.5s ease-in-out; transform: scaleY(1); } .btn-animated-border:hover::before { transform: scaleY(0); } .btn-animated-border:hover::after { transform: scaleX(0); } .btn-animated-border span { position: relative; z-index: 3; } .btn-animated-border::after { content: ""; position: absolute; left: 6px; top: -2px; height: calc(100% + 4px); width: calc(100% - 12px); background: #fff; transition: 0.5s ease-in-out; transform: scalex(1); }
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ article โ€บ how-to-define-the-border-bottom-color-is-animatable-in-css
How to define the border bottom color is animatable in CSS?
3 weeks ago - When you hover over it, the bottom border smoothly transitions from blue to red over 0.5 seconds. The border-bottom-color property is fully animatable in CSS, allowing for smooth color transitions using keyframes or transitions.
Top answer
1 of 2
2

A simple background animation can do it:

h1 {
  color: #666;
  display: inline-block;
  margin: 0;
  text-transform: uppercase;
  background:
    linear-gradient(#019fb6 0 0),
    linear-gradient(lightgray 0 0); 
  background-size:0% 3px,100% 3px; /* we make the top one 0% width */
  background-position:bottom left;
  background-repeat:no-repeat;
  transition:0.5s;
}


h1:hover {
  background-size:100% 3px; /* 100% width on hover */
}
<h1 class="fromLeft">Expand from left</h1>

Considering your code, a negative margin is all what you are missing:

h1 {
  color: #666;
  display: inline-block;
  margin: 0;
  text-transform: uppercase;
  border-bottom: 3px solid lightgray; 
}

h1:after {
  display: block;
  content: '';
  border-bottom: solid 3px #019fb6;
  margin-bottom:-3px; /* here */
  transform: scaleX(0);
  transition: transform 250ms ease-in-out;
}

h1:hover:after {
  transform: scaleX(1);
}

h1.fromLeft:after {
  transform-origin: 0% 50%;
}
<h1 class="fromLeft">Expand from left</h1>

2 of 2
1

You need to create to elements stacked on top of each other, then add pointer-events: none to the upper one, which will make it "transparent" to pointer-events, so you can still acces the input below it. Using the ~ selector we can now edit the width of the upper element, while hovering the input, since its placed "phyisically" after the input.

/* optional */

input[type=text] {
  background-color: #ECEFF1;
  border: 0;
}

/**/

*,
::after,
::before {
  box-sizing: border-box;
}

.wrapper {
  display: inline-block;
  position: relative;
}

input[type=text],
.onHover {
  height: 2rem;
  border-bottom-style: solid;
  border-bottom-width: 1px;
}

input[type=text] {
  border-bottom-color: #B0BEC5;
}

input[type=text]:hover ~ .onHover {
  width: 100%;
}

.onHover {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  border-bottom-color: #000;
  pointer-events: none;
  transition: width 400ms ease-in;
}
<div class="wrapper">
  <input type="text">
  <div class="onHover"></div>
</div>

๐ŸŒ
Stackfindover
blog.stackfindover.com โ€บ home โ€บ css border animation [ 25+ best css border effect examples]
CSS Border Animation [ 25+ Best CSS Border Effect Examples]
September 19, 2021 - Simple Border radius animation, which was developed by yuku. Moreover, you can customize it according to your wish and need. Border Effect on Hover, which was developed by LycanOne.
๐ŸŒ
Medium
medium.com โ€บ frontend-canteen โ€บ fantastic-css-border-animation-b02e06828beb
Fantastic CSS border animation
July 24, 2022 - Hereโ€™s another little trick, if we want the dashed border animation to transition from other borders to the dashed border, and then animate. It is also possible to simulate entirely by gradients, if you want to save some code, it borderwill be , for example: div { border: 1px solid #333; &:hover { border: none; background: linear-gradient(90deg, #333 50%, transparent 0) repeat-x, linear-gradient(90deg, #333 50%, transparent 0) repeat-x, linear-gradient(0deg, #333 50%, transparent 0) repeat-y, linear-gradient(0deg, #333 50%, transparent 0) repeat-y; background-size: 4px 1px, 4px 1px, 1px 4px, 1px 4px; background-position: 0 0, 0 100%, 0 0, 100% 0; } }