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

Why does the <div> element still have an offset even though its width and height are set to 100px and padding, margin, and border are set to 0px?

After styling my div element with specific CSS rules, I'm encountering an issue. The div has a set width and height of 100px along with padding, border, and margin all set to 0px. However, the elements are not being offset from the edges of the browse ...

When my script is located in the head of the HTML page, I am unable to

My goal is to make my JavaScript code function properly when I insert it into either the head or body elements of an HTML document. Let's look at some examples: First, I insert the script into the body as shown in this example (works correctly): ...

How to target the following sibling element (not a child) with CSS

I am working with the following HTML structure: <div class="col-sm-12"> <input id="my_id"> <div class="col-sm-1 col-3-box" style="position:absolute; margin-left:340px;"> </div> </div> How can I target and change ...

Error in Chrome: Text container's height is not fully extended to 100%

I'm encountering an issue with achieving 100% height on a child container in Google Chrome, although it works perfectly fine on Firefox. Here is the URL: http://linco.com.py/beta/multiplaza/cartelera.php The styling for the main container is as fol ...

What approach do you recommend for creating unique CSS or SCSS styles for the same component?

Consider a scenario where you have a complicated component like a dropdown menu and you want to apply custom styles to it when using it in different contexts. This customization includes not only changing colors but also adjusting spacing and adding icons. ...

Animate the background of a table cell (td) in React whenever a prop is updated

I have a dynamic table that receives data from props. I would like the background animation of each cell (td) to change every time it receives new props. I've tried creating an animation for the background to indicate when a cell is updated, but it on ...

What is the reason for Firefox and Opera disregarding the max-width property when used within display: table-cell?

When viewing the code below, you may notice that it displays correctly in Chrome or IE with the image set to be 200px wide. However, in Firefox and Opera, the max-width style seems to be completely ignored. Is there a reason for this inconsistency across b ...

css Sibling elements restricted within parent container

Encountering an issue with a star rating css example when more than one fieldset is added. The current CSS code seems to be working fine, but it fails when multiple instances of the same elements [fieldset] are present. I've been struggling to find a ...

The challenges with implementing makeStyles in React Material UI

const useStyles = makeStyles((theme) => ({ toolbarMargin: { ...theme.mixins.toolbar, marginBottom: "3em", }, logo: { height: "7em", }, tabContainer: { marginLeft: "auto", }, tab: { ...theme ...

Iframe not functioning properly on Internet Explorer versions 8-11 when using WordPress

I'm having trouble getting my WordPress video to display when using an iframe. When I try to view it in Internet Explorer, the video automatically loads in Windows Media Player instead of playing through the iframe. The video files are local mp4s and ...

Unable to disable background color for droppable element

For my project, I am working with two div boxes. My goal is to make it so that when I drag and drop box002 into another div box001, the background color of box001 should change to none. I have attempted to achieve this functionality using jQuery without s ...

Animate an image to the right when clicked, then return it to the left with a second click

Seeking help with animating a set of images to move individually 300px right on first click, and then 300px left when clicked again. I'm currently facing an issue where my code is not working. It could be due to A) syntax errors or B) the images not ...

Modify components in a web application based on the content of a JavaScript variable

I'm in the process of developing a webapp that needs to interact with an Arduino for its inputs in order to dynamically change the contents of the webpage. Currently, I am experimenting with variables that I have created and assigned random numbers t ...

Reorganize a list based on another list without generating a new list

Among the elements in my HTML list, there are items with text, input fields, and tables. I also have a specific order list like [3,1,2,0]. Is it feasible to rearrange the items in the HTML list on the page based on this order list without generating a new ...

Switching the typeface within the content data

Recently, I incorporated this code: <div data-content="Reach" class="main-image"> along with the following CSS styling: .main-image:before { content: attr(data-content); I am now wondering if there is a method to adjust the font size and ...

What is the best way to position two elements inline?

I was trying to create a container named project-item that looks like the image linked below: https://i.stack.imgur.com/6XzZ9.png My goal was to align the project logo and the title (h3) in one line, but I struggled to find a suitable solution. This is ...

Changing the format of PHP SQL results from vertical to horizontal

Is there a way to convert the vertical table generated by the following code into a horizontal one with stylish formatting? Additionally, is it possible to display certain columns in a popup window based on query parameters using jQuery or CSS? <html&g ...

Adjusting the width of a select box to match the size of its child table using CSS

Within my Vue application, I've implemented a select box that contains a table component. When the select box is clicked, the table becomes visible in a container. However, I'm facing an issue where I can't dynamically adjust the width of th ...

"Getting Started with Respond.js: A Step-by-Step

I've been struggling to find clear instructions on how to properly set up respond.js. Should I just unzip it into the htdocs folder, or do I only need respond.min.js in there? Then, do I simply reference the file like this... <script src="respon ...

How to customize Material UI Autocomplete options background color

Is there a way to change the background color of the dropdown options in my Material UI Autocomplete component? I've checked out some resources, but they only explain how to use the renderOption prop to modify the option text itself, resulting in a a ...