When adding classes using Angular's ng-class, CSS3 transitions are not activated

After creating a custom modal directive in Angular, I am encountering an issue with the transition animation not working as expected. Within my directive's isolated scope, there is a method called toggleModal() that toggles the modalState between true and false. While the functionality works fine, the animation does not.

HTML:

<span class="glyphicon glyphicon-edit" ng-click="toggleModal()"></span>
<div class="annotation-panel"
     ng-class="{'annotation-panel-active' : modalState == true, 'annotation-panel-inactive' : modalState == false}">
    <div class="annotation-modal" ng-class="{'active':modalState == true, 'inactive':modalState == false}">

        <button type="button" class="btn btn-default" ng-click="toggleModal()">Close</button>
    </div>
</div>

CSS:

.annotation-panel{
  display: none;
  position: fixed;
  top:0;
  left:0;
  z-index: 1000;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
  display: block!important;

}
.annotation-panel-inactive{
  display: none!important;
}
.annotation-modal{
  position: fixed;
  z-index: 1001;
  left:10vw;
  top: 0;
  width: 80vw;
  height: auto;
  overflow-y: scroll;
  opacity: 0;
  background-color: whitesmoke;
  transition: all 0.5s linear;
}
.annotation-modal.active{
  top: 10vh;
  opacity: 1;
}
.annotation-modal.inactive{
  top: 0;
  opacity: 0;
}

Through the use of ng-class, I am switching between the .active and .inactive classes. However, it appears that the transitions are not properly animating the class changes. I suspect there may be a mistake in my approach, but I am unable to identify it. I have refrained from using ngAnimate to avoid unnecessary dependencies since I am developing a module, hence opting for a custom solution with classes instead.

Answer №1

When the state changes to inactive, you are instantly hiding the annotation-panel by using display: none. This causes the contained annotation-modal to become invisible as well.

To avoid this issue, you can utilize ng-animate to apply ng-hide only after the animation is complete.

If you prefer not to use ng-animate, there is an alternative method where you move the panel offscreen to hide it once the animation finishes. In this solution, the transition-delay in the inactive state should match the animation length of the modal fadeout. Additionally, having the transition only on the inactive state ensures that when the panel becomes active, it moves instantly into view.

.annotation-panel{
  position: fixed;
  top: -2000px;
  left: 0;
  z-index: 1000;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
  top: 0;

}
.annotation-panel-inactive{
  transition-property: top;
  transition-delay: 0.5s;
  transition-duration: 0s;
}

.annotation-panel{
  position: fixed;
  top: -2000px;
  left: 0;
  z-index: 1000;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
  top: 0;

}
.annotation-panel-inactive{
  transition-property: top;
  transition-delay: 0.5s;
  transition-duration: 0s;
}
.annotation-modal{
  position: fixed;
  z-index: 1001;
  left:10vw;
  top: 0;
  width: 80vw;
  height: auto;
  overflow-y: scroll;
  opacity: 0;
  background-color: whitesmoke;
  transition: all 0.5s linear;
}
.annotation-modal.active{
  top: 10vh;
  opacity: 1;
}
.annotation-modal.inactive{
  top: 0;
  opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<span class="glyphicon glyphicon-edit" ng-click="modalState =!modalState">click</span>
<div class="annotation-panel"
     ng-class="{'annotation-panel-active' : modalState == true, 'annotation-panel-inactive' : modalState == false}">
    <div class="annotation-modal" ng-class="{'active':modalState == true, 'inactive':modalState == false}"> helloo

        <button type="button" class="btn btn-default" ng-click="modalState = false">Close</button>
    </div>
</div>
</div>

Answer №2

If you need to hide an element, consider using ng-hide for making it display none.

Check out these CSS animations for achieving that:

//
// See a live demonstration at the end of this page
//
.my-element.ng-hide-add, .my-element.ng-hide-remove {
 /* Ensure all styling is properly applied during show/hide animation */
    transition: 0s linear all;
 }

 .my-element.ng-hide-add-active,
 .my-element.ng-hide-remove-active {
    /* Define the transition in the active class */
    transition: 1s linear all;
  }

  .my-element.ng-hide-add { ... }
  .my-element.ng-hide-add.ng-hide-add-active { ... }
   .my-element.ng-hide-remove { ... }
   .my-element.ng-hide-remove.ng-hide-remove-active { ... }

For more information, visit animations

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

Monitoring $scope modifications within a directive: A simple guide

I am currently working with a directive that looks like this: app.directive('selectedForm', function(MainService) { return { scope: { formName: '=currentForm' }, restrict: 'E', ...

Utilize only certain JSON properties within JavaScript

I have access to an array of JSON objects. [ { Id: "1", StartNo: "1", ChipNo: "0", CategoryId: "0", Wave: "0", Club: "", FirstName: "Lotta", LastName: "Svenström", FullName: "Lotta Svenström", ZipCode: "24231" }, {...} ] My goal is to create a new data ...

Ways to ensure that a div, header, container, and other elements completely cover the viewport

Currently, I am attempting to create a header that spans the entire viewport regardless of screen size. This header will be split horizontally into 3 equal sections, each occupying one third of the header space. I experimented with setting the header hei ...

Tips for speeding up the loading of JSON with large data on HTTP requests or webpages

When requesting the page (via HTTP or webpage), it seems to be very slow and even crashes unless I load my JSON data with fewer entries. This issue is critical as I anticipate needing to work with large amounts of data frequently in the future. Below are t ...

Adjusting the font size in Bootstrap grid rows to include an offset

I am currently working on improving site navigation using the Bootstrap Grid system. My goal is to create a layout with 3 columns and two rows structured as follows: |Title | |Login| |Subtitle|Menu buttons| | Everything seems to be functi ...

Where can I locate a specific child element in this scenario?

Currently, I am exploring the possibilities of integrating AngularJS into my application and have encountered a question regarding the click event implementation. Within my HTML code: <div ng-click='clickMe()' ng-controller='testCtrl&ap ...

Swap out the content in a text input box with the text chosen from a suggested autocomplete option

I am working on a text input box with auto-complete options displayed below it. I want to enable users to navigate through the options using keyboard arrows and "select" one, causing it to change color. How can I update the text in the input box with the s ...

When positioning 2 divs on top of each other, rotating one by 180 degrees causes it to be considered secondary in the visibility hierarchy. What is the reason behind this?

While delving into the realm of HTML, I stumbled upon a concept that has left me perplexed. Upon stacking two divs on top of each other, I observed an interesting phenomenon where rotating the second div by 180deg (i.e transform:rotateY(180deg)), causes t ...

How can I empty the value of a UI widget (such as an input field, select menu, or date picker) in Webix UI?

Is there a way in Webix UI to clear widget values individually, rather than collectively based on form id? I'm looking for a method using a mixin like $$(<form-id>).clear(). I need control of individual elements, so is there a proper way to res ...

AngularJS UI-Router: Setting a Default Child State with UI-Sref

Within my ui-router state provider, I have set up the following states: $urlRouterProvider.when('/parent', '/parent/child'); $stateProvider.state('parent', { url: "/parent", abstract: true }); $stateProvider.state( ...

Is there a way to dynamically switch between AngularJS modules based on a configuration change?

Understanding the inner workings of Dependency Injection with AngularJS modules has sparked an idea in my mind. I thought about leveraging this concept to switch between different modules based on the environment of the application. For instance, I aim to ...

AngularJS allows users to easily navigate between different web pages by using tabs

I have created this Angular JS code to display tabs that open specific URLs when clicked. Can someone please assist me with making the tabs functional? <html ng-app="blp_tabs"> <head> <script src="http://ajax.googleapis.com/ajax/libs/angula ...

Finding the variable with the highest value using AngularJS

I have a variety of variables with different values assigned to them, such as: Weight_gain = 0.01 Weather_gain = 0.02 and many more like these. My goal is to determine the variable name with the highest assigned value. When I attempt this using code, it ...

Accordion menu causing Javascript linking problem

After following a tutorial, I managed to create an accordion menu in JavaScript. In the current setup, each main li with the class "ToggleSubmenu" acts as a category that can hide/show the sub-lis. Now, my query is this: How can I retain the link functio ...

Generate a dynamic chart using Angular-chart.js on a canvas that is created on the fly

I am facing an issue with displaying a chart or table in a div based on an XHR response. In the case of a chart, I want to replace the div contents with a canvas element that will be used by chart.js to show a graph. When I directly include the canvas ele ...

Component does not support camelCase names

My current challenge involves creating a navbar component where I need to share some data from the main page to the component. After spending several hours researching how to use components, I have been unable to find an explanation as to why camelCase var ...

Toggle the visibility of an element with a single button click

Below is a snippet of my sample code: SAMPLE HTML CODE: <ul> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <l ...

The dimensions of the window - creating divs within td elements - the appearance of scroll

Here is the HTML code that I am working with: <table> <tr> <td class='tclone' id='clone'></td> <td class='loader' id='loader'> <div id='tdiv& ...

The outsideClick feature in the uib-dropdown is malfunctioning

One issue I'm experiencing is that, when I set auto-close to outsideClick, the dropdown always closes even when I click on an element within it. <div class="v3-multiselect" uib-dropdown ng-cloak auto-close="outsideClick" is-open="isOpen"> < ...

The ease of use and availability of radio buttons

When clicking on the first or second value of the radio button, it selects the first option. Here is the HTML code: @supports(-webkit-appearance: none) or (-moz-appearance: none) { input[type='radio'], input[type='checkbox'] { ...