Achieving Horizontal Alignment of Tab Labels and Icons in Material-UI with Tabs API

I am currently attempting to customize the Material UI CSS in order to align both the phone icon and text on the same line and closer together. After doing some research, I stumbled upon the Tabs API which seemed promising.

Upon further inspection, I discovered that the wrapper property was causing some issues. Despite trying to resolve it by setting the display to block, the alignment of the phone icon and text remains stubbornly off-kilter.

To aid in troubleshooting, I have included my code snippet and a sandbox link below. You can access all of my code within tab-demo.js.

https://codesandbox.io/s/7p4ryw691

const styles = theme => ({
  root: {
    // flexGrow: 1,
    width: "100%",
    // flex: 0,
    textTransform: "capitalize"
    // backgroundColor: theme.palette.background.paper
    //  backgroundColor: 'red'
  },
  sportsAdvancedSearch: {
    // backgroundColor: 'green'
    color: "red",
    fontSize: 16,
    fontWeight: "bold"
  },
  sportsTotalNumber: {
    fontWeight: "bold"
  },
  sportsExportContainer: {
    paddingTop: 8,
    paddingBottom: 8
  },

  indicator: {
    backgroundColor: "red"
  },
  tabsIndicator: {
    backgroundColor: "red",
    textTransform: "capitalize"
  },
  tabRoot: {
    textTransform: "initial",
    width: "100%",
    display: "block",

    "&:hover": {
      color: "red",
      opacity: 1,
      textTransform: "initial"
    },
    "&$tabSelected": {
      color: "red",
      fontWeight: theme.typography.fontWeightMedium,
      textTransform: "capitalize"
    },
    "&:focus": {
      color: "red",
      textTransform: "capitalize"
    }
  },
  tabSelected: {},
  sportsHeading: {
    fontSize: 32,
    fontWeight: "bold",
    padding: 16
  },
  sportsTabHeader: {
    //  border: "1px solid red",
    backgroundColor: "#f5f5f5"
  },
  alignment: {
    display: "block"
    //  color: 'red'
  }
});

  <Tabs
            value={value}
            onChange={this.handleChange}
            scrollable
            scrollButtons="on"
            classes={{ indicator: classes.tabsIndicator }}
          >
            <Tab
              label="phone"
              icon={<PhoneIcon style={{ display: "block" }} />}
              classes={{
                root: classes.tabRoot,
                selected: classes.tabSelected,
                wrapper: classes.alignment
              }}
            />
            <Tab
              favorites={favorites}
              label="Favorites"
              icon={<FavoriteIcon style={{ display: "block" }} />}
              classes={{
                root: classes.tabRoot,
                selected: classes.tabSelected,
                wrapper: classes.alignment
              }}
            />
          </Tabs>

Answer №1

This method effectively lines up tab text and icons horizontally while preserving the Tabs/TabPanel functionality.

The "Place Everything within a Label" Technique

<Tab label= {<div><HomeIcon style = { {verticalAlign : 'middle'} } /> Home </div>}/>

Source

Using CSS

You can achieve this by adding the following to the CSS of your tabs component.

.MuiTab-wrapper {
  flex-direction: row !important;
}

Be sure to include '!important' to override the predefined class .MuiTab-wrapper from material-UI, as it may not work without it after a reload.

On a side note,

If you group icons and tabs in a div and use CSS to align them, it will work but you will lose the default Tabs/TabPanel functionality provided by material-UI.

If functionality is not a concern for you, give this approach a try.

<div style={{display:'flex',alignItems:'center'}}>
       <HomeIcon/>
       <Tab label="Home" />
</div>

I hope this information proves useful!

Answer №2

Modify line 331 to read:

icon={<PhoneIcon style={{ display: "inline-block", marginBottom:"-10px" }} />}

The reason for this change is that the svg element has a display property set to block, causing it to push the text below it. By adjusting the margins, you can position it as desired.

Answer №3

<Tab label={<><div>A different label<Icon/></div></>}/>

Answer №4

If you're looking for a solution, the best way to handle it in MUI v5+ is by utilizing the iconPosition attribute of Tab. Check out the details at https://mui.com/material-ui/react-tabs/#icon-position

Here's a snippet of code from the provided link for easier reference:

<Tabs
  value={value}
  onChange={handleChange}
  aria-label="icon position tabs example"
>
  <Tab icon={<PhoneIcon />} label="top" />
  <Tab icon={<PhoneMissedIcon />} iconPosition="start" label="start" />
  <Tab icon={<FavoriteIcon />} iconPosition="end" label="end" />
  <Tab icon={<PersonPinIcon />} iconPosition="bottom" label="bottom" />
</Tabs>

With the "start" and "end" options, the icon will be aligned on the same line as the text in the label.

This capability was introduced through this change: https://github.com/mui/material-ui/pull/28764

Answer №5

Experiment with using inline-block

display: inline-block;

Answer №6

Modify this:

alignment: {
    display: "block"
    //  color: 'red'
  }

to :

alignment: {
    display: "flex",
    flexDirection: "row"
    //  color: 'red'
  }

Tried it out and it's effective.

The flex layout makes it easier to handle across various browsers!

UPDATE:

Revised Fiddle with tab widths adjusted: https://codesandbox.io/s/82ynv5qwy9

Modifications:

1.

classes={{
              indicator: classes.tabsIndicator,
              scrollButtons: { display: "flex", flex: 1 }
            }}

2.

  tabRoot: {
    textTransform: "initial",
    width: "stretch",
    display: "flex",
    flex: 1,

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

Creating a Custom Error Page in SpringBoot

After developing an application with SpringBoot that features webservices and a front-office coded in ReactJs, the default port was set to 8080. To simplify the URL access, I decided to switch this application to port 80 by adding the code snippet below to ...

I am having difficulty toggling text within a for loop in JavaScript

When I display a list of cards using a for loop and click on them, I want to toggle some text. The issue I'm facing is that it works fine for the top card, but when I click on the card below, it toggles the text of the first card instead. This is desp ...

Storing an Excel file with JavaScript: A comprehensive guide

I've been struggling to save an Excel file using Javascript, but I'm facing compatibility issues with different browsers. I initially tried using BASE64 along with data URL, which worked well in Chrome and Firefox but failed in IE and Safari. ne ...

Configuring Firefox settings in Nightwatch

Is there a way to set Firefox preferences in nightwatch? I am trying to achieve the same thing in Java using nightwatch. To set Firefox preferences in nightwatch, you can use the following code snippet: FirefoxProfile profile = new FirefoxProfile(); prof ...

Is it feasible to maintain a persistent login session in Firebase without utilizing the firebase-admin package through the use of session cookies?

Currently, I am integrating Firebase into my next.js application for user login functionality. The issue I am facing is that users are getting logged out every time they switch paths within the site. Even though their session cookie has not expired, if the ...

Node interprets string as an object

I encountered the following code: <a class="btn-primary btn" href="/employer/booth/<%= user._id.toString() %>" <% console.log(typeof user._id, user._id) %> target="_blank"> Preview your booth </a> Upon running this ...

Combine two separate variables and insert them into a single cURL command line

I need to incorporate a random value from a variable into a cURL command. Additionally, I want the cURL command to execute a function using this random value. At the end of the function, I want to add a different value to the first one for completion and t ...

I'm unable to view any modifications in my React application after making updates to the code and rebuilding the solution

After following a helpful tutorial on creating a Node.js and React app in Visual Studio, I encountered an issue. Despite successfully implementing the tutorial and seeing the "Welcome to React" message after hitting Ctrl + F5, further changes to my app.tsx ...

The data received by request.responseText is accurate, however JavaScript is unable to interpret it

I am currently diving into the world of AJAX and educating myself using Head First AJAX. I have encountered a strange issue while working on a simple program that makes a request using JavaScript and displays the output. main.js window.onload = initPage; ...

Showing particular URL text upon opening a new window using JavaScript

I've encountered an intriguing scenario. In my application, there's a feature that triggers a new window/tab to open when a button is clicked. Upon opening, a predefined HTML page is shown to the user with a specific URL set. I'm curious abo ...

The Naming Convention for NPM Scripts

In my package.json, I have a script that looks similar to this: { ... scripts: { ... "testdb:e2e": "TESTDB_ENV='...' gulp mocha:e2e:backend && gulp mocha:e2e:frontend" } ... } I am interested in adding a s ...

Adding more rows to the array and then inserting them into the database

Seeking some clarity and appreciation in advance for any assistance! I've organized an array of information within a table that I can edit and then sync with my database once updated. <input type='button' value='add row' id=&a ...

Why does jQuery utilize the anonymous function wrapper?

When delving into jQuery's code structure, one notices that it begins by enveloping all of its code within an anonymous function: (function ( window, undefined) { /* ...jquery code... */ }) (window); It is clear that this function is immedi ...

What is the best way to retrieve the ID of the list item that has been clicked during a button event?

How can I use jQuery to get the ID of a selected list item when clicking a button in my HTML code? <ul id="nav"> <li><a href="#" rel="css/default.css" id="default" > <div class="r1"></div> </a>< ...

Cease making commitments or declarations

I am currently working on validating an image using an API. I have implemented promises and want the execution to stop and call a function if the API check fails. Here is my code: The function for calling the promises: checkPhotos(options,formData, "fr ...

The carousel image slider seamlessly transitioning from the second image

I'm having an issue with the Carousel slider where it is overlapping the image from the second slide onwards. The first image loads properly, but subsequent images are not displaying correctly. Here's a reference image: https://i.sstatic.net/pyY ...

vue-router incorrectly updates parameters upon reload

One question I have is related to routing in Vue.js: // routes.js { path: '/posts', name: 'Posts', component: PostsView }, { path: '/post/:post_id', name: 'PostRead', component: PostReadView, }, { pat ...

Populate a Textbox Automatically using a Dropdown List

MVC 4 Changing multiple display fields based on DropDownListFor selection Having some issues trying to implement the solution mentioned above. It seems like there might be a problem with either my javascript code or the controller. JavaScript in View ...

Dynamic menu bar accompanied by primary content

I'm facing an issue with my active navigation bar. Whenever I open the hamburger menu, the main content remains fixed and does not move along with the open navigation menu. I tried searching online for a solution but couldn't find anything helpfu ...

A comprehensive guide on properly obtaining user details in React with Redux and OIDC

Although I've dabbled in OIDC before, I wouldn't consider myself an expert. Currently, I'm trying to integrate OIDC into a react app using oidc-client-js and redux-oidc libraries, following the redux-oidc-example as a guide. Encountering th ...