如何为Material UI Tooltip设置样式?

81
如何为Material UI Tooltip的标题添加样式?默认的悬停提示是黑色的,没有文本换行。是否可以更改背景、颜色等?这个选项是否可用?
14个回答

87

这个问题的另一个流行答案(André Junges)适用于Material-UI的0.x版本。下面我从Material UI's Tooltip - Customization Style复制了我的答案,用于解决v3和v4的问题。更进一步地,我还添加了使用v5的示例。

以下是如何通过主题覆盖所有工具提示或仅使用withStyles自定义单个工具提示的示例(两个不同的示例)。第二种方法也可以用于创建自定义工具提示组件,您可以在不强制全局使用它的情况下重用它。

import React from "react";
import ReactDOM from "react-dom";

import {
  createMuiTheme,
  MuiThemeProvider,
  withStyles
} from "@material-ui/core/styles";
import Tooltip from "@material-ui/core/Tooltip";

const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
  overrides: {
    MuiTooltip: {
      tooltip: {
        fontSize: "2em",
        color: "yellow",
        backgroundColor: "red"
      }
    }
  }
});
const BlueOnGreenTooltip = withStyles({
  tooltip: {
    color: "lightblue",
    backgroundColor: "green"
  }
})(Tooltip);

const TextOnlyTooltip = withStyles({
  tooltip: {
    color: "black",
    backgroundColor: "transparent"
  }
})(Tooltip);

function App(props) {
  return (
    <MuiThemeProvider theme={defaultTheme}>
      <div className="App">
        <MuiThemeProvider theme={theme}>
          <Tooltip title="This tooltip is customized via overrides in the theme">
            <div style={{ marginBottom: "20px" }}>
              Hover to see tooltip customized via theme
            </div>
          </Tooltip>
        </MuiThemeProvider>
        <BlueOnGreenTooltip title="This tooltip is customized via withStyles">
          <div style={{ marginBottom: "20px" }}>
            Hover to see blue-on-green tooltip customized via withStyles
          </div>
        </BlueOnGreenTooltip>
        <TextOnlyTooltip title="This tooltip is customized via withStyles">
          <div>Hover to see text-only tooltip customized via withStyles</div>
        </TextOnlyTooltip>
      </div>
    </MuiThemeProvider>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑工具提示自定义

此处提供了有关工具提示 CSS 类的文档,可用于控制工具提示行为的不同方面:https://material-ui.com/api/tooltip/#css

此处提供了有关在主题中覆盖这些类的文档:https://material-ui.com/customization/components/#global-theme-override


以下是一个类似的示例,但已更新以适用于 Material-UI v5(请注意,在一些修复之后,它可在 5.0.3 及以上版本中使用)。 它包括通过主题进行自定义,使用styled和使用sx属性进行自定义的演示。 所有这些自定义都针对“工具提示插槽”,以便将 CSS 应用于控制工具提示外观的元素。

import React from "react";
import ReactDOM from "react-dom";

import { createTheme, ThemeProvider, styled } from "@mui/material/styles";
import Tooltip from "@mui/material/Tooltip";

const defaultTheme = createTheme();
const theme = createTheme({
  components: {
    MuiTooltip: {
      styleOverrides: {
        tooltip: {
          fontSize: "2em",
          color: "yellow",
          backgroundColor: "red"
        }
      }
    }
  }
});
const BlueOnGreenTooltip = styled(({ className, ...props }) => (
  <Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
    color: lightblue;
    background-color: green;
    font-size: 1.5em;
`);

const TextOnlyTooltip = styled(({ className, ...props }) => (
  <Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
    color: black;
    background-color: transparent;
`);

function App(props) {
  return (
    <ThemeProvider theme={defaultTheme}>
      <div className="App">
        <ThemeProvider theme={theme}>
          <Tooltip title="This tooltip is customized via overrides in the theme">
            <div style={{ marginBottom: "20px" }}>
              Hover to see tooltip customized via theme
            </div>
          </Tooltip>
        </ThemeProvider>
        <BlueOnGreenTooltip title="This tooltip is customized via styled">
          <div style={{ marginBottom: "20px" }}>
            Hover to see blue-on-green tooltip customized via styled
          </div>
        </BlueOnGreenTooltip>
        <TextOnlyTooltip title="This tooltip is customized via styled">
          <div style={{ marginBottom: "20px" }}>
            Hover to see text-only tooltip customized via styled
          </div>
        </TextOnlyTooltip>
        <Tooltip
          title="This tooltip is customized via the sx prop"
          componentsProps={{
            tooltip: {
              sx: {
                color: "purple",
                backgroundColor: "lightblue",
                fontSize: "2em"
              }
            }
          }}
        >
          <div>
            Hover to see purple-on-blue tooltip customized via the sx prop
          </div>
        </Tooltip>
      </div>
    </ThemeProvider>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑自定义提示

v4和v5之间主题结构更改的文档:https://mui.com/guides/migration-v4/#theme

Material-UI文档中的提示自定义示例:https://mui.com/components/tooltips/#customization


1
我只是好奇,为什么我们需要以这种方式创建styled component? styled(({ className, ...props }) => ( <Tooltip {...props} componentsProps={{ tooltip: { className: className } }} /> )为什么在这种情况下 styled(Tooltip) 无法工作? - Javatar
2
@Javatar 如果使用 styled(Tooltip),将通过 className 属性应用样式,但是 Tooltip 会将其接收到的大多数 props(包括 className)传递给它所包装的子元素(可能是为了让使用 Tooltip 包装的组件能够以与未被 Tooltip 包装时大致相同的方式接收 props),因此,使用 styled(Tooltip) 实际上会为被包装的元素添加样式,而不是工具提示。 - Ryan Cogswell

62

MUI v5 更新

您可以通过覆盖工具提示插槽中的样式来自定义 Tooltip。在v5中,有三种方法可以实现这一点。有关参考,请查看Tooltip自定义部分。更多关于sx属性和createTheme的示例可以在此处此处查看。

styled()

const ToBeStyledTooltip = ({ className, ...props }) => (
  <Tooltip {...props} classes={{ tooltip: className }} />
);
const StyledTooltip = styled(ToBeStyledTooltip)(({ theme }) => ({
  backgroundColor: '#f5f5f9',
  color: 'rgba(0, 0, 0, 0.87)',
  border: '1px solid #dadde9',
}));

sx属性

<Tooltip
  title="Add"
  arrow
  componentsProps={{
    tooltip: {
      sx: {
        bgcolor: 'common.black',
        '& .MuiTooltip-arrow': {
          color: 'common.black',
        },
      },
    },
  }}
>
  <Button>SX</Button>
</Tooltip>

createTheme+ThemeProvider

const theme = createTheme({
  components: {
    MuiTooltip: {
      styleOverrides: {
        tooltip: {
          backgroundColor: 'pink',
          color: 'red',
          border: '1px solid #dadde9',
        },
      },
    },
  },
});

Codesandbox Demo


我该如何在另一个组件上使用它,比如一个简单的 div 或 Typography? - sshmaxime
@sshmaxime,和我在答案中对“Button”所做的相同。有什么问题吗? - NearHuscarl
我不得不将compoentsProps更改为slotProps,但除此之外,它正常工作 :) - N. Ahlers

16
如果您想要更改Tooltip的文本颜色、字体大小等,有一种简单的方法。
例如,在Martial Ui Tooltip的标题中插入一个标签即可:
<Tooltip title={<span>YourText</span>}>
   <Button>Grow</Button>
</Tooltip>

那么您可以以任何方式样式化您的标签。

请查看下面的示例:

Edit modest-allen-6ubp6


2
到目前为止,最简单的答案。在我的情况下,我也可以使用styled-components来设置<span>的样式。 - Lucas Andrade
@LucasAndrade 是的,我很高兴它对你有所帮助,祝你好运。 - Shayan Moghadam

14

此答案已过时。该答案是2016年针对Material-UI 0.x版本编写的。请参阅这个答案,了解适用于版本3和4的方法。

您可以通过自定义mui主题来更改文本颜色和元素背景。

color - 文本颜色

rippleBackgroundColor - 工具提示的背景颜色

示例:使用IconButton - 但您也可以直接使用Tooltip..

import React from 'react';
import IconButton from 'material-ui/IconButton';
import MuiThemeProvider from 'material-ui/lib/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';

const muiTheme = getMuiTheme({
  tooltip: {
    color: '#f1f1f1',
    rippleBackgroundColor: 'blue'
  },
});

const Example = () => (
  <div>
    <MuiThemeProvider muiTheme={muiTheme}>
        <IconButton iconClassName="muidocs-icon-custom-github" tooltip="test" />
    </MuiThemeProvider>
  </div>
);

您还可以传递一个 style 对象给 Tooltip(在 IconButton 中是 tooltipStyles)- 但这些样式仅应用于根元素。

目前还不能更改标签样式使其换行多行显示。


13

我也遇到了这个问题,并希望任何想要简单更改工具提示颜色的人能够看到我的解决方案:

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';

import Tooltip from '@material-ui/core/Tooltip';
import Button from '@material-ui/core/Button';
import DeleteIcon from '@material-ui/icons/Delete';

const useStyles = makeStyles(theme => ({
  customTooltip: {
    // I used the rgba color for the standard "secondary" color
    backgroundColor: 'rgba(220, 0, 78, 0.8)',
  },
  customArrow: {
    color: 'rgba(220, 0, 78, 0.8)',
  },
}));

export default TooltipExample = () => {
  const classes = useStyles();

  return (
    <>
      <Tooltip
        classes={{
          tooltip: classes.customTooltip,
          arrow: classes.customArrow
        }}
        title="Delete"
        arrow
      >
        <Button color="secondary"><DeleteIcon /></Button>
      </Tooltip>
    </>
  );
};

1
似乎我碰巧遇到了一个“边缘”情况。如果<Tooltip>的子组件是功能性组件,则React会抛出警告消息,表示不能将引用传递给功能性组件。因此,如果我有像<Tooltip> <StyleMenu/></Tooltip>这样的东西。它可以工作,但React会抛出警告消息,指示应该使用ForwardRef。我该怎么处理呢? - Kevin Burton
这种方法效果更好,因为仅传递一个 span 会使该 span 覆盖的区域变色,因此工具提示的周围区域仍然具有默认颜色,而这种方法可以改变工具提示的背景。 - mohantyArpit
哪个版本的MUI包含了这个? - Vlado

3

MUI v5 自定义组件

NearHuscarl的答案基础上使用sx,对我来说最简单的方法是创建一个自定义组件来包含样式和任何想要在每个工具提示中重复的其他属性。

例如,该组件可以在底部显示带有箭头和较大字体大小的工具提示:

const StyledTooltip = ({ title, children, ...props }) => (
  <Tooltip
    {...props}
    title={title}
    placement="bottom"
    arrow
    componentsProps={{
      tooltip: {
        sx: {
          fontSize: '1.125rem',
        },
      },
    }}
  >
    {children}
  </Tooltip>
);

const Buttons = () => (
  <div>
    <StyledTooltip title="This is one">
      <Button>One</Button>
    </StyledTooltip>
    <StyledTooltip title="This is two">
      <Button>Two</Button>
    </StyledTooltip>
  </div>
);

2
对我来说,在尝试了多种无效的解决方案后,我找到了这个,并且它完美地起作用:

    <Tooltip
                open={!!tooltipContent}
                title={tooltipContent}
                onClose={hideTooltip}
                style={{
                  position: "fixed",
                  top: tooltipPosition.top,
                  left: tooltipPosition.left,
                }}
                componentsProps={{
                  tooltip: {
                    sx: {
                      bgcolor: state
                        ? ThemeColors.warning
                        : ThemeColors.warningdark,
                    },
                  },
                }}
              >
....
              </Tooltip>


非常感谢您的发布!componentsProps解决方案是唯一有效的方法,可以正确禁用Tooltip框的最大宽度! - user109764

1
对我来说,在使用v5sx属性时,这个方法有效:
<Tooltip
  slotProps={{
    tooltip: {
      sx:{
        [`&.${tooltipClasses.tooltip}`]: {
          backgroundColor: "red",
          color: "white"
        }
      }
    }
  }}
  arrow
  title="This is a test"
>

使用componentProps的原因不明,无法正常工作。slotProps产生了正确的结果。

对我来说,它起作用了,但需要进行以下更改: slotProps: {{ popper: { sx: { [& .${tooltipClasses.tooltip}]: {...style} } } }} 请注意&和句点之间的额外空格。还有将"tooltip"替换为"popper"。 - undefined

1

使用HtmlTooltip的另一种解决方案

我使用HtmlTooltip并添加了arrow: {color: '#f5f5f9',},来设置箭头工具提示样式。

还有更多关于工具提示样式的设置。

因此,我使用ValueLabelComponent来控制标签,并在那里放置了一个来自MaterialUI的Tooltip

希望这提供了另一种编辑MaterialUI Tooltip的方式 :)

const HtmlTooltip = withStyles((theme) => ({
  tooltip: {
    backgroundColor: 'var(--blue)',
    color: 'white',
    maxWidth: 220,
    fontSize: theme.typography.pxToRem(12),
    border: '1px solid #dadde9',
  },
  arrow: {
    color: '#f5f5f9',
  },
}))(Tooltip);

function ValueLabelComponent({ children, open, value }) {
  return (
    <HtmlTooltip arrow open={open} enterTouchDelay={0} placement="top" title={value}>
      {children}
    </HtmlTooltip>
  );
}

...
...

return (
    <div className={classes.root}>
      <Slider
        value={value}
        onChange={handleChange}
        onChangeCommitted={handleChangeCommitted}
        scale={(x) => convertRangeValueToOriginalValue(x, minMaxObj)}
        valueLabelDisplay="auto"
        valueLabelFormat={(x) => '$' + x}
        ValueLabelComponent={ValueLabelComponent}
        aria-labelledby="range-slider"
      />
    </div>
  );

0

使用 styledComponent 和 MUI V5

import styled from 'styled-components';
....
....

           <StyledTooltip title={tooltip}>
                  <IconTextStyle>
                    {icon}
                    <Label>{label}</Label>
                  </IconTextStyle>
            </StyledTooltip>

const StyledTooltip = styled((props) => (
  <Tooltip classes={{ popper: props.className }} {...props} />
))`
  & .MuiTooltip-tooltip {
    display: flex;
    background-color: #191c28;
    border-radius: 4px;
    box-shadow: 0px 0px 24px #00000034;
  }
`;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接