A couple of weeks ago I was given a design by a client where the tabs UI was quite different compared to the default appearance of the well-known ion-tabs
.
When I saw the design my first thought was "oh boy here we go again... another UI challenge that probably will be resolved adding position:absolute
and a bit of sweet sugar courtesy of the border-radius
property.
Like some of you should know, ion-tabs
is one of the most complex components built in Ionic Framework. This web component is smart enough to manage different stack navigation for each tab declared in our template and in our routing module.
The good news is that it's also flexible enough to allow us to customize the appearance with some user-defined styles.
So, after some weird CSS experiments 🌝 the final result ended like this:
To get this design, the following markup was used:
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="home" layout="icon-top">
<ion-icon name="search"></ion-icon>
<ion-label>Explore</ion-label>
</ion-tab-button>
<ion-tab-button tab="wishlists" layout="icon-top">
<ion-icon name="gift"></ion-icon>
<ion-label>Wishlists</ion-label>
</ion-tab-button>
<ion-tab-button tab="groups" layout="icon-top">
<ion-icon name="people-circle"></ion-icon>
<ion-label>Groups</ion-label>
</ion-tab-button>
<ion-tab-button tab="account" layout="icon-top">
<ion-icon name="person"></ion-icon>
<ion-label>Account</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
Nothing fancy here. This structure will be very familiar if you already have experience working with tabs in Ionic.
The real magic happens in the component styles file.
First, I targeted the ion-tab-bar
element. Since I only needed it to move it slightly from the bottom, I set the position
and the bottom
property to relative
and 20px
, respectively.
Also, the tabs shouldn't fill the whole width, so I modified the width
property to 92%
and added margin: 0 auto
to align the element horizontally. Finally, I also set border-radius: 16px
to get that nice corners.
The last thing was to add a line indicator right above the selected tab. For our fortune, the .tab-selected
class is brought automatically by Ionic, so just by using the pseudo-selector ::before
I was able to add the desired indicator.
By default, the line indicator will be transparent for all the ion-tab-button
, except the one with the .tab-selected
class.
ion-tab-bar {
bottom: 20px;
position: relative;
border-radius: 16px;
width: 92%;
margin: 0 auto;
}
ion-tab-button {
--color: var(--ion-color-medium);
--color-selected: var(--ion-color-primary);
&::before {
background-color: transparent;
display: block;
content: "";
margin: 0 auto;
width: 20px;
height: 2px;
}
&.tab-selected::before {
background-color: var(--ion-color-primary);
}
}
Demo:
Top comments (4)
Love that, indeed there are not many examples styling ion-tab component, it's been difficult even finding this one. Would it be possible to erase the under tab-bar component? If you change the list colour to e.g.: red, you will be able to see what I try to explain. It's like a div holder for the tab-buttons. I know it's been a year but will be nice to know how to modify this element since it's no accessible from inspector!!
LOVED IT!
Nice feature! I just set the position on
ion-tab-bar
to absolute so the content can scroll behind the tabs making full use of the screen! Thanks for this tutorial.lol you can just do this
&.tab-selected {
border-top: 2px solid var(--ion-color-primary);
}