Customize Tab indicator styling in Material-UI

Currently, I am attempting to customize the MUI tab by changing the indicator from a line to a background color. Through my research, I discovered that using TabIndicatorProps and setting a style of display:none eliminates the indicator completely. However, when I try

backgroundColor:"color"
, the line color changes but I'm struggling to make it span the entire background instead of just a line.

I experimented with some potential solutions, such as adding height:100% to the TabIndicatorProps, which resulted in creating the background but obscured the text within the tab. Likewise, applying opacity: .8 gave me the desired effect, but the text became too dark and I was unable to adjust it for active tabs.

Expected Tab Image Current Tab Image

<Box sx={{ width: '100%', bgcolor: 'background.paper' }}>
            <Tabs TabIndicatorProps={{
                style: {
                    backgroundColor: '#D2603D',
                    borderRadius: '5px',
                },
            }} value={value} onChange={handleChange}>
                <Tab textColor='blue' onClick={handleClick} sx={{
                    backgroundColor: '#F4F5F9',
                    borderRadius: '5px',

                }} label="Daily" />
                < Tab sx={{
                    backgroundColor: '#F4F5F9',

                }} label="Weekly" />
                <Tab sx={{
                    backgroundColor: '#F4F5F9',
                    borderRadius: '5px'
                }} label="Monthly" />
            </Tabs>
        </Box >

Answer №1

It doesn't seem feasible to achieve this in a straightforward manner. Options include resorting to less elegant solutions or completely revamping the functionality.

The tab labels are represented by <button> elements, while the tab indicator is a <span> positioned above these buttons. If you want the labels to appear above the indicator, you will need to either rearrange the hierarchy of HTML elements or introduce a secondary label above the indicator.

Unfortunately, it's not possible for the tab indicator to slide behind the button text but in front of the button background.

Here are some suboptimal ("dirty") workarounds:

  1. You can rearrange the stacking order of the HTML elements.

This can be achieved using the z-index property. You have to assign specific z-index values to the buttons and ensure that the button backgrounds remain transparent.

Take caution if there are other elements with existing z-index values or if they need to stay behind the buttons; in such cases, their z-index values might also need adjustment.

<Tab label="Daily" style={{ zIndex: 1 }} />
<Tab label="Weekly" style={{ zIndex: 1 }} />
<Tab label="Monthly" style={{ zIndex: 1 }} />
  1. You could append the current label as a child of the tab indicator, matching its style with the original label. Additionally, you would need to pass the current label so that it moves with the indicator or remains empty during sliding.
const IndicatorLabel = ({ label }) => {
  return <span className={'indicator-label'}>
    { label }
  </span>;
};

// ...

<Tabs
  TabIndicatorProps={{
    // ...
    children: <IndicatorLabel label={ currentLabel } />
  }}
>

// ...
  1. You could dynamically set the background color of the <button>, bypassing the use of the indicator altogether. However, this approach sacrifices the sliding effect.

  2. Alternatively, you could create your own custom tab indicator from scratch instead of relying on the MUI tab indicator.

Answer №2

Even though this may seem outdated, it could still be useful for anyone who is searching for a solution.

In MUI5, you can customize Tabs with styles using the code snippet below:

import { Tabs as MuiTabs } from '@mui/material';
import { styled } from '@mui/material';

const Tabs = styled(MuiTabs)(({ theme }) => ({
    '& .MuiTab-root': {
        margin: "8px 5px 8px 5px",
        borderRadius: "6px",
        lineHeight: 0,
        minHeight: "unset",
        padding: "16px",
        color: "grey",
        fontWeight: 700,
    },
    '& .MuiTab-root.Mui-selected': {
        backgroundColor: "#ff7100",
        fontWeight: 700,
        color: "white"
    }
}));

export default Tabs

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

Upon initial page load, React JS is unable to fetch the data but it functions correctly when triggered by a click

Here is the code I am working with: var CommonHeader = require('./header/CommonHeader.jsx'); var ListOptions = require('./header/ListOptions.jsx'); var SortableTable = require('../shared/SortableTable.jsx'); var ColumnDefinit ...

Tips for resolving an issue with mongoose Model.create becoming unresponsive indefinitely

I'm having trouble understanding why my mongoose Model.create operation isn't completing successfully. The same connection is working well with other controller functions. vscode postman I am attempting to create a new document, but my code s ...

What is the best way to divide the height of one div evenly among three other divs?

I have three child divs inside a parent div and I'm looking to distribute the height of the parent div evenly among the three children. Here is the HTML code: <div class="frameright"> <div class="divright"> <t ...

Can object-fit be preserved while applying a CSS transform?

Currently, I am developing a component that involves transitioning an image from a specific starting position and scale to an end position and scale in order to fill the screen. This transition is achieved through a CSS transform animation on translate and ...

Unable to modify the style of a deeply embedded component within Material-UI's Jss styling

When using Material-UI's ExpansionPanelSummary component, you have the ability to include an icon inside it by utilizing the expandIcon prop and customize its style using the expandIcon css class. Examining the component's implementation, we ca ...

What could be causing the issue of receiving the error message: "Uncaught TypeError: Cannot read property 'Title' of undefined"?

I am currently working on developing an AJAX web application. One of the functions I have is aimed at requesting a JSON object and then utilizing it to refresh the website content. Below is the portion of JavaScript causing an issue (Lines 8 - 16): windo ...

Angular2 - Utilizing Promises within a conditional block

I'm currently facing an issue where I need to await a response from my server in order to determine if an email is already taken or not. However, I am struggling to achieve this synchronously. TypeScript is indicating that the function isCorrectEmail( ...

Is there a way to make images appear on the screen only when they come into view on

While exploring the internet, I came across something quite intriguing on a website: As you scroll down the page, images only load when they come into view in the browser window. This is a feature I have never seen before and I am curious if anyone else h ...

How can I increase the size of the nuka-carousel dots in React/Nextjs?

Looking for help on customizing the size of dots in my nuka-carousel. Unsure how to change their sizing and margin. ...

Utilizing JavaScript to retrieve input names from arrays

This is the HTML form that I am currently working with: <form action="#" method="post"> <table> <tr> <td><label>Product:<label> <input type="text" /></td> <td><label>Price:<label> ...

Creating an interactive table with the power of FPDF and PHP

I have developed a unique Invoice System that allows users to customize the number of headings and fields using FPDF in conjunction with PHP. Subsequently, I can input the heading names and field values into HTML input fields. However, I am encountering a ...

Swapping out the initial occurrence of every word in the list with a hyperlink

I stumbled upon a fantastic script on a programming forum that almost fits my requirements perfectly. It essentially replaces specific words in a document with links to Wikipedia. However, I have run into an issue where I only want the first occurrence of ...

What could be the reason my div is not being hidden in jQuery?

Creating a quiz layout for school is my current project, and I'm just getting started. My goal is to have the questions disappear once the 'next question' button is clicked. The issue arises after the second question because instead of the ...

Looking for assistance on how to use Express JS to make a post request to insert data with an array of objects into a database. Can anyone provide guidance?

While utilizing ExpressJS for serverside functionality, I encountered an issue when making a post call with multiple objects in an array. The error message displayed is as follows: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to t ...

Utilize CSS scrolling to present all items in a single line

Looking to showcase images in a horizontal line with scroll functionality? Unsure of how to achieve this and would really appreciate some guidance. CSS .img { max-width: 400px; position: relative; } .animal { float: left; background-color: #fff; ...

Stopping halfway through a jQuery toggle width animation to close again

Perhaps the question may be a bit unclear, but allow me to provide an example. When repeatedly clicking the button that toggles the width, the div continues to animate long after the button press, which is not visually appealing. My desired outcome is for ...

Refreshing a React form

this.state = { name: "", arr: [], story: "" }; add(e) { e.preventDefault(); this.setState({ story: e.target.value }); this.state.arr.push(this.state.story); this.form.reset(); } <form action=""> <input onChange={this.b} type="t ...

Issue with Ajax request not redirecting to correct URL

I have been successfully using ajax requests in my document without any issues. I am looking to retrieve the user's coordinates as they load the document and then pass this data on to other methods for distance calculations. On the loading of the ind ...

Is it feasible to utilize the resulting value from a ReferenceField externally?

const MyComponent = (props) => { //how can I access the user.fullName here? //console.log(user.fullName) return ( <ReferenceField reference="users" source="userId" record={props.record} ...

What is the best way to merge makeStyle classes from both the parent and child components together?

Is it possible to pass makeStyle classes from a parent component to a child component and merge them with the makeStyle classes within the child component? For example, incorporating breakpoint hiding into the child component's style. Here is an exam ...