MUI (Material-UI) предлагает несколько способов стилизации компонентов, среди которых наиболее актуальны:
sx проп – краткий и мощный способ
задавать стили на уровне компонента. Позволяет использовать объектную
запись, похожую на CSS-in-JS, с поддержкой темизации.styled API – совместимый с Emotion и
styled-components подход, который позволяет создавать переиспользуемые
стилизованные компоненты.makeStyles и withStyles –
устаревающие, но все еще применяемые в существующих проектах методы,
подходящие для пошаговой миграции.Главная идея при миграции заключается в том, что MUI интегрирует стили в компоненты на уровне их API, что упрощает поддержку темы и сокращает необходимость создавать отдельные файлы стилей.
styledРассмотрим типичный компонент на styled-components:
import styled from 'styled-components';
const Button = styled.button`
background-color: ${(props) => props.primary ? 'blue' : 'gray'};
color: white;
padding: 8px 16px;
border-radius: 4px;
&:hover {
opacity: 0.8;
}
`;
Его аналог на MUI будет выглядеть так:
import { styled } from '@mui/material/styles';
import ButtonBase from '@mui/material/Button';
const Button = styled(ButtonBase)(({ theme, primary }) => ({
backgroundColor: primary ? theme.palette.primary.main : theme.palette.grey[500],
color: theme.palette.common.white,
padding: '8px 16px',
borderRadius: 4,
'&:hover': {
opacity: 0.8,
},
}));
Ключевые отличия:
theme для доступа к
цветовой палитре и другим параметрам темы.styled из MUI работает совместимо с Emotion под
капотом, что облегчает плавный переход.css и jsx в sx и
styledКомпоненты, написанные с использованием Emotion css:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
const style = (primary) => css`
background-color: ${primary ? 'blue' : 'gray'};
color: white;
padding: 8px 16px;
border-radius: 4px;
`;
export const Button = ({ primary, children }) => (
<button css={style(primary)}>{children}</button>
);
На MUI можно переписать двумя способами:
Через sx проп:
import Button from '@mui/material/Button';
export const Button = ({ primary, children }) => (
<Button
sx={{
backgroundColor: primary ? 'primary.main' : 'grey.500',
color: 'common.white',
p: '8px 16px',
borderRadius: 1,
'&:hover': {
opacity: 0.8,
},
}}
>
{children}
</Button>
);
Через styled API:
import { styled } from '@mui/material/styles';
import ButtonBase from '@mui/material/Button';
const Button = styled(ButtonBase, {
shouldForwardProp: (prop) => prop !== 'primary',
})(({ theme, primary }) => ({
backgroundColor: primary ? theme.palette.primary.main : theme.palette.grey[500],
color: theme.palette.common.white,
padding: '8px 16px',
borderRadius: 4,
'&:hover': {
opacity: 0.8,
},
}));
Примечания при миграции:
shouldForwardProp предотвращает
передачу пользовательских пропов в DOM, что критично при использовании
нестандартных атрибутов.sx проп.styled,
чтобы сохранять чистоту кода и переиспользуемость.MUI интегрирует систему тем, которая позволяет полностью отказаться от магических цветов в коде. Пример переноса темы:
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
grey: {
500: '#9e9e9e',
},
},
});
export default theme;
В styled-components или Emotion тема использовалась через
ThemeProvider и хук useTheme. В MUI подход
схож, но объект темы уже предоставляет доступ к Material Design palette,
типам и размерам компонентов, упрощая единообразие интерфейса.
Для глобальных CSS, ранее применяемых через
createGlobalStyle (styled-components) или
Global (Emotion), MUI предлагает
GlobalStyles:
import { GlobalStyles } from '@mui/styled-engine';
<GlobalStyles
styles={{
body: {
margin: 0,
padding: 0,
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
backgroundColor: '#f5f5f5',
},
}}
/>
Особенности:
GlobalStyles интегрируется с темой и позволяет
использовать переменные theme.palette и
theme.spacing.MUI позволяет задавать адаптивные стили через объектную структуру:
<Box
sx={{
width: {
xs: '100%', // до small
sm: '50%', // от small и выше
md: '25%', // от medium и выше
},
p: 2,
}}
/>
Это заменяет медиазапросы в styled-components и Emotion и упрощает поддержку адаптивности без внешних зависимостей.
sx для
простых случаев – быстрый выигрыш.styled для сложных компонентов с
логикой пропсов – сохраняет читаемость.GlobalStyles – упрощение и интеграция с
темой.sx – уменьшение CSS-файлов и inline
медиазапросов.В MUI пропсы, влияющие на стиль, передаются в styled
через функцию:
const Card = styled(Box)(({ theme, highlighted }) => ({
backgroundColor: highlighted ? theme.palette.primary.light : theme.palette.background.paper,
border: `1px solid ${theme.palette.divider}`,
}));
Рекомендации:
theme для всех цветов, шрифтов и
отступов.sx для быстрой стилизации и
styled для переиспользуемых компонентов.GlobalStyles.Это позволяет постепенно отказаться от styled-components и Emotion, сохраняя логическую структуру компонентов и повышая согласованность интерфейса.