Is it possible to prevent a CSS transition reversing off hover?

Viewed 127

I have a hover animation that I have created with CSS. When the user hovers over the link the underline transitions from left to right changing the colour from black to grey. Currently as you would expect when the user moves their mouse off the link the transition reverses to start state.

I wondered if it is possible to prevent this reverse transition and instead fade the underline back to the colour black (the original start state)?

Here is a jsfiddle to work with.

Any suggestions/advise would be most welcome.

a.btn--tertiary {
  padding-left: 0;
  padding-right: 0;
  background-color: transparent;
  color: #000;
  border: 0;
  position: relative;
  padding-bottom: 5px;
  text-transform: uppercase;
  text-decoration: none;
  font-size: 40px;
}

.btn--tertiary:before {
  content: '';
  height: 2px;
  right: 0;
  width: 100%;
  background: #000;
  position: absolute;
  bottom: 0;
  opacity: 1;
  transition: width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0s;
  z-index: 2;
  border-left: 10px solid transparent;
}

.btn--tertiary:after {
  content: '';
  height: 2px;
  left: 0;   
  right: auto;
  width: 0%;
  background: grey;
  position: absolute;
  bottom: 0;
  transition: width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0.1s;
  z-index: 3;
}

.btn--tertiary:hover:before,
.btn--tertiary:focus:before {
  width: 0%;
  border-left: 20px solid $white;
}

.btn--tertiary:hover::after,
.btn--tertiary:focus::after {
  right: 0;
  width: 100%;
}
3 Answers

You can try like below. Check the comments for the details:

a.btn--tertiary {
  color: #000;
  position: relative;
  padding-bottom: 5px;
  display:inline-block;
  text-decoration:none;
  overflow:hidden;
  font-size: 40px;
}

.btn--tertiary:before,
.btn--tertiary:after {
  content: '';
  height: 2px;
  position: absolute;
  bottom: 0;

}

.btn--tertiary:before {
  right: 0;
  width: 100%;
  background: #000;
  border-left: 20px solid #fff;
  transition:
    background 2s cubic-bezier(0.100, 0.600, 0.350, 1.000); /* transition the background on mouseout*/
}

.btn--tertiary:after {
  left: 0;
  width: 0%;
  background: red;
}
  
.btn--tertiary:hover:before,
.btn--tertiary:focus:before {
  width: 0%;
  background: red;
  transition: 
    width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0s, /* visible transition of width on hover */
    background 0s 1s; /* no transition but a background change after 1s */
}

.btn--tertiary:hover::after,
.btn--tertiary:focus::after {
  right: 0;
  width: 100%;
  transition: 
    width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0.1s; /* visible transition of width on hover  */
}
<a href="#" class="btn--tertiary">Button</a>

Yes, it is indeed. The trick is to make the width transition out take 0s with a delay of 1s.

html,
body {
  margin: 0;
  padding: 0;
}

a.btn--tertiary {
  padding-left: 0;
  padding-right: 0;
  background-color: transparent;
  color: #000;
  border: 0;
  position: relative;
  padding-bottom: 5px;
  text-transform: uppercase;
  text-decoration: none;
  font-size: 40px;
}

.btn--tertiary::before {
  content: '';
  height: 2px;
  right: 0;
  width: 100%;
  background: #000;
  position: absolute;
  bottom: 0;
  transition: width 0s;
  z-index: 2;
  border-left: 10px solid transparent;
}

.btn--tertiary::after {
  content: '';
  height: 2px;
  left: 0;
  right: auto;
  width: 0%;
  background: grey;
  position: absolute;
  bottom: 0;
  opacity: 0;
  transition: opacity .5s, width 0s .5s;
  z-index: 3;
}

.btn--tertiary:hover:before,
.btn--tertiary:focus:before {
  width: 0%;
  border-left: 20px solid $white;
  transition: width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0s;
}

.btn--tertiary:hover::after,
.btn--tertiary:focus::after {
  right: 0;
  width: 100%;
  opacity: 1;
  transition: opacity 0s, width 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0.1s;
}
<a href="#" class="btn--tertiary">Button</a>

Fiddle.

I hope this would help, please see the example below.

div {
  text-align: center;
  margin-top: 20px;
}

.btn--tertiary {
  text-decoration: none;
  font-family: sans-serif;
  text-transform: uppercase;
  display: inline-block;
  position: relative;
  overflow: hidden;
  font-size: 45px;
  color: black;
}

.btn--tertiary::before {
  position: absolute;
  content: '';
  width: 100%;
  height: 3px;
  bottom: 0;
  left: 0;
  background: gray;
  transform: scale(0, 1);
  transform-origin: right;
  transition: transform 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0s;
}

.btn--tertiary:hover::before {
  transform: scale(1, 1);
  transform-origin: left;
  transition: transform 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) .1s;
}

.btn--tertiary::after {
  position: absolute;
  content: '';
  width: 100%;
  height: 3px;
  bottom: 0;
  right: 0;
  background: black;
  transform: scale(1, 1);
  transform-origin: left;

  transition: transform 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) .1s;
}

.btn--tertiary:hover::after {
  transform: scale(0, 1);
  transform-origin: right;
  transition: transform 1s cubic-bezier(0.100, 0.600, 0.350, 1.000) 0s;
}
<div>
  <a href="#" class="btn--tertiary">Button</a>
</div>

Related