Move the box upwards and change it to grayscale when hovering over the image, then reverse the effect when the hover

As I hover over the image, my goal is to make a gray box appear at the bottom and smoothly slide up. While it slides up, everything it covers should turn grayscale. When I move my mouse away from the image, I want the gray box to slide back down and remove the grayscale effect as it passes over the image.

I managed to achieve most of this using just CSS, but the issue I'm facing is figuring out how to reverse the animation when the mouse leaves the image.

Below is the code snippet I have been working on:

.wrapper {
  position: relative;
  
  img {
    width: 600px;
    height: 375px;  
  }
  
  .hover {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 2;
    width: 600px;
    height: 100px;
    animation-name: example2;
    animation-duration: 1s;
    display: none;
    
    .gray-image {
      width: 100%;
      height: 100%;
      background-image: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg');
      background-repeat: no-repeat;
      background-size: 600px 375px;
      background-position: bottom 0 left 0;
      
      filter: grayscale(100%);
      -webkit-filter: grayscale(100%);
      //position: absolute;
    }
    
    .text {
      color: #FFF;
      text-align: center;
      width: 100%;
      height: 100px;
      background-color: rgba(89, 89, 89, 0.9);
    }
  }
  
  &:hover {
    
    .hover {
      animation-name: example;
      animation-duration: 1s;
      height: 375px;
      display: block;
    }
  }
}

@keyframes example {
  from {
    height: 100px;
  }
  to {
    height: 375px;
  }
}

@keyframes example2 {
  from {
    height: 375px;
  }
  to {
    height: 100px;
  }
}
<div class="wrapper">
  <img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg" />

  <div class="hover">
    <div class="gray-image" />
    <div class="slide-box">
      <div class="text">
          <span>This is the title</span>
      </div>
    </div>
  </div>
</div>

How can I achieve the desired full effect?

For those who prefer it, here is a link to the jsfiddle version: https://jsfiddle.net/pt15ckeL/2/

Answer №1

You can streamline your code by incorporating transitions, as demonstrated below:

.wrapper {
  position: relative;
  width: 600px; /* adjust the size */
  overflow: hidden;
}
.wrapper img {
  width: 100%;
  display: block;
}
/* create a gray image using pseudo-element */
.wrapper::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg') 50%/100% auto;
  filter: grayscale(100%);
  clip-path: inset(100% 0 0); /* initially hide it */
  transition: 1s;
}
/* styling for text */
.text {
  position: absolute;
  inset: 0;
  color: #FFF;
  text-align: center;
  line-height: 100px; /* vertically center within 100px height */
  background: linear-gradient(grey 100px,#0000 0); /* apply gradient to top 100px only */
  translate: 0 100%; /* slide up to overflow the wrapper */
  transition: 1s;
}
.wrapper:hover::before {
  clip-path: inset(0); /* reveal the gray image */
}
.wrapper:hover .text {
  translate: 0 0; /* slide back to the top */
}
<div class="wrapper">
  <img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg" />
  <div class="text">
    <span>This is the title</span>
  </div>
</div>

Furthermore, here's an alternative approach utilizing backdrop-filter, eliminating the need to set the image as a background and avoiding duplicate URLs in your code.

.wrapper {
  position: relative;
  width: 600px; 
  overflow: hidden;
}
.wrapper img {
  width: 100%;
  display: block;
}
.text {
  position: absolute;
  inset: 0;
  color: #FFF;
  text-align: center;
  line-height: 100px; 
  background: linear-gradient(grey 100px,#0000 0); 
  translate: 0 100%; 
  backdrop-filter: grayscale(100%);
  transition: 1s;
}
.wrapper:hover .text {
  translate: 0 0; 
}
<div class="wrapper">
  <img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg" />
  <div class="text">
    <span>This is the title</span>
  </div>
</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

Obtaining JSON values by key name using JQuery

I am trying to extract JSON data using an HTML attribute How can I retrieve JSON values based on the translate attribute and "ed" key? JSON FILE { "open" : [ { "en": "Open", "ed": "Opened ...

Encountering issues when trying to incorporate SASS and CSS libraries in NextJS

I have been attempting to integrate the wix-style-react plugin into my NextJS project, but I am encountering difficulties when trying to build. According to their documentation, they utilize Stylable, SASS, and CSS Modules. After installing the plugin and ...

Revealing concealed content within a Bootstrap modal

I am seeking a way to utilize bootstrap modal in order to display certain contents. Specifically, the email, gender, and status information should initially be hidden and revealed only upon clicking the "view more" button. My goal is to showcase this dat ...

"Exploring the world of TypeScript Classes in combination with Webpack

If I create a TypeScript class with 10 methods and export a new instance of the class as default in one file, then import this class into another file (e.g. a React functional component) and use only one method from the class, how will it affect optimizati ...

Integrate CKEditor with elFinder to allow for direct file uploads

I am utilizing the elFinder Laravel package for file management with CKEditor. I have followed all the steps and everything is working fine except for one issue. When I click on the image button in CKEditor to select or upload an image, after selecting an ...

Can I use MuiThemeProvider in my component without any restrictions?

I have a unique component called View: import React from 'react'; import { AppBar, Toolbar } from 'material-ui'; import { Typography } from 'material-ui'; import { MuiThemeProvider, createMuiTheme } from 'material-ui/st ...

Transferring data from a stream in NodeJS to FrontEnd using ReactJS

How are you doing? I'm trying to figure out how to send a large data request from PostgreSQL to the FrontEnd in JSON format. Can anyone help with an example of how this can be achieved? Thank you. Here is my code: const express = require('expr ...

Issue with Chrome not triggering onMouseEnter event when an element blocking the cursor disappears in React

Important Note: This issue seems to be specific to Chrome Currently, React does not trigger the onMouseEnter event when a blocking element disappears. This behavior is different from standard JavaScript events and even delegated events. Below is a simpli ...

javascript issue with setting the id attribute on a select option

I can't seem to set the id attribute in my select element using JavaScript. When I inspect it, the id attribute isn't showing up... Here's the first method using JS: var selectorElem = document.getElementById('selector') var ...

Eliminating quotation marks from individual elements within a JavaScript array that includes JSON-encoded HTML strings retrieved from a MySQL database using PHP

Performing an Ajax call to fetch data from a MySQL database using the data1.php file with PDO results in HTML strings being stored in an array, encoded into JSON format, and then sent to the Ajax response function for display on a webpage. However, dealing ...

There is a single div sandwiched between two others, with each of the surrounding divs reaching the edge of the browser

Require a small space between the middle div and the two on each side. The middle bar should have a fixed width. Here is my attempt so far, but it seems messy: <!DOCTYPE html> <html> <head> <style> #container { width: auto; ...

Creating a chic look for your conditional statement: If Else Styling

While it may not be possible to directly style PHP code, you can definitely style the HTML output that PHP generates. I'm curious if there's a way for me to apply styles to the output of an IF ELSE statement. if ($result != false) { print "Y ...

Browser prioritizes Bootstrap over custom CSS styles

I've organized my stylesheet directory like this: stylesheets bootstrap.min.css style.css Within my style.css file, I've made adjustments to the pre tag styling: pre { background-color: #d9edf7; border: #d9edf7; color: navy ...

What is causing my Bootstrap Controls to malfunction?

I'm trying to create a Bootstrap carousel that shows 3 items at once and includes controls to switch between them. The carousel I've made does display the three items, but for some reason, the controls are not responding when clicked. I'm un ...

The error message thrown in Node.js: "Cannot access 'filename' property of undefined object"

Struggling with an issue in nodejs, whenever I try to post with an image, I keep getting the error message "Cannot read property 'filename' of undefined" I've been trying to debug but can't find the root cause of the error. Can someone ...

I am looking to arrange two div elements and one navigation bar into the header, positioning them at the top-left, top-center, and top-right using CSS. How

I'm attempting to arrange three divs within the <header>: div1 (logo) at the top left of the page, nav2 (menu bar) at the top center of the page, and div3 (social networks) at the top right of the page. However, I am unsure of how to achieve thi ...

How can one elevate the properties of each item's sub-structure to the root level in an array containing object items?

I am working with an array containing objects, each with a specific structure... [{ user: { /* ... more (nested) user data ... */ }, vacation: { id: 'idValue', name: 'nameValue', startDate: 'dateValue', }, }, ...

Is it possible for a prop to change dynamically?

I am currently developing a component that is responsible for receiving data through a prop, making modifications to that data, and then emitting it back to the parent (as well as watching for changes). Is it possible for a prop to be reactive? If not, wh ...

tapping on the division and sliding it to and fro

I am trying to achieve a functionality where clicking a div will move another div to the right by 0, and on clicking the div again, the second div will move to the right by -200. However, I am facing issues getting it to work properly. $(document).ready(f ...

Radio buttons failing to transfer any data

I am experiencing an issue with setting values for radio buttons and using the $_POST variable to read the value, but the value being set is empty. <form style="text-align:left;margin-left:80px;" class="form-inline signup" role="form" method="post" act ...