Tab animation using Angular
Tags: angular, html, css, typescript
Published: 2020-11-13 06:07:16

I assume if you are going through this post then you have some idea about angular Framework basic HTML and CSS.

still, let's start from the beginning, open your preferred terminal.

npm install -g @angular/cli
ng new my-app
cd my-app
remove all the boilerplate content from app.component.html and at the app TS file I have taken an array of tabs.

```
<div class="main_container">
  <div class="tabs_container">
    <div
      class="tab"
      [class.active]="tab.tabId === selectedTabId"
      (click)="handelTabChange(tabRef.getBoundingClientRect());selectedTabId = tab.tabId"
      #tabRef
      *ngFor=" let tab of tabs"
    >
      {{tab.tabName}}
    </div>
  </div>
  <span #panelRef class="active_panel"></span>
</div>
```
here I am iterating the tabs array and showing the tabs name .active_panel class is the one which should show under the active tab.
```
#tabRef takes the reference for each tab.
#panelRef reference of the active panel
(click)="handelTabChange(tabRef.getBoundingClientRect())
handelTabChange function gives the width,height and position of the clicked tab. 
```
That all we need for the HTML let's move to TS now.

```
  @ViewChild("panelRef", { read: ElementRef })
  panelRef: ElementRef; // panel reference 
  @ViewChildren("tabRef", { read: ElementRef }) 
  tabRef: QueryList<ElementRef>; // tabs reference Query List
```

```
  ngAfterViewInit() {
    const firstChild = this.tabRef.toArray()[0];
   // I want to show the first child of the tab as selected
   // so 0th index is going to be the first one
    const firstChildPosition = 
    firstChild.nativeElement.getBoundingClientRect();
   // here I am storing the position of the first child.
    this.renderer.setStyle(
      this.panelRef.nativeElement,
      "width",
      `${firstChildPosition.width}px`
    );
   // giving same width as tab label to the active panel
    this.renderer.setStyle(
      this.panelRef.nativeElement,
      "left",
      `${firstChildPosition.left}px`
    );
   // setting same left position as the first child to panel
  }
```

Now when the page will load it will look for the first tab and the active panel will take the same width and left position.

```
  handelTabChange(tabRef: DOMRect) {
    this.renderer.setStyle(
      this.panelRef.nativeElement,
      "left",
      `${tabRef.left}px`
    );
    this.renderer.setStyle(
      this.panelRef.nativeElement,
      "width",
      `${tabRef.width}px`
    );
  }
```
Kinda doing the same thing as explained above but now when the user clicks on the tabs.
```
.main_container {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.tabs_container {
  width: 100%;
  display: flex;
  justify-content: space-around;
}
.tab {
  font-size: 18px;
  cursor: pointer;
  margin-right: 10px;
  text-align: center;
  margin: 5px;
  transform: scale(0.95);
}
.active {
  color: gray;
  transform: scale(1);
}
.active_panel {
  position: relative;
  height: 5px;
  background-color: cyan;
  transition: all 400ms ease-in-out;
  border-radius: 10px;
}
```
Required CSS for this one

live link for the demo https://angular-tab-animations-u6421j.stackblitz.io