DEV Community

Cover image for Tab animation using Angular
Bibhu Padhy
Bibhu Padhy

Posted on

Tab animation using Angular

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>
Enter fullscreen mode Exit fullscreen mode

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. 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  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
  }
Enter fullscreen mode Exit fullscreen mode

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`
    );
  }
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Required CSS for this one

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

Top comments (0)