98

I am a newbie in Material UI, now my icon and text are not aligned:

not align

My desired results:

My code is:

<div style={{
    display: 'inline-flex',
    VerticalAlign: 'text-bottom',
    BoxSizing: 'inherit',
    textAlign: 'center',
    AlignItems: 'center'
}}>
    <LinkIcon className={classes.linkIcon}  />
    revolve
</div>  

I tried grid and row, but not work. Can anyone help me?

Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
tong
  • 1,001
  • 1
  • 9
  • 8

15 Answers15

109

This works perfectly!

<div style={{
    display: 'flex',
    alignItems: 'center',
    flexWrap: 'wrap',
}}>
    <LinkIcon />
    <span>revolve</span>
</div>  
DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127
Peter Moses
  • 1,997
  • 1
  • 19
  • 22
  • 2
    I used the style but applied them to a single `Typography` so I did not need the `p` element. Works a charm with `v4.0.2`. – hsimah Jun 05 '19 at 23:42
50

You need to use Grid. Something like that should works:

<Grid container direction="row" alignItems="center">
  <Grid item>
    <LinkIcon className={classes.linkIcon} />
  </Grid>
  <Grid item>
    revolve
  </Grid>
</Grid>
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
tinmarfrutos
  • 1,740
  • 1
  • 14
  • 23
  • 9
    Perfect, if the text gets longer than the row by default the grid starts wrapping which means the text will be below the icon, to prevent this you can add `wrap="nowrap"` – Shikyo May 10 '19 at 08:48
  • 2
    Feels more like the 'MUI' way, using their components. BTW, `direction="row"` should not be needed. Pretty sure it's the default. – CodeFinity May 08 '22 at 20:38
48

This can be easily achieved in MUI v5 by using a Stack and set alignItems prop to center:

import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import AddCircleIcon from '@mui/icons-material/AddCircle';
<Stack direction="row" alignItems="center" gap={1}>
  <AddCircleIcon />
  <Typography variant="body1">text</Typography>
</Stack>

Codesandbox Demo

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
33

Try the below code. You can use variant as per your requirement.

const useStyles = makeStyles(theme => ({
  wrapIcon: {
    verticalAlign: 'middle',
    display: 'inline-flex'
   }
}));

<Typography variant="subtitle1" className={classes.wrapIcon}>
    <LinkIcon className={classes.linkIcon}  /> revolve
</Typography>
Chetan Gawai
  • 2,361
  • 1
  • 25
  • 36
22

alternative simple solution

<Grid container direction="row" alignItems="center">
     <SearchIcon /> example
</Grid>
ThomasP1988
  • 4,597
  • 3
  • 30
  • 36
  • I'm confused why this works, as the [Material UI](https://v4.mui.com/components/grid/) examples always have a ``, the `alignItems="center"` doesn't work, icon still not vertically aligned, but with this solution it's finally working. I also find ` – Shawn Apr 20 '22 at 19:01
  • I think that's why they have introduced Stack in V5 – ThomasP1988 Apr 21 '22 at 08:28
7

styles

const styles = theme => ({
    icon: {
        position: "relative",
        top: theme.spacing.unit,
        width: theme.typography.display1.fontSize,
        height: theme.typography.display1.fontSize
    }
});

JSX

<Typography variant="display1">
    <Icon className={this.props.classes.icon}/>Your&nbsp;Text
</Typography>

you could replace display1 with display3 or another typography variant in all 3 places to choose your text size. The &nbsp; ensures that your text doesn't break between words when it wraps.

For me this can render to look like this

enter image description here

with display3 and a few other styles added for color.

nxtman123
  • 91
  • 1
  • 2
  • hello @nxtman123 I'm not really sure to understand where you use your `styles` variable defined at first... – maxxyme Dec 05 '19 at 15:29
  • @maxxyme that variable goes into `withStyles` HOC see https://material-ui.com/styles/basics/#higher-order-component-api – nxtman123 Dec 06 '19 at 20:47
  • 2
    Interesting answer, nowadays you would write: `icon: { position: "relative", top: theme.spacing(0.5), width: theme.typography.body1.fontSize, height: theme.typography.body1.fontSize }` – Eric Burel Mar 23 '20 at 14:50
  • @EricBurel, I haven't worked closely with Material UI for a little while now, so feel free to edit this answer to reflect the changes Material UI has had in recent years. I understand they have a new Typography system? My "typography variant" link appears to be outdated. – nxtman123 Mar 24 '20 at 19:43
5

Having ListItemIcon and ListItemText wrapped inside a ListItem will keep it in one line and prevent breaking:

import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
    
<ListItem >
  <ListItemIcon><AccessAlarmIcon color="secondary" /></ListItemIcon>
  <ListItemText>Updated 1 hour ago</ListItemText>
</ListItem>

Demo image:

Demo image

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
Sabareesh
  • 51
  • 1
  • 1
  • 3
    Can you please add a little more context with answer – Rigin Oommen Oct 16 '19 at 09:32
  • 2
    Please, just place a link to the image you were trying to attach and explain why `ListItem` solves the problem. – CPHPython Oct 16 '19 at 10:21
  • @Sabareesh, I can see you are brand new to Stack Overflow, so Welcome to the community. When answering questions, it's helpful to explain why your answer works. I'm not sure how the `AccessAlarmIcon` is magically vertically aligned, so please explain why this works. – PatS Nov 01 '19 at 20:00
4

You can also use Material UI's Flexbox component.

For example:

// ...
import { Box } from '@material-ui/core';
// ...

<Box alignItems="center" display="flex">
 <Box>
    <LinkIcon className={classes.linkIcon}  />
 </Box>
 <Box>
    revolve
 </Box>
</Box>

The alignItems: center attribute will vertically align the inner items.

This will add some additional markup. However, if you look at the component's API there's a lot of additional flexibility. Such as for example a method to use margin or padding that's consistent with the rest of your Material UI implementation. Also it's really easy to align the items differently if the use-case should occur.

Remi
  • 4,663
  • 11
  • 49
  • 84
3

You can import these on top

import { Grid, Typography } from "@material-ui/core";
import LinkIcon from "@material-ui/icons/Link";

You can use

<Grid style={{ display: "flex" }}>
    <LinkIcon />
    <Typography>Revolve</Typography>
</Grid>

Sample Sandbox Example Here

3

If you are trying to vertical align text and icon within MUI's Typography without using variant, you can simply add a display setting to Typography as follows:

<Typography display="flex">
    Welcome!
    <Icon />
</Typography>

This is what worked for me.

Kris Stern
  • 1,192
  • 1
  • 15
  • 23
2

I have seen all the solutions. But here is the simplest I believe :-):

<Typography><LinkIcon sx={{verticalAlign:"middle"}}/> RESOLVE</Typography> 

It also works with inline image when you want the image align with the text.

Alexander Gladysh
  • 39,865
  • 32
  • 103
  • 160
us_david
  • 4,431
  • 35
  • 29
0

Same problem here, this is what I did.

import LinkIcon from '@material-ui/icons/Link';
import styled from 'styled-components';
...
const Resolve = styled.div`
  display: flex;
  vertical-align: middle,
`;

<Resolve>
  <LinkIcon style={{ marginRight: '5px' }} />
  <p>resolve</p>
</Resolve>

If you aren't happy with mUI default link icon you can always DIY:

{/* this is the same chained icon used in the own material-ui, 
idk why this ins't avaiable yet */}

function CustomLinkIcon(props) {
  return (
    <SvgIcon {...props}>
      <path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" />
    </SvgIcon>
  );
}
...
<Resolve>
  <CustomLinkIcon 
     {/* adjust margin top if needed */}
     style={{ marginRight: '3px', marginTop: '3px' }} {
  />
  <p>resolve</p>
</Resolve>

martin
  • 862
  • 9
  • 28
0

the best option is to use it like that :

  import {Box, Typography} from '@material-ui/core'
  import LinkIcon from '@material-ui/icons/LinkIcon';

   ........

   <Box display='flex' alignItems='center'>
       <LinkIcon className={classes.linkIcon}  />
       <Typography variant='h5'>
          resolve
       </Typography>
    </Box>
djamaile
  • 695
  • 3
  • 12
  • 30
ran ia
  • 86
  • 1
  • 6
0

With this solution the icon will inherit your typography, it prevents having to re-write the style when changin

<Typography component={Stack} direction="row" alignItems="center" color="secondary">
     <EditIcon fontSize="inherit" sx={{ marginRight: 1 }} />
     Edit
</Typography>
ThomasP1988
  • 4,597
  • 3
  • 30
  • 36
0

We can use Typography to make align horizontal spacing with icon

const styles = theme => ({
    icon: {
        fontSize: '1rem',
        position: 'relative',
        right: theme.spacing(0.5),
        top: theme.spacing(0.5),
    },
});


<Typography><CheckCircleIcon className={className={this.props.classes.icon}}/>Home</Typography>
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133