Website Markup Using Material UI
Material UI (MUI) is a React component library implementing Material Design from Google. In version v5+ the library switched from JSS to emotion as the styling engine and provides a theme system via ThemeProvider. The component set covers almost the entire UI spectrum: from buttons to complex data grids.
Installation and Basic Theme
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
// src/theme/index.ts
import { createTheme, responsiveFontSizes } from '@mui/material/styles';
declare module '@mui/material/styles' {
interface Palette {
neutral: Palette['primary'];
}
interface PaletteOptions {
neutral?: PaletteOptions['primary'];
}
}
let theme = createTheme({
palette: {
primary: {
light: '#60a5fa',
main: '#2563eb',
dark: '#1d4ed8',
contrastText: '#ffffff',
},
secondary: {
main: '#7c3aed',
contrastText: '#ffffff',
},
neutral: {
main: '#6b7280',
light: '#9ca3af',
dark: '#374151',
contrastText: '#ffffff',
},
background: {
default: '#f9fafb',
paper: '#ffffff',
},
text: {
primary: '#111827',
secondary: '#6b7280',
disabled: '#9ca3af',
},
},
typography: {
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
h1: { fontWeight: 700, fontSize: '3rem' },
h2: { fontWeight: 700, fontSize: '2.25rem' },
h3: { fontWeight: 600, fontSize: '1.5rem' },
h4: { fontWeight: 600, fontSize: '1.25rem' },
body1: { fontSize: '1rem', lineHeight: 1.6 },
body2: { fontSize: '0.875rem', lineHeight: 1.57 },
},
shape: {
borderRadius: 8,
},
components: {
MuiButton: {
defaultProps: {
disableElevation: true,
},
styleOverrides: {
root: {
textTransform: 'none',
fontWeight: 500,
borderRadius: 8,
},
sizeLarge: {
padding: '12px 28px',
fontSize: '1rem',
},
},
},
MuiCard: {
defaultProps: {
elevation: 0,
},
styleOverrides: {
root: {
border: '1px solid #f3f4f6',
borderRadius: 12,
},
},
},
MuiTextField: {
defaultProps: {
variant: 'outlined',
size: 'small',
},
},
},
});
theme = responsiveFontSizes(theme);
export default theme;
// src/main.tsx
import { ThemeProvider, CssBaseline } from '@mui/material';
import theme from './theme';
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Router>...</Router>
</ThemeProvider>
);
}
Component Examples
Hero Section
import { Box, Container, Typography, Button, Stack } from '@mui/material';
const HeroSection = () => (
<Box
component="section"
sx={{
py: { xs: 8, md: 14 },
background: 'linear-gradient(135deg, #eff6ff 0%, #f5f3ff 100%)',
}}
>
<Container maxWidth="lg">
<Stack
direction={{ xs: 'column', md: 'row' }}
spacing={6}
alignItems="center"
>
<Box flex={1}>
<Typography
variant="h1"
sx={{ mb: 3, fontSize: { xs: '2rem', md: '3rem' } }}
>
Your Product Title
</Typography>
<Typography
variant="body1"
color="text.secondary"
sx={{ mb: 4, fontSize: '1.125rem', maxWidth: 480 }}
>
Description of your value proposition in two or three sentences.
</Typography>
<Stack direction="row" spacing={2} flexWrap="wrap">
<Button variant="contained" size="large" href="/start">
Start Free
</Button>
<Button variant="outlined" size="large" href="/demo">
View Demo
</Button>
</Stack>
</Box>
<Box flex={1}>
<Box
component="img"
src="/img/hero.webp"
alt="Product preview"
sx={{ width: '100%', borderRadius: 3, boxShadow: 6 }}
/>
</Box>
</Stack>
</Container>
</Box>
);
Service Cards
import { Grid, Card, CardContent, Typography } from '@mui/material';
import { Code, Cloud, Security } from '@mui/icons-material';
const services = [
{ icon: <Code />, title: 'Development', description: '...' },
{ icon: <Cloud />, title: 'Cloud', description: '...' },
{ icon: <Security />, title: 'Security', description: '...' },
];
const ServicesGrid = () => (
<Grid container spacing={3}>
{services.map((service) => (
<Grid item xs={12} sm={6} lg={4} key={service.title}>
<Card
sx={{
height: '100%',
transition: 'box-shadow 250ms ease',
'&:hover': { boxShadow: 4 },
}}
>
<CardContent sx={{ p: 4 }}>
<Box
sx={{
mb: 2,
color: 'primary.main',
'& svg': { fontSize: 40 },
}}
>
{service.icon}
</Box>
<Typography variant="h4" gutterBottom>
{service.title}
</Typography>
<Typography variant="body2" color="text.secondary">
{service.description}
</Typography>
</CardContent>
</Card>
</Grid>
))}
</Grid>
);
styled() for Custom Components
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
// MUI styled — access to theme via props
const GradientBox = styled(Box)(({ theme }) => ({
background: `linear-gradient(135deg, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`,
borderRadius: theme.shape.borderRadius * 2,
padding: theme.spacing(6),
color: '#fff',
[theme.breakpoints.down('md')]: {
padding: theme.spacing(4),
},
}));
Dark Theme
import { createTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
const App = () => {
const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
const theme = createTheme({
palette: {
mode: prefersDark ? 'dark' : 'light',
// Rest of overrides...
},
});
return <ThemeProvider theme={theme}>...</ThemeProvider>;
};
Bundle Optimization
MUI imports components component-by-component automatically via babel-plugin or tree-shaking:
// Correct — tree-shaking works
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
// Or via destructuring (tree-shaking in Vite works too)
import { Button, Card, Typography } from '@mui/material';
Icons — only necessary ones:
import CodeIcon from '@mui/icons-material/Code'; // Correct
// import { Code } from '@mui/icons-material'; // Slower at build
Timeline
Theme setup and ThemeProvider: 3–4 hours (careful designer collaboration). Landing page: 1.5–2 days. Full website with forms, modals, data tables: 4–8 days depending on functionality.







