Angular 4 animation for smooth sliding down

Attempting to add animation to my webpage has presented a challenge:
I have a content div on my page, along with a button that triggers the opening of another div above the content. My goal is to have this top div fade and slide into view while simultaneously having the content div slide down or up. Although I managed to create the desired animation for the div that appears upon clicking the button, I am unsure how to handle the content div as shown in the code snippet below:

<div class="wrapper">
  <button (click)="animated = !animated"></button>
  <div *ngIf="animated" [@slideInOutAnimation] class="animated-div">
  THIS DIV IS ANIMATED</div>

  <div class="content">THIS IS CONTENT DIV</div>

</div>

TYPESCRIPT:
animations: [
trigger('slideInOutAnimation', [

  state('*', style({

  })),
  transition(':enter', [
    style({
      transform: 'translateY(-10%)',
      opacity: 0
    }),
    animate('.5s ease-in-out', style({
      transform: 'translateY(0)',
      opacity: 1
    }))
  ]),
  transition(':leave', [
    animate('.5s ease-in-out', style({
      transform: 'translateY(-10%)',
      opacity: 0
    }))
  ])
])
]

Do I need to create an additional trigger to move my content div along with the animated one?

Answer №1

To begin, make sure to establish a file where your animations are defined and exported. This will help clarify things in your app.component.ts

In this particular scenario, I have set the max-height of the div to transition from 0px (when hidden) to 500px. However, feel free to adjust this according to your specific requirements.

The animation utilizes states (in and out) that switch when the button is clicked, triggering the animation.

animations.ts

import { trigger, state, style, transition,
    animate, group, query, stagger, keyframes
} from '@angular/animations';

export const SlideInOutAnimation = [
    trigger('slideInOut', [
        state('in', style({
            'max-height': '500px', 'opacity': '1', 'visibility': 'visible'
        })),
        state('out', style({
            'max-height': '0px', 'opacity': '0', 'visibility': 'hidden'
        })),
        transition('in => out', [group([
            animate('400ms ease-in-out', style({
                'opacity': '0'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '0px'
            })),
            animate('700ms ease-in-out', style({
                'visibility': 'hidden'
            }))
        ]
        )]),
        transition('out => in', [group([
            animate('1ms ease-in-out', style({
                'visibility': 'visible'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '500px'
            })),
            animate('800ms ease-in-out', style({
                'opacity': '1'
            }))
        ]
        )])
    ]),
]

Next, in your app.component, import the animation and create a method that toggles the animation state.

app.component.ts

import { SlideInOutAnimation } from './animations';

@Component({
  ...
  animations: [SlideInOutAnimation]
})
export class AppComponent {
  animationState = 'in';

  ...

  toggleShowDiv(divName: string) {
    if (divName === 'divA') {
      console.log(this.animationState);
      this.animationState = this.animationState === 'out' ? 'in' : 'out';
      console.log(this.animationState);
    }
  }
}

Here's what your app.component.html would resemble:

<div class="wrapper">
  <button (click)="toggleShowDiv('divA')">TOGGLE DIV</button>
  <div [@slideInOut]="animationState" style="height: 100px; background-color: red;">
  THIS DIV IS ANIMATED</div>
  <div class="content">THIS IS CONTENT DIV</div>
</div>

slideInOut corresponds to the animation trigger outlined in animations.ts

Check out this StackBlitz example I crafted: https://stackblitz.com/edit/angular-muvaqu

Just a quick note: If an error prompts you to include BrowserAnimationsModule, simply import it in your app.module.ts:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports: [ ..., BrowserAnimationsModule ],
  ...
})

Answer №2

When it comes to handling height transitions, I find the wildcard operator to be quite useful for accommodating dynamic content heights.

// Setting up transitions based on true/false states using 0 and 1 values

trigger('slideUpDown', [
  state('0', style({ 'max-height': '*', opacity: 1 })),
  state('1', style({ 'max-height': '0px', opacity: 0 })),
  transition(':enter', animate('400ms ease-in-out')),
  transition('* => *', animate('400ms ease-in-out')),
])

To implement this:

<div #someDiv [@slideUpDown]="someDiv.state"></div>

Elsewhere in your code or template, you can toggle the state with a button click.

<button (click)="someDiv.state = !someDiv.state"></button>

Answer №3

If you want to add a smooth slide down animation in your Angular 2+ project, here's a simple and elegant way to do it.

animation.component.ts

import { animate, style, transition, trigger } from '@angular/animations';
@Component({
  animations: [
    trigger('slideDownUp', [
      transition(':enter', [style({ height: 0 }), animate(500)]),
      transition(':leave', [animate(500, style({ height: 0 }))]),
    ]),
  ],
})

animation.component.html

<div @slideDownUp *ngIf="isVisible" class="box">
  This is the content within the div!
</div>

animation.component.scss

.box {
  overflow: hidden;
}

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 align the navigation bar in the center using Bootstrap?

Let's discuss the code snippet provided below. I am looking to use Bootstrap to center this dropdown menu on the left side of the screen. Here is the screenshot for reference: . Any suggestions on how I can achieve this? Also, I would like to know h ...

Is it permissible to utilize the ::Before::Before element?

While working on a CSS file for a page with a non-editable profile, I encountered the challenge of not being able to add content directly. This limitation prompted me to explore alternative solutions. My idea was to utilize the page ID and incorporate it ...

Is it necessary for me to develop an Angular library in order to release a basic TypeScript class that makes use of Angular components?

In one of my Angular projects, I have a Typescript class called APIResponse that I want to convert into an NPM package for use in other projects. This class is not specific to Angular like a Service or Component. After doing some research on creating non-A ...

Where should the transformation of server response data into a format that the component can interpret be done within the NgRx framework?

New to NgRx and feeling a bit confused at the moment. I have a basic component that displays a list of objects, in this case Orders, retrieved from the backend using an Effect. The challenge is to transform the response from the backend into a simplified l ...

Count of elements in one flexbox row

Having a flexbox container with multiple items in row-wrap format, is there a way to use JavaScript to determine the number of items in each row? Essentially, finding out at what point they wrap. For instance- <div class="container"> <div clas ...

The functionality of -moz-background-clip:text is not functioning properly on Firefox browsers

Struggling to incorporate an image into a text within an h1 tag. Here's what I've attempted: <div class="image_clip"> <h1> MY WONDERFUL TEXT </h1> </div> In the CSS file: .image_clip{ background: url(../images/defa ...

Blending a background image with CSS

I've set a background image for the div, which is also used for responsive design. Check out the demo My goal is to ensure that the image doesn't appear cut off in the responsive view. I'm looking for a CSS solution to blend the image wit ...

Setting column heights and spacing in Bootstrap

I'm looking to dynamically populate the blocks. Essentially, a for loop would be used to pass the data. However, I'm facing some challenges with the height of the blocks at different screen sizes while utilizing bootstrap 4. My goal is to have th ...

Is there a way to repurpose a function to work with both ids and classes?

My current code is affecting all elements instead of just the intended one. I've experimented with classes and ids, ruling out those as potential issues. I'm hoping for my JavaScript to target only the selected element, not all of them. Check ou ...

Although IE may have issues, @font-face is not functioning properly in Chrome and FireFox

Hello, I've encountered an issue with implementing @font-face in CSS. It seems to be working properly in Internet Explorer, but it has no effect in FireFox and Chrome. I am trying to add a custom font to my website by placing the files Snazanin.ttf an ...

Ways to clear an Angular form after a failed login attempt

Looking for a solution to reset the input fields used to store login PIN from a user. My current code generates a modal error message but I am facing an issue in resetting the PIN input fields under the #inputs id. Take a look at the code snippet below: H ...

The process of assigning a local variable to a JSON response in Angular 2

I need to store a JSON response that includes an array with the following data: 0 : {ID: 2, NAME: "asd", PWD_EXPIRY_IN_DAYS: 30} 1 : {ID: 1, NAME: "Admin", PWD_EXPIRY_IN_DAYS: 30} In my code, I have defined a local variable called groups of type ...

Steps for Adding a JSON Array into an Object in Angular

Here is a JSON Array that I have: 0: {name: "Jan", value: 12} 1: {name: "Mar", value: 14} 2: {name: "Feb", value: 11} 3: {name: "Apr", value: 10} 4: {name: "May", value: 14} 5: {name: "Jun", value ...

Creating smooth and natural movement of a div element using Javascript (rotating and moving)

After struggling to use jquery plugins for smooth motion with the div elements I'm working on, I've decided it's time to seek some assistance. I have a group of div elements that all share a class and I want them to move around the screen c ...

Exploring HTML and CSS backgrounds

I am new to CSS and I have a question regarding design. I want to create a form in the center of my webpage (shown as the black box) with a white background that overlaps the body background (represented by the red lines). For reference, please view this ...

Access the Angular Universal application through a link without specifying a port number

After creating my Angular Universal application, I'm facing an issue where I can only start it by adding the site.com:4000 port to the address. Is there a way to configure it to open without specifying a port? Any guidance on what needs to be done wou ...

The Ineffectiveness of Social Media Sharing in WordPress

I'm encountering an issue with adding social media sharing buttons to my website's product page. Although I've implemented the PHP code, clicking on the Facebook button only redirects to a page displaying a share button and URL, but it doesn ...

Personalize the file button for uploading images

I have a button to upload image files and I want to customize it to allow for uploading more than one image file. What is the logic to achieve this? <input type="file" />, which renders a choose button with text that says `no files chosen` in the sa ...

Choose the default value of the select tag if hardcoded options are used with ngModel

When the value is set by using this.model.type = OPTION_NR1, Angular automatically sets the HTML attribute ng-reflect-model to 0. However, the desired value for this HTML attribute should be OPTION_NR1 in order to populate the drop-down with Option1 instea ...

The misaligned navigation bar and distortion on mobile devices are causing issues with the website's layout

The logo, search bar, cart, login, and sign up are not aligned on the same line. When I try to view it on mobile, distortion occurs. The search bar and other elements get messed up. In mobile view, nothing happens when clicking on the menu collapse butt ...