Reference
App Bar
The App Bar presents information and actions relevant to the active screen.
The top App Bar offers content and actions tied to the current view. It serves purposes like branding, displaying screen titles, facilitating navigation, and providing action options.
It can adapt into a contextual action bar or function as a navigation bar.
Basic App bar
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; import IconButton from '@mui/material/IconButton'; import MenuIcon from '@mui/icons-material/Menu'; export default function ButtonAppBar() { return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <Toolbar> <IconButton size="large" edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> News </Typography> <Button color="inherit">Login</Button> </Toolbar> </AppBar> </Box> ); }
App bar with menu
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import MenuIcon from '@mui/icons-material/Menu'; import AccountCircle from '@mui/icons-material/AccountCircle'; import Switch from '@mui/material/Switch'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormGroup from '@mui/material/FormGroup'; import MenuItem from '@mui/material/MenuItem'; import Menu from '@mui/material/Menu'; export default function MenuAppBar() { const [auth, setAuth] = React.useState(true); const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { setAuth(event.target.checked); }; const handleMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; return ( <Box sx={{ flexGrow: 1 }}> <FormGroup> <FormControlLabel control={ <Switch checked={auth} onChange={handleChange} aria-label="login switch" /> } label={auth ? 'Logout' : 'Login'} /> </FormGroup> <AppBar position="static"> <Toolbar> <IconButton size="large" edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> Photos </Typography> {auth && ( <div> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleMenu} color="inherit" > <AccountCircle /> </IconButton> <Menu id="menu-appbar" anchorEl={anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorEl)} onClose={handleClose} > <MenuItem onClick={handleClose}>Profile</MenuItem> <MenuItem onClick={handleClose}>My account</MenuItem> </Menu> </div> )} </Toolbar> </AppBar> </Box> ); }
App bar with responsive menu
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import Menu from '@mui/material/Menu'; import MenuIcon from '@mui/icons-material/Menu'; import Container from '@mui/material/Container'; import Avatar from '@mui/material/Avatar'; import Button from '@mui/material/Button'; import Tooltip from '@mui/material/Tooltip'; import MenuItem from '@mui/material/MenuItem'; import AdbIcon from '@mui/icons-material/Adb'; const pages = ['Products', 'Pricing', 'Blog']; const settings = ['Profile', 'Account', 'Dashboard', 'Logout']; function ResponsiveAppBar() { const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElNav(event.currentTarget); }; const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElUser(event.currentTarget); }; const handleCloseNavMenu = () => { setAnchorElNav(null); }; const handleCloseUserMenu = () => { setAnchorElUser(null); }; return ( <AppBar position="static"> <Container maxWidth="xl"> <Toolbar disableGutters> <AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} /> <Typography variant="h6" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'none', md: 'flex' }, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleOpenNavMenu} color="inherit" > <MenuIcon /> </IconButton> <Menu id="menu-appbar" anchorEl={anchorElNav} anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'left', }} open={Boolean(anchorElNav)} onClose={handleCloseNavMenu} sx={{ display: { xs: 'block', md: 'none' } }} > {pages.map((page) => ( <MenuItem key={page} onClick={handleCloseNavMenu}> <Typography sx={{ textAlign: 'center' }}>{page}</Typography> </MenuItem> ))} </Menu> </Box> <AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} /> <Typography variant="h5" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'flex', md: 'none' }, flexGrow: 1, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> {pages.map((page) => ( <Button key={page} onClick={handleCloseNavMenu} sx={{ my: 2, color: 'white', display: 'block' }} > {page} </Button> ))} </Box> <Box sx={{ flexGrow: 0 }}> <Tooltip title="Open settings"> <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}> <Avatar alt="Remy Sharp" src="/material-ui-static/images/avatar/2.jpg" /> </IconButton> </Tooltip> <Menu sx={{ mt: '45px' }} id="menu-appbar" anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > {settings.map((setting) => ( <MenuItem key={setting} onClick={handleCloseUserMenu}> <Typography sx={{ textAlign: 'center' }}>{setting}</Typography> </MenuItem> ))} </Menu> </Box> </Toolbar> </Container> </AppBar> ); } export default ResponsiveAppBar;
App bar with search field
A sidebar-integrated search bar.
import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import InputBase from '@mui/material/InputBase'; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; const Search = styled('div')(({ theme }) => ({ position: 'relative', borderRadius: theme.shape.borderRadius, backgroundColor: alpha(theme.palette.common.white, 0.15), '&:hover': { backgroundColor: alpha(theme.palette.common.white, 0.25), }, marginLeft: 0, width: '100%', [theme.breakpoints.up('sm')]: { marginLeft: theme.spacing(1), width: 'auto', }, })); const SearchIconWrapper = styled('div')(({ theme }) => ({ padding: theme.spacing(0, 2), height: '100%', position: 'absolute', pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', })); const StyledInputBase = styled(InputBase)(({ theme }) => ({ color: 'inherit', width: '100%', '& .MuiInputBase-input': { padding: theme.spacing(1, 1, 1, 0), // vertical padding + font size from searchIcon paddingLeft: `calc(1em + ${theme.spacing(4)})`, transition: theme.transitions.create('width'), [theme.breakpoints.up('sm')]: { width: '12ch', '&:focus': { width: '20ch', }, }, }, })); export default function SearchAppBar() { return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <Toolbar> <IconButton size="large" edge="start" color="inherit" aria-label="open drawer" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h6" noWrap component="div" sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }} > MUI </Typography> <Search> <SearchIconWrapper> <SearchIcon /> </SearchIconWrapper> <StyledInputBase placeholder="Search…" inputProps={{ 'aria-label': 'search' }} /> </Search> </Toolbar> </AppBar> </Box> ); }
Responsive App bar with Drawer
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import CssBaseline from '@mui/material/CssBaseline'; import Divider from '@mui/material/Divider'; import Drawer from '@mui/material/Drawer'; import IconButton from '@mui/material/IconButton'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import MenuIcon from '@mui/icons-material/Menu'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; interface Props { /** * Injected by the documentation to work in an iframe. * You won't need it on your project. */ window?: () => Window; } const drawerWidth = 240; const navItems = ['Home', 'About', 'Contact']; export default function DrawerAppBar(props: Props) { const { window } = props; const [mobileOpen, setMobileOpen] = React.useState(false); const handleDrawerToggle = () => { setMobileOpen((prevState) => !prevState); }; const drawer = ( <Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> <Typography variant="h6" sx={{ my: 2 }}> MUI </Typography> <Divider /> <List> {navItems.map((item) => ( <ListItem key={item} disablePadding> <ListItemButton sx={{ textAlign: 'center' }}> <ListItemText primary={item} /> </ListItemButton> </ListItem> ))} </List> </Box> ); const container = window !== undefined ? () => window().document.body : undefined; return ( <Box sx={{ display: 'flex' }}> <CssBaseline /> <AppBar component="nav"> <Toolbar> <IconButton color="inherit" aria-label="open drawer" edge="start" onClick={handleDrawerToggle} sx={{ mr: 2, display: { sm: 'none' } }} > <MenuIcon /> </IconButton> <Typography variant="h6" component="div" sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }} > MUI </Typography> <Box sx={{ display: { xs: 'none', sm: 'block' } }}> {navItems.map((item) => ( <Button key={item} sx={{ color: '#fff' }}> {item} </Button> ))} </Box> </Toolbar> </AppBar> <nav> <Drawer container={container} variant="temporary" open={mobileOpen} onClose={handleDrawerToggle} ModalProps={{ keepMounted: true, // Better open performance on mobile. }} sx={{ display: { xs: 'block', sm: 'none' }, '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth }, }} > {drawer} </Drawer> </nav> <Box component="main" sx={{ p: 3 }}> <Toolbar /> <Typography> Lorem ipsum dolor sit amet consectetur adipisicing elit. Similique unde fugit veniam eius, perspiciatis sunt? Corporis qui ducimus quibusdam, aliquam dolore excepturi quae. Distinctio enim at eligendi perferendis in cum quibusdam sed quae, accusantium et aperiam? Quod itaque exercitationem, at ab sequi qui modi delectus quia corrupti alias distinctio nostrum. Minima ex dolor modi inventore sapiente necessitatibus aliquam fuga et. Sed numquam quibusdam at officia sapiente porro maxime corrupti perspiciatis asperiores, exercitationem eius nostrum consequuntur iure aliquam itaque, assumenda et! Quibusdam temporibus beatae doloremque voluptatum doloribus soluta accusamus porro reprehenderit eos inventore facere, fugit, molestiae ab officiis illo voluptates recusandae. Vel dolor nobis eius, ratione atque soluta, aliquam fugit qui iste architecto perspiciatis. Nobis, voluptatem! Cumque, eligendi unde aliquid minus quis sit debitis obcaecati error, delectus quo eius exercitationem tempore. Delectus sapiente, provident corporis dolorum quibusdam aut beatae repellendus est labore quisquam praesentium repudiandae non vel laboriosam quo ab perferendis velit ipsa deleniti modi! Ipsam, illo quod. Nesciunt commodi nihil corrupti cum non fugiat praesentium doloremque architecto laborum aliquid. Quae, maxime recusandae? Eveniet dolore molestiae dicta blanditiis est expedita eius debitis cupiditate porro sed aspernatur quidem, repellat nihil quasi praesentium quia eos, quibusdam provident. Incidunt tempore vel placeat voluptate iure labore, repellendus beatae quia unde est aliquid dolor molestias libero. Reiciendis similique exercitationem consequatur, nobis placeat illo laudantium! Enim perferendis nulla soluta magni error, provident repellat similique cupiditate ipsam, et tempore cumque quod! Qui, iure suscipit tempora unde rerum autem saepe nisi vel cupiditate iusto. Illum, corrupti? Fugiat quidem accusantium nulla. Aliquid inventore commodi reprehenderit rerum reiciendis! Quidem alias repudiandae eaque eveniet cumque nihil aliquam in expedita, impedit quas ipsum nesciunt ipsa ullam consequuntur dignissimos numquam at nisi porro a, quaerat rem repellendus. Voluptates perspiciatis, in pariatur impedit, nam facilis libero dolorem dolores sunt inventore perferendis, aut sapiente modi nesciunt. </Typography> </Box> </Box> ); }
App bar with a primary search field
A prominently featured search bar.
import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import InputBase from '@mui/material/InputBase'; import Badge from '@mui/material/Badge'; import MenuItem from '@mui/material/MenuItem'; import Menu from '@mui/material/Menu'; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; import AccountCircle from '@mui/icons-material/AccountCircle'; import MailIcon from '@mui/icons-material/Mail'; import NotificationsIcon from '@mui/icons-material/Notifications'; import MoreIcon from '@mui/icons-material/MoreVert'; const Search = styled('div')(({ theme }) => ({ position: 'relative', borderRadius: theme.shape.borderRadius, backgroundColor: alpha(theme.palette.common.white, 0.15), '&:hover': { backgroundColor: alpha(theme.palette.common.white, 0.25), }, marginRight: theme.spacing(2), marginLeft: 0, width: '100%', [theme.breakpoints.up('sm')]: { marginLeft: theme.spacing(3), width: 'auto', }, })); const SearchIconWrapper = styled('div')(({ theme }) => ({ padding: theme.spacing(0, 2), height: '100%', position: 'absolute', pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', })); const StyledInputBase = styled(InputBase)(({ theme }) => ({ color: 'inherit', '& .MuiInputBase-input': { padding: theme.spacing(1, 1, 1, 0), // vertical padding + font size from searchIcon paddingLeft: `calc(1em + ${theme.spacing(4)})`, transition: theme.transitions.create('width'), width: '100%', [theme.breakpoints.up('md')]: { width: '20ch', }, }, })); export default function PrimarySearchAppBar() { const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState<null | HTMLElement>(null); const isMenuOpen = Boolean(anchorEl); const isMobileMenuOpen = Boolean(mobileMoreAnchorEl); const handleProfileMenuOpen = (event: React.MouseEvent<HTMLElement>) => { setAnchorEl(event.currentTarget); }; const handleMobileMenuClose = () => { setMobileMoreAnchorEl(null); }; const handleMenuClose = () => { setAnchorEl(null); handleMobileMenuClose(); }; const handleMobileMenuOpen = (event: React.MouseEvent<HTMLElement>) => { setMobileMoreAnchorEl(event.currentTarget); }; const menuId = 'primary-search-account-menu'; const renderMenu = ( <Menu anchorEl={anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} id={menuId} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={isMenuOpen} onClose={handleMenuClose} > <MenuItem onClick={handleMenuClose}>Profile</MenuItem> <MenuItem onClick={handleMenuClose}>My account</MenuItem> </Menu> ); const mobileMenuId = 'primary-search-account-menu-mobile'; const renderMobileMenu = ( <Menu anchorEl={mobileMoreAnchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} id={mobileMenuId} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={isMobileMenuOpen} onClose={handleMobileMenuClose} > <MenuItem> <IconButton size="large" aria-label="show 4 new mails" color="inherit"> <Badge badgeContent={4} color="error"> <MailIcon /> </Badge> </IconButton> <p>Messages</p> </MenuItem> <MenuItem> <IconButton size="large" aria-label="show 17 new notifications" color="inherit" > <Badge badgeContent={17} color="error"> <NotificationsIcon /> </Badge> </IconButton> <p>Notifications</p> </MenuItem> <MenuItem onClick={handleProfileMenuOpen}> <IconButton size="large" aria-label="account of current user" aria-controls="primary-search-account-menu" aria-haspopup="true" color="inherit" > <AccountCircle /> </IconButton> <p>Profile</p> </MenuItem> </Menu> ); return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <Toolbar> <IconButton size="large" edge="start" color="inherit" aria-label="open drawer" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h6" noWrap component="div" sx={{ display: { xs: 'none', sm: 'block' } }} > MUI </Typography> <Search> <SearchIconWrapper> <SearchIcon /> </SearchIconWrapper> <StyledInputBase placeholder="Search…" inputProps={{ 'aria-label': 'search' }} /> </Search> <Box sx={{ flexGrow: 1 }} /> <Box sx={{ display: { xs: 'none', md: 'flex' } }}> <IconButton size="large" aria-label="show 4 new mails" color="inherit"> <Badge badgeContent={4} color="error"> <MailIcon /> </Badge> </IconButton> <IconButton size="large" aria-label="show 17 new notifications" color="inherit" > <Badge badgeContent={17} color="error"> <NotificationsIcon /> </Badge> </IconButton> <IconButton size="large" edge="end" aria-label="account of current user" aria-controls={menuId} aria-haspopup="true" onClick={handleProfileMenuOpen} color="inherit" > <AccountCircle /> </IconButton> </Box> <Box sx={{ display: { xs: 'flex', md: 'none' } }}> <IconButton size="large" aria-label="show more" aria-controls={mobileMenuId} aria-haspopup="true" onClick={handleMobileMenuOpen} color="inherit" > <MoreIcon /> </IconButton> </Box> </Toolbar> </AppBar> {renderMobileMenu} {renderMenu} </Box> ); }
Dense (desktop only)
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import MenuIcon from '@mui/icons-material/Menu'; export default function DenseAppBar() { return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <Toolbar variant="dense"> <IconButton edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }}> <MenuIcon /> </IconButton> <Typography variant="h6" color="inherit" component="div"> Photos </Typography> </Toolbar> </AppBar> </Box> ); }
Prominent
An emphasized app bar design.
import * as React from 'react'; import { styled } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; import MoreIcon from '@mui/icons-material/MoreVert'; const StyledToolbar = styled(Toolbar)(({ theme }) => ({ alignItems: 'flex-start', paddingTop: theme.spacing(1), paddingBottom: theme.spacing(2), // Override media queries injected by theme.mixins.toolbar '@media all': { minHeight: 128, }, })); export default function ProminentAppBar() { return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <StyledToolbar> <IconButton size="large" edge="start" color="inherit" aria-label="open drawer" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h5" noWrap component="div" sx={{ flexGrow: 1, alignSelf: 'flex-end' }} > MUI </Typography> <IconButton size="large" aria-label="search" color="inherit"> <SearchIcon /> </IconButton> <IconButton size="large" aria-label="display more actions" edge="end" color="inherit" > <MoreIcon /> </IconButton> </StyledToolbar> </AppBar> </Box> ); }
Bottom App bar
import * as React from 'react'; import { styled } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import CssBaseline from '@mui/material/CssBaseline'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import Paper from '@mui/material/Paper'; import Fab from '@mui/material/Fab'; import List from '@mui/material/List'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemAvatar from '@mui/material/ListItemAvatar'; import ListItemText from '@mui/material/ListItemText'; import ListSubheader from '@mui/material/ListSubheader'; import Avatar from '@mui/material/Avatar'; import MenuIcon from '@mui/icons-material/Menu'; import AddIcon from '@mui/icons-material/Add'; import SearchIcon from '@mui/icons-material/Search'; import MoreIcon from '@mui/icons-material/MoreVert'; const messages = [ { id: 1, primary: 'Lunch plans this week?', secondary: "I'm visiting the area soon. Want to meet up for a meal?", person: '/material-ui-static/images/avatar/5.jpg', }, { id: 2, primary: 'Gift Ideas', secondary: "Can you recommend a great gift for John's work milestone? I'm stumped and would appreciate your input.", person: '/material-ui-static/images/avatar/1.jpg', }, { id: 3, primary: 'New Dish to Test', secondary: "I'm experimenting with a new grilling recipe that I think could be fantastic.", person: '/material-ui-static/images/avatar/2.jpg', }, { id: 4, primary: 'Got Them!', secondary: "I secured passes for this year's ReactConf event.", person: '/material-ui-static/images/avatar/3.jpg', }, { id: 5, primary: 'Medical Visit Update', secondary: "My doctor's visit has been moved to next Saturday.", person: '/material-ui-static/images/avatar/4.jpg', }, { id: 6, primary: 'Interface Talk', secondary: "Menus triggered by the bottom app bar, like navigation drawers or overflow menus, appear as bottom sheets at a higher elevation than the bar itself.", person: '/material-ui-static/images/avatar/5.jpg', }, { id: 7, primary: 'Backyard Party', secondary: "Anyone up for a barbecue this weekend? I just got new outdoor furniture and I'm eager to start grilling.", person: '/material-ui-static/images/avatar/1.jpg', }, ]; const StyledFab = styled(Fab)({ position: 'absolute', zIndex: 1, top: -30, left: 0, right: 0, margin: '0 auto', }); export default function BottomAppBar() { return ( <React.Fragment> <CssBaseline /> <Paper square sx={{ pb: '50px' }}> <Typography variant="h5" gutterBottom component="div" sx={{ p: 2, pb: 0 }}> Inbox </Typography> <List sx={{ mb: 2 }}> {messages.map(({ id, primary, secondary, person }) => ( <React.Fragment key={id}> {id === 1 && ( <ListSubheader sx={{ bgcolor: 'background.paper' }}> Today </ListSubheader> )} {id === 3 && ( <ListSubheader sx={{ bgcolor: 'background.paper' }}> Yesterday </ListSubheader> )} <ListItemButton> <ListItemAvatar> <Avatar alt="Profile Picture" src={person} /> </ListItemAvatar> <ListItemText primary={primary} secondary={secondary} /> </ListItemButton> </React.Fragment> ))} </List> </Paper> <AppBar position="fixed" color="primary" sx={{ top: 'auto', bottom: 0 }}> <Toolbar> <IconButton color="inherit" aria-label="open drawer"> <MenuIcon /> </IconButton> <StyledFab color="secondary" aria-label="add"> <AddIcon /> </StyledFab> <Box sx={{ flexGrow: 1 }} /> <IconButton color="inherit"> <SearchIcon /> </IconButton> <IconButton color="inherit"> <MoreIcon /> </IconButton> </Toolbar> </AppBar> </React.Fragment> ); }
Fixed placement
When the app bar is set to a fixed position, its size does not affect the layout of the remaining page content. This may cause some content to be hidden behind the app bar. Here are three potential solutions:
- You can use
position="sticky"
instead of fixed. - You can render a second
<Toolbar />
component:
function App() { return ( <React.Fragment> <AppBar position="fixed"> <Toolbar>{/* content */}</Toolbar> </AppBar> <Toolbar /> </React.Fragment> ); }
- You can use
theme.mixins.toolbar
CSS:
const Offset = styled('div')(({ theme }) => theme.mixins.toolbar); function App() { return ( <React.Fragment> <AppBar position="fixed"> <Toolbar>{/* content */}</Toolbar> </AppBar> <Offset /> </React.Fragment> ); }
Scrolling
The
useScrollTrigger()
hook enables dynamic responses to user scrolling actions.Hide App bar
The app bar conceals itself when scrolling down to maximize space for content viewing.
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import CssBaseline from '@mui/material/CssBaseline'; import useScrollTrigger from '@mui/material/useScrollTrigger'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; import Slide from '@mui/material/Slide'; interface Props { /** * Injected by the documentation to work in an iframe. * You won't need it on your project. */ window?: () => Window; children?: React.ReactElement<unknown>; } function HideOnScroll(props: Props) { const { children, window } = props; // Typically, you won't need to set the window ref as useScrollTrigger // defaults to window. // This is set here only because the demo is in an iframe. const trigger = useScrollTrigger({ target: window ? window() : undefined, }); return ( <Slide appear={false} direction="down" in={!trigger}> {children ?? <div />} </Slide> ); } export default function HideAppBar(props: Props) { return ( <React.Fragment> <CssBaseline /> <HideOnScroll {...props}> <AppBar> <Toolbar> <Typography variant="h6" component="div"> Scroll to hide App bar </Typography> </Toolbar> </AppBar> </HideOnScroll> <Toolbar /> <Container> <Box sx={{ my: 2 }}> {[...new Array(12)] .map( () => `Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, ) .join('\n')} </Box> </Container> </React.Fragment> ); }
Elevate App bar
The app bar elevates during scrolling to indicate that the user is not at the top of the page.
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import CssBaseline from '@mui/material/CssBaseline'; import useScrollTrigger from '@mui/material/useScrollTrigger'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; interface Props { /** * Injected by the documentation to work in an iframe. * You won't need it on your project. */ window?: () => Window; children?: React.ReactElement<{ elevation?: number }>; } function ElevationScroll(props: Props) { const { children, window } = props; // Typically, you won't need to set the window ref as useScrollTrigger // defaults to window. // This is set here only because the demo is in an iframe. const trigger = useScrollTrigger({ disableHysteresis: true, threshold: 0, target: window ? window() : undefined, }); return children ? React.cloneElement(children, { elevation: trigger ? 4 : 0, }) : null; } export default function ElevateAppBar(props: Props) { return ( <React.Fragment> <CssBaseline /> <ElevationScroll {...props}> <AppBar> <Toolbar> <Typography variant="h6" component="div"> Scroll to elevate App bar </Typography> </Toolbar> </AppBar> </ElevationScroll> <Toolbar /> <Container> <Box sx={{ my: 2 }}> {[...new Array(12)] .map( () => `Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, ) .join('\n')} </Box> </Container> </React.Fragment> ); }
Back to top
A floating action button appears during scrolling to facilitate quick navigation back to the page's top.
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import CssBaseline from '@mui/material/CssBaseline'; import useScrollTrigger from '@mui/material/useScrollTrigger'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; import Fab from '@mui/material/Fab'; import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; import Fade from '@mui/material/Fade'; interface Props { /** * Injected by the documentation to work in an iframe. * You won't need it on your project. */ window?: () => Window; children?: React.ReactElement<unknown>; } function ScrollTop(props: Props) { const { children, window } = props; // Typically, you won't need to set the window ref as useScrollTrigger // defaults to window. // This is set here only because the demo is in an iframe. const trigger = useScrollTrigger({ target: window ? window() : undefined, disableHysteresis: true, threshold: 100, }); const handleClick = (event: React.MouseEvent<HTMLDivElement>) => { const anchor = ( (event.target as HTMLDivElement).ownerDocument || document ).querySelector('#back-to-top-anchor'); if (anchor) { anchor.scrollIntoView({ block: 'center', }); } }; return ( <Fade in={trigger}> <Box onClick={handleClick} role="presentation" sx={{ position: 'fixed', bottom: 16, right: 16 }} > {children} </Box> </Fade> ); } export default function BackToTop(props: Props) { return ( <React.Fragment> <CssBaseline /> <AppBar> <Toolbar> <Typography variant="h6" component="div"> Scroll to see button </Typography> </Toolbar> </AppBar> <Toolbar id="back-to-top-anchor" /> <Container> <Box sx={{ my: 2 }}> {[...new Array(12)] .map( () => `Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, ) .join('\n')} </Box> </Container> <ScrollTop {...props}> <Fab size="small" aria-label="scroll back to top"> <KeyboardArrowUpIcon /> </Fab> </ScrollTop> </React.Fragment> ); }
useScrollTrigger([options]) => trigger
Arguments
options
(object [optional]):options.disableHysteresis
(bool [optional]): Defaults tofalse
. Disables hysteresis, ignoring scroll direction when determining thetrigger
value.options.target
(Node [optional]): Defaults towindow
.options.threshold
(number [optional]): Defaults to100
. Adjusts thetrigger
value when the vertical scroll crosses this threshold (exclusive).
Returns
trigger
: Indicates whether the scroll position meets the specified criteria.Examples
import useScrollTrigger from '@mui/material/useScrollTrigger'; function HideOnScroll(props) { const trigger = useScrollTrigger(); return ( <Slide in={!trigger}> <div>Hello</div> </Slide> ); }
Enable color on dark
In accordance with Material Design guidelines, the
color
prop does not alter the app bar's appearance in dark mode. You can override this by setting the enableColorOnDark
prop to true
.import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Stack from '@mui/material/Stack'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import MenuIcon from '@mui/icons-material/Menu'; import { ThemeProvider, createTheme } from '@mui/material/styles'; function appBarLabel(label: string) { return ( <Toolbar> <IconButton edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }}> <MenuIcon /> </IconButton> <Typography variant="h6" noWrap component="div" sx={{ flexGrow: 1 }}> {label} </Typography> </Toolbar> ); } const darkTheme = createTheme({ palette: { mode: 'dark', primary: { main: '#1976d2', }, }, }); export default function EnableColorOnDarkAppBar() { return ( <Stack spacing={2} sx={{ flexGrow: 1 }}> <ThemeProvider theme={darkTheme}> <AppBar position="static" color="primary" enableColorOnDark> {appBarLabel('enableColorOnDark')} </AppBar> <AppBar position="static" color="primary"> {appBarLabel('default')} </AppBar> </ThemeProvider> </Stack> ); }