Installation
Grids in Sync UI are built using Material-UI and Framer Motion:npm install @mui/material @emotion/react @emotion/styled framer-motion
Variants
Masonry
A cascading grid layout with items of varying heights.import React from "react";
import { Box } from "@mui/material";
import { motion } from "motion/react";
const MotionBox = motion.create(Box);
const MasonryGrid = () => {
const images = [
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e",
"https://images.unsplash.com/photo-1469474968028-56623f02e42e",
];
const items = Array.from({ length: 9 }, (_, i) => ({
id: i + 1,
imageUrl: images[i % images.length],
}));
return (
<MotionBox
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
sx={{
columnCount: { xs: 1, sm: 2, md: 3 },
columnGap: "16px",
padding: 2,
width: "100%",
}}
>
{items.map((item, index) => (
<MotionBox
key={item.id}
whileHover={{ scale: 1.03 }}
sx={{
mb: "16px",
breakInside: "avoid-column",
borderRadius: 2,
overflow: "hidden",
cursor: "pointer",
boxShadow: "0 2px 10px rgba(0,0,0,0.1)",
}}
>
<Box
sx={{
width: "100%",
height: 250 + (index % 4) * 40,
backgroundImage: `url(${item.imageUrl})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
/>
</MotionBox>
))}
</MotionBox>
);
};
export default MasonryGrid;
Bento
A Japanese-style compartmentalized grid with structured layout.import React from "react";
import { Box } from "@mui/material";
import { motion } from "motion/react";
const MotionBox = motion.create(Box);
const BentoGrid = () => {
const images = [
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e",
"https://images.unsplash.com/photo-1469474968028-56623f02e42e",
"https://images.unsplash.com/photo-1439066615861-d1af74d74000",
];
return (
<MotionBox
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
sx={{
padding: 2,
display: "grid",
gap: 2,
gridTemplateColumns: { xs: "1fr", md: "2fr 1fr" },
gridTemplateRows: "auto auto auto",
}}
>
<MotionBox
sx={{
gridColumn: { md: "1" },
gridRow: { md: "1 / 3" },
minHeight: { xs: 260, md: 480 },
backgroundImage: `url(${images[0]})`,
backgroundSize: "cover",
borderRadius: 3,
boxShadow: "0 0 0 1px rgba(0,0,0,0.1)",
}}
/>
{[1, 2].map((i) => (
<MotionBox
key={i}
sx={{
minHeight: 200,
backgroundImage: `url(${images[i]})`,
backgroundSize: "cover",
borderRadius: 3,
boxShadow: "0 0 0 1px rgba(0,0,0,0.1)",
}}
/>
))}
<MotionBox
sx={{
gridColumn: { md: "1" },
height: 200,
borderRadius: 3,
backgroundImage: `url(${images[3]})`,
backgroundSize: "cover",
}}
/>
<MotionBox
sx={{
gridColumn: { md: "2" },
height: 200,
borderRadius: 3,
backgroundImage: `url(${images[4]})`,
backgroundSize: "cover",
}}
/>
</MotionBox>
);
};
export default BentoGrid;
Glassmorphism
A grid with frosted glass cards and inner content containers.import React from "react";
import { Box } from "@mui/material";
import { motion } from "motion/react";
const MotionBox = motion.create(Box);
const GlassmorphismGrid = () => {
const images = [
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e",
"https://images.unsplash.com/photo-1469474968028-56623f02e42e",
];
return (
<MotionBox
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
sx={{
display: "grid",
gap: 2,
padding: 2,
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2,1fr)",
md: "repeat(3,1fr)",
},
}}
>
{Array.from({ length: 6 }).map((_, index) => (
<MotionBox
key={index}
sx={{
height: 260,
borderRadius: 4,
backdropFilter: "blur(10px)",
border: "1px solid rgba(255,255,255,0.2)",
display: "flex",
justifyContent: "center",
alignItems: "center",
padding: 2,
}}
>
<Box
sx={{
height: "90%",
width: "90%",
borderRadius: 3,
backgroundImage: `url(${images[index % images.length]})`,
backgroundSize: "cover",
boxShadow: "0 4px 20px rgba(0,0,0,0.12)",
}}
/>
</MotionBox>
))}
</MotionBox>
);
};
export default GlassmorphismGrid;
Organic Shapes
A playful grid with smooth, irregular shapes using stable memoized radii.import React from "react";
import { Box } from "@mui/material";
import { motion } from "motion/react";
const MotionBox = motion.create(Box);
const OrganicShapesGrid = () => {
const images = [
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e",
];
const shapes = React.useMemo(() => {
return Array.from({ length: 6 }).map(() => {
const rand = () => Math.floor(Math.random() * 20) + 25;
return `${rand()}px ${rand()}px ${rand()}px ${rand()}px`;
});
}, []);
return (
<MotionBox
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
sx={{
display: "grid",
gap: 2,
padding: 2,
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2,1fr)",
md: "repeat(3,1fr)",
},
}}
>
{Array.from({ length: 6 }).map((_, index) => (
<MotionBox
key={index}
sx={{
height: 260,
borderRadius: shapes[index],
backgroundImage: `url(${images[index % images.length]})`,
backgroundSize: "cover",
backgroundPosition: "center",
boxShadow: "0 0 0 1px rgba(0,0,0,0.1)",
}}
/>
))}
</MotionBox>
);
};
export default OrganicShapesGrid;
Minimal Cards
A clean card layout with soft shadows and rounded corners.import React from "react";
import { Box } from "@mui/material";
import { motion } from "motion/react";
const MotionBox = motion.create(Box);
const MinimalCardsGrid = () => {
const images = [
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e",
];
return (
<MotionBox
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
sx={{
display: "grid",
gap: 2,
padding: 2,
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2,1fr)",
md: "repeat(3,1fr)",
},
}}
>
{Array.from({ length: 6 }).map((_, index) => (
<MotionBox
key={index}
whileHover={{ scale: 1.02 }}
sx={{
height: 260,
borderRadius: 2,
backgroundColor: "background.paper",
boxShadow: "0 0 0 1px rgba(0,0,0,0.1)",
backgroundImage: `url(${images[index % images.length]})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
/>
))}
</MotionBox>
);
};
export default MinimalCardsGrid;
Customization
All grid variants can be customized using Material-UI’ssx prop. Common customizations include:
- Responsive breakpoints: Adjust
gridTemplateColumnsfor different screen sizes - Spacing: Modify
gapandpaddingvalues - Colors: Use theme palette values for backgrounds and borders
- Heights: Customize
minHeightandheightproperties - Animations: Adjust Framer Motion animation properties
- Border radius: Change the roundness of corners
Dependencies
@mui/material- Material-UI componentsframer-motionormotion/react- Animation library