应用栏与其他元素重叠

12

我开始使用React/Material-UI,对CSS等方面也不太熟悉... 我有一个带有APPBar的简单页面布局。不幸的是,这个AppBar会覆盖它下面应该放置的元素。

我找到了这个答案: AppBar Material UI questions

但是这感觉完全不对。如果我的AppBar具有可变高度,取决于图标、显示模式等等,怎么办?

我尝试创建一个垂直网格,将元素包装在不同的项中,将顶部容器设置为flex,并调整flex设置,但都没有任何作用,应用栏始终位于文本上方。

代码非常简单:

import React from 'react';
import { AppBar, Typography, Box } from '@material-ui/core';

function App() {
    return (
        <div>
            <AppBar>
                <Typography variant='h3'>
                    AppBar
                </Typography>
            </AppBar>
            <Box>
                <Typography variant='h1' style={{ border: '1px solid black' }}>
                    Hello
                </Typography>
            </Box>
        </div>
    )
}

export default App;

“Hello”文本块只有一半可见:

在此输入图片描述


现在我和你有同样的问题,哈哈哈,你找到答案了吗? - chichi
2
是的,您可以将AppBar位置设置为相对位置:<AppBar style={{ position: 'relative' }}>。 - Will59
1
我尝试过那个方法,但它会将所有内容向下推。不过,我正在导入应用栏并将其放置在不同的组件上。非常感谢! - chichi
8个回答

10
这是由于 MaterialUI 应用栏默认为 position="fixed"。这将其与标准 DOM 布局分开,以允许内容在其下方滚动,但结果页面上没有为其留出空间。
您可以通过将其下方的所有内容包装在一个 div 中并指定足够的 margin,或者更改 <AppBar>position 属性,使其不再是 "fixed",从而解决此问题。在您的示例中,如果 <Box> 是应用栏下唯一的内容,则可以将样式应用于 <Box>
import React from 'react';
import { AppBar, Typography, Box } from '@material-ui/core';

function App() {
    return (
        <div>
            <AppBar>
                <Typography variant='h3'>
                    AppBar
                </Typography>
            </AppBar>
            <div style={{marginTop: 80}}>
                <Box>
                    <Typography variant='h1' style={{ border: '1px solid black' }}>
                        Hello
                    </Typography>
                </Box>
            </div>
        </div>
    )
}

export default App;

2
上面所示的代码不是我要找的,因为任何固定大小的div都无法与可变大小的应用栏配合使用(正如问题中所述)。 然而,简单地改变AppBar的位置就解决了问题。所以接受这个解决方案。 - Will59

5
根据Material-ui的说法,这个问题有三种解决方案。

https://material-ui.com/components/app-bar/#fixed-placement

  1. 你可以使用 position="sticky" 替代 fixed。⚠️ sticky 不支持 IE 11。
  2. 你可以渲染第二个 <Toolbar> 组件
  3. 你可以使用 theme.mixins.toolbar CSS

我个人喜欢像这样使用第二种解决方案。

  return (
    <>
      <AppBar position="fixed">
        <Toolbar>{/* content */}</Toolbar>
      </AppBar>
      <Toolbar />
    </>
  );

5

MaterialUI提供了一个应用栏的主题mixin,可以帮助你。不确定你是否使用了推荐的JSS设置,但你可以这样做:

import withStyles from '@material-ui/core/styles/withStyles';
const styles = theme => ({
  appBarSpacer: theme.mixins.toolbar
});

const style = withStyles(styles)

function MyScreen ({ classes }) {
  <AppBar></AppBar>
    <div className={classes.appBarSpacer}></div>
  <Box></Box>
}

export default style(MyScreen)

该Mixin将使该div具有与您的AppBar相同的高度,并将其他内容向下推。

2
谢谢你的回答。但是appBarSpacer的高度不会固定为64px吗?我尝试了这个选项,在AppBar中放置修改其高度的项目,但是appBarSpacer似乎没有调整? - Will59
@Will59 我刚试了一下,高度会根据应用栏的高度进行调整。应用栏的高度将根据窗口宽度和应用栏属性/配置响应式地改变高度。编辑:我想我误解了你的评论。听起来你的应用栏高度是自定义的,这种方法不会考虑到它。 - Matt Huggins

2

<AppBar position='static'>

使用这个,它可以达到效果并且内容不会被 AppBar 遮盖。


1

我认为拥有一个良好的应用程序设置是有主观性的,但我建议以下操作:

import React from "react";
import ReactDOM from "react-dom";
import {
  AppBar,
  Typography,
  Box,
  CssBaseline,
  makeStyles,
  Container,
  Grid,
  Toolbar
} from "@material-ui/core";

const useStyles = makeStyles(theme => ({
  content: {
    flexGrow: 1,
    height: "100vh",
    overflow: "auto"
  },
  appBarSpacer: theme.mixins.toolbar,
  title: {
    flexGrow: 1
  },
  container: {
    paddingTop: theme.spacing(4),
    paddingBottom: theme.spacing(4)
  }
}));

function App() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <CssBaseline />
      <AppBar position="absolute">
        <Toolbar className={classes.toolbar}>
          <Typography
            component="h1"
            variant="h6"
            color="inherit"
            noWrap
            className={classes.title}
          >
            AppBar
          </Typography>
        </Toolbar>
      </AppBar>
      <main className={classes.content}>
        <div className={classes.appBarSpacer} />
        <Container maxWidth="lg" className={classes.container}>
          <Grid container spacing={3}>
            <Grid item xs={12}>
              <Box>
                <Typography variant="h1" style={{ border: "1px solid black" }}>
                  Hello
                </Typography>
              </Box>
            </Grid>
          </Grid>
        </Container>
      </main>
    </div>
  );
}

How the result should look


1
感谢回答。不过appBarSpacer的高度不会固定为64px吗?我尝试了在AppBar中放置修改其高度的项目,但是appBarSpacer似乎没有进行调整? - Will59
你为什么要修改 appBar 的高度? - Julian Kleine
1
如果您想要将徽标(无法缩小到一定的大小)添加到应用栏,更改文本大小或进行其他任何操作,都可以修改高度... - lowcrawler

0

试试这个!

const useStyles = makeStyles((theme) => ({
root: {
    flexGrow: 1,
    [theme.breakpoints.down('sm')]: {
        marginBottom: 56,
    },
    [theme.breakpoints.up('sm')]: {
        marginBottom: 64,
    },
},
menuButton: {
    marginRight: theme.spacing(1),
},
title: {
    flexGrow: 1,
}, }))

您可以像这样将上述内容添加到您的代码中

const Navbar = () => {
const classes = useStyles()
return (
    <div className={classes.root}>
        <AppBar position='fixed' color='primary'>
            <Toolbar>
                <IconButton
                    edge='start'
                    className={classes.menuButton}
                    color='inherit'
                    aria-label='menu'>
                    <MenuIcon />
                </IconButton>
                <Typography variant='h6' className={classes.title}>
                    News
                </Typography>
                <Button color='inherit'>Login</Button>
            </Toolbar>
        </AppBar>
    </div>
)}

如需更多文档,请访问material-ui断点定制


请避免将代码作为答案发布,因为没有解释可能不会有帮助。 - Malakai

0
最简单的方法是将位置设置为粘性的Appbar。您可以参考下面附上的图片! 输入图像描述

最好直接粘贴代码片段,而不是链接图片。此外,请确保使用有帮助的链接文本。 - Thenlie

0
我在我的Vite-React应用程序中使用了MUI ResponsiveAppBar组件,并尝试了这里所说的所有方法来更改导航栏的属性,但都没有成功,因为导航栏在每个页面上都会被渲染,并且不知道其他组件在特定页面上的渲染情况。我的解决方案是在index.css中添加一个css类,像这样:
.content-container {
margin-top: 80px;
}

然后将该类作为每个页面中呈现其余组件的div的属性添加。例如在主页中:
import React from "react";

function HomePage() {
    return (
        <div className="content-container">
            <h1>Home Page of App</h1>
        </div>
    )
}

export default HomePage

这将在页面的顶部创建一个边距(您可以指定),以便应用栏不会“覆盖”页面上的其他内容。根据我的检查,它不应以任何方式影响应用的响应性质。

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