Is there a way to undo the transition when hovering out?

Is it possible to achieve a reverse transition animation on hover out using CSS?

I want the "Menu" text to slide to the right blue line when I hover out, and after a delay of 400ms, slide back from the left grey line.

Can this be done?

.menu {
  display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
}
.menu:before, .menu:after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: 4px;
  background-color: blue;
  transform: scaleX(0);
  transform-origin: right center;
  transition: 500ms transform cubic-bezier(0, 0.75, 0.45, 1);
}
.menu:after {
  background-color: grey;
  transform: scaleX(1);
  transform-origin: left center;
}
.menu:hover {
  cursor: pointer;
}
.menu:hover:before {
  transform: scaleX(1);
  transform-origin: left center;
  transition-delay: 400ms;
}
.menu:hover:after {
  transform: scaleX(0);
  transform-origin: right center;
}
<div class="menu">
  Menu
</div>

Answer №1

If you want to create a gradient effect with blue on the left, grey on the right, and a transparent middle section using minimal code, here's how you can achieve it. By setting the background-size to cover 100% of the element width and adjusting the percentages of blue, grey, and transparent parts in the gradient, you can control the transition between colors when changing the background-position.

For example, you can set the blue and grey sections to be 25% each with a total size of 400%, creating the delay effect:

.menu {
 display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
  background-image:
    linear-gradient(to right,blue 0,blue 25%,transparent 25%,transparent 75%,grey 75%);
  background-size:400% 4px;
  background-position:bottom right;
  background-repeat:no-repeat;
  transition:1s all;
}
.menu:hover {
  background-position:bottom left;
}
<div class="menu">
  Menu
</div>

To increase the delay while maintaining the same duration, you can adjust the sizes of the transparent parts accordingly, as shown in this example:

.menu {
 display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
  background-image:
    linear-gradient(to right,blue 0,blue 10%,transparent 10%,transparent 90%,grey 90%);
  background-size:1000% 4px;
  background-position:bottom right;
  background-repeat:no-repeat;
  transition:1s all;
}
.menu:hover {
  background-position:bottom left;
}
<div class="menu">
  Menu
</div>

UPDATE

If you want to further customize the transition effects, you can use multiple gradients with different color combinations and sizes. Here's an example that creates a more complex transition:

.menu {
 display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
  background-image:
    linear-gradient(to right,blue 0,blue 25%,transparent 25%,transparent 75%,grey 75%),
    linear-gradient(to right,grey 0,grey 25%,transparent 25%,transparent 75%,blue 75%);
  background-size:400% 4px,400% 0px;
  background-position:bottom right,bottom left;
  background-repeat:no-repeat;
  transition:background-position 1s,background-size 0s 1s;
}
.menu:hover {
  background-position:bottom left,bottom right;
  background-size:400% 0px,400% 4px;
}
<div class="menu">
  Menu
</div>

Answer №2

There is another CSS technique that resembles your initial code, involving positions and borders. Nevertheless, the method using gradients provided by @Temani Afif is more concise and smart.

Check out the demo on JSFiddle: http://jsfiddle.net/joshmoto/2f4zm1wk/

.menu {
  display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
  overflow: hidden;
  cursor: pointer;

  &:after,
  &:before {
    content: "";
    position: absolute;
    bottom: 0;
    display: block;
    height: 4px;

  }

  &:before {
    background: grey;
    left: -80px; right: 0;
    transition: left .6s ease;
    border-left: 80px white solid;

  }

  &:after {
    background: blue;
    left: 0; right: calc(100% + 80px);
    transition: right .6s ease;

  }

  &:hover {

    &:before {
      left: calc(100% + 80px);

    }

    &:after {
      right: -80px;

    }

  }

}

SASS output of the CSS...

.menu {
  display: inline-block;
  position: relative;
  font-family: sans-serif;
  font-size: 32px;
  font-weight: bold;
  overflow: hidden;
  cursor: pointer;
}

.menu:after,
.menu:before {
  content: "";
  position: absolute;
  bottom: 0;
  display: block;
  height: 4px;
}

.menu:before {
  background: grey;
  left: -80px;
  right: 0;
  transition: left .6s ease;
  border-left: 80px white solid;
}

.menu:after {
  background: blue;
  left: 0;
  right: calc(100% + 80px);
  transition: right .6s ease;
}

.menu:hover:before {
  left: calc(100% + 80px);
}

.menu:hover:after {
  right: -80px;
}
<div class="menu">
  Menu
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I access a nested FormArray in Angular?

I have a situation where I am trying to access the second FormArray inside another FormArray. Here is an excerpt from my component: registrationForm = new FormGroup({ registrations: new FormArray([this.patchRegistrationValues()]) }); patchRegistrati ...

Trigger the opening of a class or window upon pressing the button

Good evening, I'm attempting to create a functionality where pressing a specific button will open a window. However, I am unsure of how to achieve this using CSS classes. My initial thought was to add a new class in the CSS file and call it every ti ...

Using jQuery to update the input value when the mouse hovers over a div

Attempting to update an input value using jQuery mouseover. Situation: There are 5 divs with different colors and usernames. When hovering over a div, the input text (and background color for the color input) changes based on database values. Each time a ...

Best practices for coding in HTML and CSS

Creating my first website for an internship has been quite a learning experience. Throughout my training, I was always advised to avoid embedding styles directly into the HTML code. However, now that I am actually developing a site, I can't help but f ...

How can I fix the issue of the header background image not resizing properly? Any suggestions?

I am currently working on improving the responsiveness of my website when a user resizes their browser window. One specific issue I'm facing is resizing the banner image as the window size changes. The website in question can be found at The CSS code ...

Getting the most out of fonts with Webpack sass-loader

I recently set up a custom font in my project like this: $font-path: '~@/assets/fonts/'; @font-face { font-family: 'mainFont'; font-weight: 300; font-style: normal; src: url('#{$font-path}mainFont/mainFont.eot&apos ...

How can I prevent the expansion of elements in a drop-down menu when using display:

I've been struggling to implement a drop-down feature in my menu. The issue is that when I use display: flex, hovering over the drop-down also expands all other boxes without drop-downs. Any ideas on how to fix this easily? Additionally, is there a w ...

CSS navbar with a unique design: Issue with List Hover not Persisting

I'm facing a common issue with a pure CSS navbar. I have constructed a navbar using ul and li elements, but I am unable to make the menus stay visible when I hover over them. The problem lies in the fact that the menu opens only when I hover over the ...

Creating an object positioned to the right side of a div (div:right) is a matter of using CSS positioning properties

While we are familiar with pseudo-classes like :before and :after, have you ever wondered why there is no nav ul li a:left or :right? Do you think it's achievable? I'm open to using HTML5, CSS3, and JavaScript to make it happen. ...

UL tags incompatible with columns

I am attempting to create 2 columns using an ordered list (ul). Despite successfully adding the ul and li's, I am encountering issues with the column formatting. You can view the JSFiddle here. Below is the code snippet: ul { background-color:yello ...

Tips for ensuring the Search button always remains alongside the input bar during resizing with percentages

I've been trying to figure out why the search button is still showing at the bottom left and creating an "l" shape even though I'm using style="overflow: hidden; padding-right: .5em;". Does anyone have any ideas as to what might be causing this i ...

The CSS does not get applied to the returned element in Next JS

When I create a function to return a DOM element with an associated className, the local style doesn't seem to be applied. For example: export default function thing(){ const elem = function(){ return (<div className="myCss">Hello< ...

What is the best way to position a single element in React using the Grid Component without causing any overlap?

I am struggling with positioning 3 components on my react page: PageHeader, SideMenu & FeatureList (which consists of Display Cards). Here is the code for each component: App.js // App.js code here... PageHeader.js // PageHeader.js code here... SideMenu ...

What are some techniques for styling a field when the div id is not specified?

I need to customize a data field within a table, but I am unable to locate or identify its div ID. Here is the page source: <tbody> <tr> <td style="font-size:12px; text-align:center;" name=""> <div sty ...

How to target the DIV elements that have at least one unordered list (UL) inside using CSS selector or JavaScript

Imagine a hierarchy structured like this: <div class="first_level"> <div class="second_level_1"> <div class="third_level_1"> <div class="fourth_level_1"> <ul><li></li><li></li></ ...

A specific div remains in place as the user scrolls

Imagine a div that is positioned 60px from the top of the screen. What if, as you scroll down, it stops when it reaches 10px from the top and remains there for the rest of your scrolling session? And then, when you scroll back up, it goes back to its ori ...

Icon Searchbar Feature in Ionic 2

I am currently working with Ionic2 and have integrated the ion-searchbar component into my project: https://i.sstatic.net/CqmF4.png Question Would it be possible to customize the search icon? The default icon is a magnifying glass, but I would like to r ...

Guide on incorporating Bootstrap JS into HTML5 reusable web elements

RESOLVED: the solution is in a comment TL;DR: Issues triggering Bootstrap's JS, likely due to incorrect import of JS scripts I've been working on integrating Bootstrap with my custom reusable web components across all pages. Specifically, I&apo ...

Adjust the height of the list when including or excluding floated list items that are not in the final row

Within my ul are li elements with varying widths that wrap around inside a container into multiple rows. When removing an li element from the ul, I want the container's height to adjust dynamically in case a row is eliminated. If the removal happens ...

What is the best way to position my div outside of the wrapper while keeping the text inside?

For example: I want the blue text that says "join our discord server" to extend to 100% width when it's placed inside the wrapper. The reason it's inside the wrapper is to ensure the text matches up perfectly with the rest of the content. ...