Modular Grid
A composable layout grid that provides responsive breakpoints and configurable variants for building structured UI sections.
Ubuntu
User-friendly distro with strong community support and regular LTS releases.
Fedora
Cutting-edge features with a focus on innovation and upstream technologies.
Debian
Extremely stable and reliable, ideal for servers and long-term use.
Arch Linux
Minimal and highly customizable, built for advanced users.
openSUSE
Flexible distro with powerful system management tools like YaST.
Pop!_OS
Developer-focused distro optimized for productivity and hardware support.
Elementary OS
Clean and elegant distro focused on simplicity and design.
Linux Mint
Beginner-friendly distro with a familiar desktop experience.
1. Copy the component file
Create a new file called modular-grid.jsx in
your reusable components folder (for example
/src/components/) and paste the following code
into it.
modular-grid.jsx
import styles from "./modular-grid.module.css";
const ModularGridItem = (props) => {
const {
xs = 12,
sm = 12,
md = 12,
lg = 12,
xl = 12,
xxl = 12,
children,
} = props;
return (
<div
className={[
styles["grid-item"],
styles[`col-xs-${xs}`],
styles[`col-sm-${sm}`],
styles[`col-md-${md}`],
styles[`col-lg-${lg}`],
styles[`col-xl-${xl}`],
styles[`col-xxl-${xxl}`],
].join(" ")}
>
{children}
</div>
);
};
const ModularGrid = (props) => {
const {
children,
spacing = 16,
variant = "none",
} = props;
return (
<div
style={{ "--grid-spacing": spacing }}
className={[
styles["modular-grid"],
styles[`variant-${variant}`]
].join(" ")
}
>
{children}
</div>
);
};
export { ModularGridItem };
export default ModularGrid; 2. Copy the CSS module file
In the same folder, create a file called modular-grid.module.css and paste the following CSS.
modular-grid.module.css
.modular-grid {
--grid-item-border-color: #ddd;
--grid-spacing: 16;
@media (prefers-color-scheme: dark) {
--grid-item-border-color: #222;
}
width: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: calc(var(--grid-spacing) * 1px);
>.grid-item {
display: flex;
flex-direction: column;
grid-column: span 1;
@media (min-width: 1400px) {
&.col-xxl-1 {
grid-column: span 1;
}
&.col-xxl-2 {
grid-column: span 2;
}
&.col-xxl-3 {
grid-column: span 3;
}
&.col-xxl-4 {
grid-column: span 4;
}
&.col-xxl-5 {
grid-column: span 5;
}
&.col-xxl-6 {
grid-column: span 6;
}
&.col-xxl-7 {
grid-column: span 7;
}
&.col-xxl-8 {
grid-column: span 8;
}
&.col-xxl-9 {
grid-column: span 9;
}
&.col-xxl-10 {
grid-column: span 10;
}
&.col-xxl-11 {
grid-column: span 11;
}
&.col-xxl-12 {
grid-column: span 12;
}
}
@media (max-width: 1400px) {
&.col-xl-1 {
grid-column: span 1;
}
&.col-xl-2 {
grid-column: span 2;
}
&.col-xl-3 {
grid-column: span 3;
}
&.col-xl-4 {
grid-column: span 4;
}
&.col-xl-5 {
grid-column: span 5;
}
&.col-xl-6 {
grid-column: span 6;
}
&.col-xl-7 {
grid-column: span 7;
}
&.col-xl-8 {
grid-column: span 8;
}
&.col-xl-9 {
grid-column: span 9;
}
&.col-xl-10 {
grid-column: span 10;
}
&.col-xl-11 {
grid-column: span 11;
}
&.col-xl-12 {
grid-column: span 12;
}
}
@media (max-width: 1200px) {
&.col-lg-1 {
grid-column: span 1;
}
&.col-lg-2 {
grid-column: span 2;
}
&.col-lg-3 {
grid-column: span 3;
}
&.col-lg-4 {
grid-column: span 4;
}
&.col-lg-5 {
grid-column: span 5;
}
&.col-lg-6 {
grid-column: span 6;
}
&.col-lg-7 {
grid-column: span 7;
}
&.col-lg-8 {
grid-column: span 8;
}
&.col-lg-9 {
grid-column: span 9;
}
&.col-lg-10 {
grid-column: span 10;
}
&.col-lg-11 {
grid-column: span 11;
}
&.col-lg-12 {
grid-column: span 12;
}
}
@media (max-width: 992px) {
&.col-md-1 {
grid-column: span 1;
}
&.col-md-2 {
grid-column: span 2;
}
&.col-md-3 {
grid-column: span 3;
}
&.col-md-4 {
grid-column: span 4;
}
&.col-md-5 {
grid-column: span 5;
}
&.col-md-6 {
grid-column: span 6;
}
&.col-md-7 {
grid-column: span 7;
}
&.col-md-8 {
grid-column: span 8;
}
&.col-md-9 {
grid-column: span 9;
}
&.col-md-10 {
grid-column: span 10;
}
&.col-md-11 {
grid-column: span 11;
}
&.col-md-12 {
grid-column: span 12;
}
}
@media (max-width: 768px) {
&.col-sm-1 {
grid-column: span 1;
}
&.col-sm-2 {
grid-column: span 2;
}
&.col-sm-3 {
grid-column: span 3;
}
&.col-sm-4 {
grid-column: span 4;
}
&.col-sm-5 {
grid-column: span 5;
}
&.col-sm-6 {
grid-column: span 6;
}
&.col-sm-7 {
grid-column: span 7;
}
&.col-sm-8 {
grid-column: span 8;
}
&.col-sm-9 {
grid-column: span 9;
}
&.col-sm-10 {
grid-column: span 10;
}
&.col-sm-11 {
grid-column: span 11;
}
&.col-sm-12 {
grid-column: span 12;
}
}
@media (max-width: 576px) {
&.col-xs-1 {
grid-column: span 1;
}
&.col-xs-2 {
grid-column: span 2;
}
&.col-xs-3 {
grid-column: span 3;
}
&.col-xs-4 {
grid-column: span 4;
}
&.col-xs-5 {
grid-column: span 5;
}
&.col-xs-6 {
grid-column: span 6;
}
&.col-xs-7 {
grid-column: span 7;
}
&.col-xs-8 {
grid-column: span 8;
}
&.col-xs-9 {
grid-column: span 9;
}
&.col-xs-10 {
grid-column: span 10;
}
&.col-xs-11 {
grid-column: span 11;
}
&.col-xs-12 {
grid-column: span 12;
}
}
}
&.variant-outlined>.grid-item {
border: 1px solid var(--grid-item-border-color);
}
&.variant-shadow>.grid-item {
box-shadow: 0 2px 6px var(--grid-item-shadow-color);
}
} 3. Use the component
Now you can import and use the component anywhere in your project.
modular-grid-preview.jsx
import ModularGrid, { ModularGridItem } from "@/components/essentials/modular-grid/modular-grid";
const ModularGridPreview = () => {
return (
<div style={{ width: "100%", padding: "24px" }}>
<ModularGrid>
<ModularGridItem xxl={6} xl={6}>
<Card
title="Ubuntu"
description="User-friendly distro with strong community support and regular LTS releases."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Fedora"
description="Cutting-edge features with a focus on innovation and upstream technologies."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Debian"
description="Extremely stable and reliable, ideal for servers and long-term use."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="Arch Linux"
description="Minimal and highly customizable, built for advanced users."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="openSUSE"
description="Flexible distro with powerful system management tools like YaST."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Pop!_OS"
description="Developer-focused distro optimized for productivity and hardware support."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Elementary OS"
description="Clean and elegant distro focused on simplicity and design."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="Linux Mint"
description="Beginner-friendly distro with a familiar desktop experience."
/>
</ModularGridItem>
</ModularGrid>
</div>
);
};
const Card = (props) => {
const {
title,
description
} = props;
return (
<div
className="card"
style={{
background: "var(--layer-tertiary)",
padding: "24px",
borderRadius: "8px",
height: "100%"
}}
>
<h4
style={{
marginBottom: "4px"
}}
>
{title}
</h4>
<p>{description}</p>
</div>
)
};
export default ModularGridPreview; Outlined Variant
Ubuntu
User-friendly distro with strong community support and regular LTS releases.
Fedora
Cutting-edge features with a focus on innovation and upstream technologies.
Debian
Extremely stable and reliable, ideal for servers and long-term use.
Arch Linux
Minimal and highly customizable, built for advanced users.
openSUSE
Flexible distro with powerful system management tools like YaST.
Pop!_OS
Developer-focused distro optimized for productivity and hardware support.
Elementary OS
Clean and elegant distro focused on simplicity and design.
Linux Mint
Beginner-friendly distro with a familiar desktop experience.
modular-grid
import ModularGrid, { ModularGridItem } from "@/components/essentials/modular-grid/modular-grid";
const ModularGridOutlinedVariantPreview = () => {
return (
<div style={{ width: "100%", padding: "24px" }}>
<ModularGrid variant="outlined">
<ModularGridItem xxl={6} xl={6}>
<Card
title="Ubuntu"
description="User-friendly distro with strong community support and regular LTS releases."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Fedora"
description="Cutting-edge features with a focus on innovation and upstream technologies."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Debian"
description="Extremely stable and reliable, ideal for servers and long-term use."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="Arch Linux"
description="Minimal and highly customizable, built for advanced users."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="openSUSE"
description="Flexible distro with powerful system management tools like YaST."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Pop!_OS"
description="Developer-focused distro optimized for productivity and hardware support."
/>
</ModularGridItem>
<ModularGridItem xxl={3} xl={6}>
<Card
title="Elementary OS"
description="Clean and elegant distro focused on simplicity and design."
/>
</ModularGridItem>
<ModularGridItem xxl={6} xl={6}>
<Card
title="Linux Mint"
description="Beginner-friendly distro with a familiar desktop experience."
/>
</ModularGridItem>
</ModularGrid>
</div>
);
};
const Card = (props) => {
const {
title,
description
} = props;
return (
<div
className="card"
style={{
padding: "24px",
borderRadius: "8px",
height: "100%"
}}
>
<h4
style={{
marginBottom: "4px"
}}
>
{title}
</h4>
<p>{description}</p>
</div>
)
};
export default ModularGridOutlinedVariantPreview; Props
Configure the component with the following props:
ModularGrid Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| spacing | number | No | 16 | Space between grid items in pixels. Example: 16 = 16px gap. |
| variant | 'none' | 'outlined' | No | 'none' | Visual style applied to grid items. |
| children | React.ReactNode | Yes | — | ModularGridItem components rendered inside the grid. |
ModularGridItem Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| xs | number | No | 12 | Columns to span on extra-small screens (0px+). |
| sm | number | No | 12 | Columns to span on small screens (≥576px). |
| md | number | No | 12 | Columns to span on medium screens (≥768px). |
| lg | number | No | 12 | Columns to span on large screens (≥992px). |
| xl | number | No | 12 | Columns to span on extra-large screens (≥1200px). |
| xxl | number | No | 12 | Columns to span on very large screens (≥1400px). |
| children | React.ReactNode | Yes | — | Content rendered inside the grid item. |