В библиотеке MUI (Material-UI) управление позиционированием элементов
выполняется с помощью системной пропсы sx, а также
стандартных компонентов, таких как AppBar,
Toolbar, Box и Typography.
Sticky заголовки — это заголовки, которые остаются
видимыми при прокрутке страницы или контейнера, но только до тех пор,
пока их родительский блок не выйдет из области видимости.
position: stickyОсновная логика sticky заголовков строится вокруг CSS-свойства
position: sticky. MUI полностью поддерживает это через
пропсу sx:
import { Box, Typography } from '@mui/material';
<Box sx={{ overflow: 'auto', maxHeight: 400 }}>
<Typography sx={{ position: 'sticky', top: 0, backgroundColor: '#fff', zIndex: 1 }}>
Заголовок
</Typography>
<Box>
{Array.from({ length: 50 }).map((_, i) => (
<Typography key={i}>Элемент {i + 1}</Typography>
))}
</Box>
</Box>
Ключевые моменты:
position: sticky фиксирует элемент относительно
ближайшего родителя с прокруткой.top: 0 указывает точку, от которой элемент будет
«прилипать».zIndex гарантирует, что заголовок будет отображаться
поверх других элементов.backgroundColor предотвращает наложение текста при
прокрутке.AppBarКомпонент AppBar поддерживает sticky режим через пропсу
position:
import { AppBar, Toolbar, Typography } from '@mui/material';
<AppBar position="sticky">
<Toolbar>
<Typography variant="h6">Главный заголовок</Typography>
</Toolbar>
</AppBar>
Отличия от стандартного CSS:
position="sticky" в AppBar автоматически
задаёт top: 0 и правильный zIndex для Material
Design.zIndex для корректного перекрытия.Для больших таблиц или списков часто требуется, чтобы заголовки колонок оставались видимыми:
import { Table, TableHead, TableBody, TableRow, TableCell } from '@mui/material';
<Table>
<TableHead sx={{ position: 'sticky', top: 0, backgroundColor: '#f5f5f5', zIndex: 2 }}>
<TableRow>
<TableCell>Имя</TableCell>
<TableCell>Возраст</TableCell>
<TableCell>Город</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Array.from({ length: 100 }).map((_, i) => (
<TableRow key={i}>
<TableCell>Пользователь {i + 1}</TableCell>
<TableCell>{20 + (i % 30)}</TableCell>
<TableCell>Город {i % 10}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
Особенности:
overflow.backgroundColor обязателен, иначе текст таблицы может
просвечивать.zIndex помогает заголовку оставаться поверх строк
таблицы.Когда заголовки изменяются динамически или добавляются новые секции,
важно использовать уникальные ключи и контролировать top
для каждого заголовка:
import { Box, Typography } from '@mui/material';
const sections = [
{ title: 'Секция 1', items: 20 },
{ title: 'Секция 2', items: 15 },
{ title: 'Секция 3', items: 30 },
];
<Box sx={{ overflowY: 'auto', maxHeight: 500 }}>
{sections.map((section, idx) => (
<Box key={idx}>
<Typography
sx={{
position: 'sticky',
top: 0,
backgroundColor: '#fff',
zIndex: 1,
padding: 1,
borderBottom: '1px solid #ddd',
}}
>
{section.title}
</Typography>
{Array.from({ length: section.items }).map((_, i) => (
<Typography key={i} sx={{ padding: 1 }}>
Элемент {i + 1}
</Typography>
))}
</Box>
))}
</Box>
Рекомендации:
top
может корректироваться суммой высот предыдущих заголовков.borderBottom или boxShadow
повышает визуальную читаемость.Чтобы заголовки оставались заметными в разных темах, MUI позволяет
использовать theme.palette в sx:
import { useTheme, Typography } from '@mui/material';
const theme = useTheme();
<Typography
sx={{
position: 'sticky',
top: 0,
backgroundColor: theme.palette.background.paper,
zIndex: 1,
padding: 1,
}}
>
Заголовок
</Typography>
Преимущества:
react-window или react-virtualized вместе с
sticky заголовками, чтобы уменьшить нагрузку на DOM.position: sticky, так как это
может вызывать подтормаживания на мобильных устройствах.Sticky заголовки в MUI позволяют создавать аккуратные интерфейсы с
фиксированными элементами, остающимися видимыми при прокрутке.
Правильная комбинация position: sticky, top,
zIndex и backgroundColor обеспечивает
стабильное и визуально чистое отображение заголовков в любых
компонентах.