Translucent Tabs in Ionic 4
Tags: ionic, angular, translucenttabs, react
Published: 2019-09-24 07:06:13

# What are Translucent Tabs?

Translucent tabs are a visual enhancement to native tab layouts that allow the contents of the view to bleed through the tab bar with a blurred effect. It's best utilized when your application has rich visuals and colors that can be visually depicted through the tab bar. 

## Ionic Core Support

If you're curious why Ionic doesn't support this out of the box, the answer is that they kind-of do. The translucent flag on the tab bar does update the styling of the tab bar to be semi-transparent. Unfortunately the way the tabs were architected, makes the tab-bar a sibling to the contents; which prevents the contents from naturally scrolling underneath the tab bar. 

Here's a few open issues to track when Ionic will officially support translucent tabs:

- https://github.com/ionic-team/ionic/issues/17676
- https://github.com/ionic-team/ionic/issues/17201

## Work-around

Let's get started with a workaround to add the translucent effect to your application. Be aware that this method requires a little extra styling configuration to your pages where you are using bottom fixed positioning (i.e. ion-fab).

#### Translucent Effect

Add the `translucent` property binding on the `ion-tab-bar` to be `true` to enable the styling presets set by the Ionic Core team.

```html
<ion-tabs>
    <ion-tab-bar [translucent]="true" slot="bottom">
       <!--- Your Tabs --->
    </ion-tab-bar>
</ion-tabs>
```

This will allow the color of the content to pass through the tab bar. Unfortunately the contents will not scroll under the tabs, so next let's adjust the positioning of the tab bar.


#### Absolute Positioning

In the component that is containing the `ion-tabs` component, apply the following style.

```scss
ion-tab-bar {
    // Translucent positioning effect
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
}
```

This will make the tab-bar "pop out" of the view and always rest at the bottom of the app's container. Great! Now the contents will display under the tab bar with a translucent effect. The next problem you will face is that since you have removed the tab-bar from the viewport sizing, the bottom of your contents will always be hidden under the tab bar and preventing the user from interacting with them. 

#### Offsetting Content Container

Now I guarantee there is a better way of handling this manipulation, but I needed a quick way to pierce the lazy-loaded router-outlets and modify the contents of the page without manually applying a class to every page or applying the same styling overrides to each page.

In your component containing the `ion-tabs`, implement the `AfterViewInit` life cycle hook and apply the following mark-up.

```tsx
@ViewChild(IonTabs, { static: true }) ionTabs: IonTabs;

ngAfterViewInit() {
    this.overrideTabContainer();
}

private overrideTabContainer() {
    setTimeout(() => {
        const routerOutlet = (this.ionTabs.outlet as any).nativeEl as HTMLElement;
        const container = routerOutlet.querySelector('ion-content');
        if (container) {
             container.style.setProperty('--padding-bottom', '90px');
        }
    });
}
```

This code will find the `ion-content` inside the lazy-loaded tab and override the padded bottom to a size that is greater than the tab bars height. You could manually pull the `clientHeight` of the tab bar here instead of supplying a static value. 


#### Gotcha's 

Since the `ion-tab-bar` is now resting at the bottom of the view, commonly position fixed elements will display on the tab bar and/or under the tab bar. An instance of this will be with the `ion-fab` and `ion-footer`. To get around this, you will need to create a global style that applies the same offset that we use for the padding-bottom, to the positioning of the elements.

i.e:

```scss
// Used for the translucent tabs
ion-fab, ion-footer {
    bottom: 90px;
}
```

## The Result

![Translucent Tabs Image](https://i.gyazo.com/89b8cdf826349b45483d008673c62675.gif)