Angular Material Rotate Ink Bar to Vertical Orientation

After wanting to change the orientation of Angular Material's Tab Component to vertical, I visited this page (Tabs) and experimented with the CSS. By making the necessary adjustments, I successfully displayed the tabs vertically using the following CSS:

.mat-tab-group {
    display: flex;
    flex-direction: row!important;
}
.mat-tab-labels {
    display: flex;
    flex-direction: column!important;
}

However, the mat-ink-bar remained at the bottom as expected: https://i.stack.imgur.com/fM7Y3.png

I am now wondering how I can rotate the bar to be vertical and position it at the right side of the tab labels while keeping its transition intact.

My current solution involves rotating the bar 90 degrees clockwise and aligning it properly on the right side. Additionally, adjusting the width of the bar to match the height of the tabs could create a more seamless display.

Answer №1

Since no one has provided any code samples, I'll share mine as I was able to figure it out. Credit to the previous answer for the inspiration.

This is how I approached it:

Add the following SCSS code either globally or in the necessary location (If you need basic CSS conversion, that's up to you):

mat-tab-group[vertical] {
  flex-direction: row;

  ::ng-deep mat-tab-header {
    flex-direction: column;
    border-bottom: 0px solid transparent;
    border-right: 1px solid rgba(0, 0, 0, 0.12);

    .mat-tab-label-container {
      flex-direction: column;

      .mat-tab-labels {
        flex-direction: column;
      }

      mat-ink-bar {
        left: initial !important;
        bottom: initial;
        right: 0;
        width: 2px !important;
        height: initial;
      }
    }
  }

  ::ng-deep .mat-tab-body-wrapper {
    flex-direction: column;
    width: 100%;
  }
}

:host-context(.dark) mat-tab-group[vertical] ::ng-deep mat-tab-header {
  border-right: 1px solid rgba(255, 255, 255, 0.12);
}

Next, make these modifications to your component TypeScript file. You can place this in your main app component TS if vertical tabs will be used frequently; otherwise, add it to each relevant component:

Firstly, implement the DoCheck interface and include the following function:

ngDoCheck() {
  document.querySelectorAll("mat-tab-group[vertical]").forEach((verticalTabGroup: HTMLElement) => {
    let inkBar: HTMLElement = verticalTabGroup.querySelector("mat-ink-bar");
    if (!inkBar) {
      return;
    }
    let active: HTMLElement = verticalTabGroup.querySelector(".mat-tab-label-active");
    if (!active) {
      return;
    }
    inkBar.style.top = `${active.offsetTop}px`;
    inkBar.style.height = `${active.offsetHeight}px`;
  });
}

There might be a more efficient way to achieve this in Angular, but coming from a traditional vanilla background, I'm still learning,

One issue remaining is that the tab body may still scroll horizontally when switching tabs. This appears to require altering CSS transform styles through JavaScript, making it difficult to adjust without modifying the original mat-tab-group source code.

Please note that my testing was limited to a basic tab group. I cannot guarantee that pagination arrows will function correctly with this setup. That task is left for the developer who requires it.

For those interested, a potential challenge could involve rotating the entire tab group using CSS transforms, then counter-rotating the tab labels and bodies to recreate the vertical orientation. In theory, this approach should maintain ink bar and body transitions. However, it may be unnecessary complexity.

Answer №2

In my opinion,

<mat-ink-bar class="mat-ink-bar" style="visibility: visible; left: 160px; width: 160px;"></mat-ink-bar>

the key element that requires modification is the one mentioned above. Instead of using left positioning, it is recommended to utilize top and bottom positioning based on the image provided. This adjustment cannot be achieved solely through CSS as the left position changes dynamically when a tab is tapped or clicked. In your CSS file, make sure to include the following code:

.mat-ink-bar {
position: absolute;
bottom: 0;
width: 2px;
transition: .5s cubic-bezier(.35,0,.25,1);

Additionally, consider changing 'height' to 'width' with a value of 2px, while setting the height to match that of the .mat-tab-label.

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

I'm having trouble getting the height of my div element to render in percentage (%) in the CSS. Can anyone assist me with this issue?

When I try to set the "height" CSS property in percentage (%) for a div element, the HTML doesn't render anything. However, if I set the "height" CSS property using length values such as px or cm, it works perfectly fine. Can anyone provide assistance ...

Looking for a logo placed in the center with a top fixed navigation using Bootstrap

I am in need of a Centered Logo using Bootstrap fixed top navigation. The goal is to have the brand centered within the navigation. Check out my Sample Fiddle .LandPageNavLinks { list-style-type:none; margin:0; padding:0; } .LandPageNavLin ...

Arranging Radio Buttons in a Row and Aligning a Radio Input Group Side by Side using Bootstrap 5

"I'm having a little issue with aligning radio buttons and a radio input group inline on the same line. The input group keeps moving to a new line for some reason. Can anyone help?" Below is the code snippet: <div class="d-flex flex ...

Switch the Header Image on a Page in WordPress

I am currently using the Sunrise Theme from s5themes.com and I have a question regarding the header image on individual pages. It seems that all pages are displaying the same header image as the homepage, which is not what I want. Attached below is a scre ...

I wonder where this unique design originated from on my webpage?

This is a screenshot of Chrome Developer Tools that shows the styling information. Usually, the style is clearly defined in a specific CSS file (like in this screenshot, datepicker.css). I am attempting to modify the styling at the very top of the screens ...

What is the best way to minify and concatenate multiple CSS files only after converting SCSS to CSS with Gulp?

When attempting to convert my scss files to css files using gulp, I encountered an issue. After writing the scss code, it is easily converted to css. However, I wanted to minify this css and save it in a different folder called 'min'. Within the ...

Is there a way to ensure that the size of the second div box can adjust dynamically in CSS?

Is there a way to make multiple boxes expand dynamically in size when one of them contains more words? Currently, the problem is that only the box with more text expands while the others remain unchanged. I want all the boxes to follow the same size dynami ...

Struggling to place the sans-serif font right at the edge of the H1 tag

Encountering a strange issue that suggests I might be overlooking something simple. Any thoughts on the following: I have a heading tag styled with a sans-serif font (loaded from Google fonts) and when I apply a background-color, the text does not align t ...

Utilize dynamically generated form fields to upload multiple files at once

Currently, as I delve into learning the MEAN stack, I am encountering difficulties with file uploads. Specifically, within a company form: this.companyForm = this.fb.group({ trucks: this.fb.array([]), ... }); The 'trucks' field i ...

Is there an npm package that functions like Google's page translator?

Is there an npm package that serves a similar purpose to Google Page Translator? I've integrated it into my Angular project, but I'm curious if there is a version available as an npm package. Click here for image description ...

Modify the disabled background color of the mat-form-field component in Angular version 15

Is there a way to customize the background color and outline of disabled text input in Angular 15? I attempted using mdc-text-field--disabled and overriding the outline CSS, but it had no effect. Current appearance when disabled .mat-mdc-input-element { ...

Create an unordered list using the <ul> tag

Creating a ul as input is my goal, similar to this example on jsfiddle: http://jsfiddle.net/hailwood/u8zj5/ (However, I want to avoid using the tagit plugin and implement it myself) I envision allowing users to enter text in the input field and upon hitt ...

The flex grow animation fails to activate when the Bootstrap 4 style sheet is added

Trying to implement transitions with flex grow has been a challenge. It works smoothly without any issues, but as soon as I add the bootstrap 4 style sheet, the transitions stop working. I haven't even started using the bootstrap 4 classes yet, it&apo ...

Fluid div causing navigation to display improperly

I am currently working on a navigation design where I want to have an image above each list item instead of having individual images for each item. It looks great when the screen is at full size, but as soon as I minimize it, the list items start stacking ...

What is the process for altering the color of an HTML output depending on its values?

I created a simple HTML code to showcase some outcomes. The possible results are SUCCESS, Failure, and Still Failing. I want these results to be displayed with corresponding colors, such as green for SUCCESS, and red for both Failure and Still Failing. I ...

Ways to conceal a division within the Repeater

Currently, I am developing a VB ASP.NET site using Visual Studio 2012 Express for Web. Within my project, there is a Repeater containing two div elements with the css classes .dnnFormLabel and .dnnFormItem. Here is a snippet of code from the Repeater: < ...

Obtain the precise number input by the user

Seeking assistance with Angular, I am encountering an issue in my application where users input a specific budget (e.g. 18278.85) into a form. However, after submission, the displayed number is rounded to 18278.8 which is not the desired outcome. How can I ...

Is it possible to incorporate a Material-UI theme palette color into a personalized React component?

My custom Sidebar component needs to have its background color set using Material-UI's primary palette color. Sidebar.js import styles from '../styles/Home.module.css'; export default function Sidebar() { return ( <div className={ ...

Achieving a tidy layout with child divs inside a parent div

I'm struggling to figure out how to arrange objects with margins inside a parent div. Initially, I thought using float would do the trick, but I quickly realized it wasn't the solution. This results in an unsightly amount of space. The divs that ...

How to set a canvas as the background of a div element

Check out my code snippet below: <!DOCTYPE html> <html> <body> <div id='rect' style='width:200px;height:200px;border:1px solid red'> </div> <canvas id="myCanvas" style="borde ...