CSS Grid is one of the most powerful layout systems ever created. But let's be honest - remembering grid-template-columns, grid-area, and all those line numbers can be a headache, especially when you're just trying to prototype an idea.
That's why I built Gridzzly - a visual playground where you click and drag to create grid items, edit track sizes in real time, and export production‑ready HTML/CSS with one click.
Live Demo: https://gridzzly.vercel.app
GitHub Repo: github.com/byllzz/gridzzly
What Makes Gridzzly Different?
- Visual Drawing - Click and drag across the grid. Release to create a new grid item. No writing
grid-row or grid-column manually.
- Live Track Editing - Edit column/row sizes directly in inputs above the grid. Use
1fr, auto, 200px, minmax() - anything CSS Grid supports.
- Instant Code Export - Switch between CSS and HTML tabs, copy the code, and paste it into your project.
- Built‑in Templates & Random Generator - Stuck? Load a preset or hit "Random Pattern" for instant inspiration.
- Overlapping Items - Place items on top of each other (great for magazine‑style layouts).
- Dark Theme - Easy on the eyes for long coding sessions.
How It Works (Under the Hood)
The entire app is built with React and Tailwind CSS. The core logic lives inside a custom hook: useGridGenerator.js.
1. Grid State
We store:
- Number of columns/rows
- Gap values (in pixels)
- Column/row size strings (e.g.,
['1fr', '2fr', '1fr'])
- Placed items: each item is an object
{ id, rStart, cStart, rEnd, cEnd }
2. Drawing Mechanism
When the user mouses down on a cell, we start tracking the starting row/column. On mouse move, we calculate the rectangle between the start and current cell, highlight all cells, and show a live badge (3 cols Ă— 2 rows). On mouse up, we create a new item and reset the selection.
// Simplified from useGridGenerator.js
const startDrawing = (row, col) => {
setIsDrawing(true);
setStartCell({ row, col });
setHighlightedCells([{ row, col }]);
};
const updateDrawing = (row, col) => {
if (!isDrawing || !startCell) return;
const rMin = Math.min(startCell.row, row);
const rMax = Math.max(startCell.row, row);
const cMin = Math.min(startCell.col, col);
const cMax = Math.max(startCell.col, col);
// highlight all cells from rMin..rMax, cMin..cMax
};
3. Code Generation
Every time the grid or items change, we generate fresh CSS + HTML. We even compress consecutive identical track sizes into repeat():
css
/* Instead of: */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* We output: */
grid-template-columns: repeat(4, 1fr);
The generated HTML uses simple div elements with classes like .div1, .div2, and a .parent container.
Quick Usage Guide
- Create a grid item: Click and drag across empty cells → release
- Delete an item: Hover the item → click the × Resize a track: Click
- the input above the grid (e.g., 1fr) → type a new value Change grid
- Scroll through "Grid Patterns" → click any preview Random layout:
- Click Random Grid Pattern Export code: Click Please May I have Some
- Code → copy CSS or HTML
Why I Built This
I've taught CSS Grid to many developers, and the hardest part is always the mental model of grid lines and spanning. I wanted a tool that gives immediate visual feedback while generating real, copy‑pastable code – no vendor lock‑in, no weird abstractions. Just vanilla CSS Grid.
Whether you're:
- Learning CSS Grid for the first time,
- Prototyping a dashboard layout,
- Or building a complex magazine‑style design,
Gridzzly helps you see what you're building and export it instantly.
Contributions Welcome
Found a bug? Have an idea for a feature? Open an issue or a pull request. The project is MIT licensed, so feel free to fork and build your own version.
Let's Connect
GitHub: @byllzz
Twitter: @bilalmlkdev
If you found this useful, please ❤️ the post and share it with your network.
Happy Gridding! 🎉