Incorporate CSS3 transitions along with gradient backgrounds by utilizing the before and after pseudo elements

While this question shares similarities with the one found at Use CSS3 transitions with gradient backgrounds, there is a key difference that makes the answers provided on that thread unsuitable for addressing the issue described here.


In the code snippet below, you'll see a menu button with a background featuring a linear gradient. The intention is for the middle line of this button to fade away when clicked. However, instead of smoothly fading, it abruptly disappears. This unexpected behavior is not what I had in mind. You can view the example either below or through this JSFiddle link

var toggleOpenClose = 0;
var menuButton = $("#bt-menu");

menuButton.click(function() {
  if(toggleOpenClose % 2 == 0) {
    menuButton.removeClass('bt-menu-close').addClass('bt-menu-open');
    menuButton.children(".bt-menu-trigger").children("span").removeClass("close").addClass("open");
  } else {
    menuButton.removeClass('bt-menu-open').addClass('bt-menu-close');
    menuButton.children(".bt-menu-trigger").children("span").removeClass("open").addClass("close");
  }

  toggleOpenClose++;
});

var time = 1;
var timeShortSlide = 0.8;

document.styleSheets[0].addRule(".bt-menu-trigger span.open", "transition: background " + timeShortSlide + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.open:before", "transition: transform " + timeShortSlide + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.open:after", "transition: transform " + timeShortSlide + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.close", "transition: background " + timeShortSlide + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.close:before", "transition: transform " + timeShortSlide + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.close:after", "transition: transform " + timeShortSlide + "s;");
* {
  margin: 0;
  padding: 0;
}

.bt-menu {
  width: 50px;
}
.bt-menu .bt-menu-trigger {
  position: fixed;
  top: 0px;
  left: 0px;
  display: block;
  width: 50px;
  height: 50px;
  cursor: pointer;
}
.bt-menu .bt-menu-trigger span {
  position: absolute;
...
/bt-menu>

When my previous attempts failed to achieve the desired effect, I turned to solutions offered in the linked question. Unfortunately, these also did not provide a satisfactory result as elaborated upon below.

The Opacity Approach
This strategy was ineffective as utilizing pseudo elements :before and :after caused all three lines to simultaneously fade out instead of just the middle line.

The background-position Approach
This method simply did not yield the expected outcome, though the reason behind this eludes me.

I am seeking assistance in resolving the issue of the middle line failing to fade out properly upon clicking the menu button.

Answer №1

There is a clever solution to tackle this issue. Simply make the span transparent, while keeping the :before and :after pseudo-elements as they are. Then introduce a div that will overlay the span. Once you've completed these steps, apply a background gradient to the div and gradually decrease its opacity. This approach will maintain the integrity of the span and achieve the desired outcome.

For instance, modify the HTML code like this:

<nav id="bt-menu" class="bt-menu">
    <a href="#" class="bt-menu-trigger"><span><div></div></span></a>
</nav>

And adjust the SCSS code as follows:

span {
  background: transparent;

  div {
    @include linear(#adadff, left, blue, transparent);
    float: left;
    height: 100%;
    width: 100%;
    opacity: 1;
  }
}

&.bt-menu-open {
  .bt-menu-trigger span {
    div {
      opacity: 0;
    }
  }
}

This leads to a functional example:

var toggleOpenClose = 0;
var menuButton = $("#bt-menu");

menuButton.click(function() {
  if(toggleOpenClose % 2 == 0) {
    menuButton.removeClass('bt-menu-close').addClass('bt-menu-open');
    menuButton.children(".bt-menu-trigger").children("span").removeClass("close").addClass("open");
  } else {
    menuButton.removeClass('bt-menu-open').addClass('bt-menu-close');
    menuButton.children(".bt-menu-trigger").children("span").removeClass("open").addClass("close");
  }

  toggleOpenClose++;
});

var time = 1;
var timeShortSlide = 0.8;

document.styleSheets[0].addRule(".bt-menu-trigger span div", "transition: opacity " + (timeShortSlide * 0.75) + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.open:before", "transition: transform " + timeShortSlide + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.open:after", "transition: transform " + timeShortSlide + "s; transition-delay: " + (time - timeShortSlide) + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.close:before", "transition: transform " + timeShortSlide + "s;");
document.styleSheets[0].addRule(".bt-menu-trigger span.close:after", "transition: transform " + timeShortSlide + "s;");
* {
  margin: 0;
  padding: 0;
}

.bt-menu {
  width: 50px;
}
.bt-menu .bt-menu-trigger {
  position: fixed;
  top: 0px;
  left: 0px;
  display: block;
  width: 50px;
  height: 50px;
  cursor: pointer;
}
.bt-menu .bt-menu-trigger span {
  position: absolute;
  top: 50%;
  left: 0;
  display: block;
  width: 100%;
  height: 4px;
  margin-top: -2px;
  background: transparent;
  font-size: 0px;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.bt-menu .bt-menu-trigger span:before, .bt-menu .bt-menu-trigger span:after {
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  background: #adadff;
  background: -webkit-linear-gradient(left, blue, transparent);
  background: -moz-linear-gradient(left, blue, transparent);
  background: -o-linear-gradient(left, blue, transparent);
  background: linear-gradient(left, blue, transparent);
  content: '';
}
.bt-menu .bt-menu-trigger span:before {
  -webkit-transform: translateY(-250%);
  -moz-transform: translateY(-250%);
  -o-transform: translateY(-250%);
  transform: translateY(-250%);
}
.bt-menu .bt-menu-trigger span:after {
  -webkit-transform: translateY(250%);
  -moz-transform: translateY(250%);
  -o-transform: translateY(250%);
  transform: translateY(250%);
}
.bt-menu.bt-menu-open .bt-menu-trigger span:before {
  -webkit-transform: translateY(0) rotate(45deg);
  -moz-transform: translateY(0) rotate(45deg);
  -o-transform: translateY(0) rotate(45deg);
  transform: translateY(0) rotate(45deg);
}
.bt-menu.bt-menu-open .bt-menu-trigger span:after {
  -webkit-transform: translateY(0) rotate(-45deg);
  -moz-transform: translateY(0) rotate(-45deg);
  -o-transform: translateY(0) rotate(-45deg);
  transform: translateY(0) rotate(-45deg);
}
.bt-menu.bt-menu-open .bt-menu-trigger span div {
  opacity: 0;
}
.bt-menu .bt-menu-trigger span div {
  background: #adadff;
  background: -webkit-linear-gradient(left, blue, transparent);
  background: -moz-linear-gradient(left, blue, transparent);
  background: -o-linear-gradient(left, blue, transparent);
  background: linear-gradient(left, blue, transparent);
  float: left;
  height: 100%;
  width: 100%;
  opacity: 1;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>

<nav id="bt-menu" class="bt-menu">
  <a href="#" class="bt-menu-trigger"><span><div></div></span></a>
</nav>

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

Design a new CSS grid arrangement

Need help with achieving a responsive layout using CSS grid. The design should be as seen in the image link below for resolutions over 900px:- https://i.sstatic.net/QaFub.jpg For resolutions lower than 900px, the layout should switch to resemble this ht ...

Utilizing either Maps or Objects in Typescript

I'm in the process of developing a simple Pizza Ordering App. The concept is, you select a pizza from a list and it's added to a summary that groups all the selections together. Here's how I want it to appear: Pizza Margarita 2x Pizza Sala ...

Utilizing the power of ui-views alongside angularjs ui Tabs to handle inappropriate user input

I recently updated the markup for some forms to utilize the angularJS ui Tabs component. The new markup structure is as follows: <div class="col-lg-3 col-md-3 panel-container"> <tabset vertical="true" type="pills"> ...

Generate a D3.js vertical timeline covering the period from January 1, 2015 to December 31, 2015

I am in need of assistance with creating a vertical timeline using D3.js that spans from the beginning of January 2015 to the end of December 2015. My goal is to have two entries, represented by colored circles, at specific dates within the middle of the t ...

Is there a repeated call detected in the Readable stream node?

The issue at hand Currently, I have encountered a problem with this code snippet. It involves a Readable stream that retrieves movements from the database in a paginated manner, but it seems to be returning duplicate records inexplicably. const read ...

Locate the word or phrase without a comma

I am currently working on a code that involves finding keys with string values separated by commas. var db = { "name": "Nkosana", "middle": "Baryy", "surname": "walked", "batch_number": "test,b", "temp": ",,67,6,87,86,5,67865,876,67" ...

The menu field remains open even after clicking on the menu

I have encountered an issue with my code. Here is a DEMO that I created on jsfiddle.net Currently, when you click on the red div, the menu opens. However, if you click on the menu items, the menu area does not close. What do I need to do in order to clo ...

What is the best way to convert a JavaScript array with nested arrays into a single-level array with all elements at the top level?

Apologies if this question has already been posed, I am struggling to frame it properly so I'll present it in code format. Please note that I cannot alter the original data format and have to work with it as is... My array looks something like this ( ...

The beforeCreate function is failing to execute when a new user is being created

I'm currently working with sailsjs version 0.11.0. My goal is to ensure that when a new user is created, their password is encrypted before being stored in the database. To achieve this, I have implemented the use of the bcrypt library. In my User.js ...

Issue with IE11 not saving specific object value after performing a GET request

I'm encountering a strange issue where Internet Explorer (IE11) is having difficulty saving a specific variable returned from a GET request. This particular variable works fine in other browsers, but seems to be empty in IE. Below you can see a snipp ...

Adjust the number of decimal places shown for a dynamically calculated value in JavaScript

JavaScript Code <script type="text/javascript> function updateTotal() { document.getElementById('total').value = parseFloat(document.getElementById('cheque').value) + parseFloat(document.getElementById('cash&apos ...

WebdriverIo- Focus remains outside the browser after closing a pop-up window

Trying to automate a scenario, but encountering an issue where execution stops after step 3. Entering username/password on login page Clicking submit button opens a pop-up window, entering data in input box on pop-up window and clicking the OK button Pop- ...

The selected item is not being determined in the dropdown due to the AJAX response from the

Trying to create a functional dropdown, but encountering an issue where the first value of the second dropdown cannot be selected after using html(). Below is the code snippet: Check out the dependable dropdown image https://i.sstatic.net/nZsSL.png Here ...

What is the best way to connect a chosen observable to a freshly inserted item?

I'm completely new to knockout. I have this sample set up where it will: Fill the left box with a list of items When you select an item in the left box, display its details in the right box Seems like everything is working fine so far. But I want t ...

Selector for CSS variant of target button in Material UI

For each type of Material UI button variant, I have created 3 classes that apply a gradient: gradient, outlinedGradient, and containedGradient, https://i.sstatic.net/paMvR.png Instead of having to manually change the gradient class when altering button s ...

I'm currently working with ReactJS and attempting to retrieve JSON data from a REST API in JIRA, but I'm facing challenges in achieving this

I've been struggling for hours trying to understand why I am unable to access and transfer data in my array from the JSON data in JIRA using the REST API. Basically, I am attempting to retrieve the JSON data from the JIRA website via URL with Basic Au ...

The revised document now exceeds 16,777,216 in size

When attempting to add new data to an array using mongoose, I encountered two errors. Here is the code snippet in question: return await db.fileMeta.findOneAndUpdate({ username: username, 'files.fileUID': { $ne: data.fileUID } ...

Add a new element to the page with a smooth fade-in animation using jQuery

var content = "<div id='blah'>Hello stuff here</div>" $("#mycontent").append(content).fadeIn(999); Unfortunately, the desired effect is not achieved with this code. I am trying to create a sleek animation when adding new content. ...

Creating custom hollow cylinder geometries in Three.js

I am looking to design my own unique geometry for hollow cylinders using three.js. I have attempted to blend elements from the RingGeometry and CylinderGeometry classes, but encountered some visual issues: The cap normalization is incorrect (both caps on ...

Struggling to integrate the navigation bar with Wordpress platform

For a while now, I have been facing challenges with the navigation bar on the WordPress theme I am currently creating. I am struggling to get the navigation bar to display correctly. Below is the code snippet from my header.php file: <body> &l ...