Copied information from the CodePen:
Grid using custom properties for columns and rows. It also features are drag to resize, using a simple drag-handle. The resize is snapped to the grid spans.
Browser support baseline-status added for transparency.
Here's the revised version of the DEV.to post with code blocks added for key parts:
Hello, DEV community! ?
I've been experimenting with CSS grids lately, and I want to share a fun project: Grid with Custom Properties and Resizable Elements. This pen started as an attempt to create a Bento-style grid but evolved into something more dynamic, featuring customizable grid dimensions and draggable resizable elements. While there's room to grow (drag-to-reorder is next on my list!), I’m excited about what’s already possible with this setup.
Let’s break it down! ?
I used the @property at-rule to define custom properties, which add type safety and control inheritance. Here’s an example from the project:
@property --grid-cols { syntax: "<integer>"; inherits: false; initial-value: 12; } @property --grid-rows { syntax: "<integer>"; inherits: false; initial-value: 12; } @property --col-span { syntax: "<integer>"; inherits: false; initial-value: 2; } @property --row-span { syntax: "<integer>"; inherits: false; initial-value: 2; }
These properties allow the grid layout to be dynamically adjusted with minimal effort, whether via CSS or JavaScript. For example, you can set the grid structure with:
.grid { display: grid; grid-template-columns: repeat(var(--grid-cols), 1fr); grid-template-rows: repeat(var(--grid-rows), 1fr); gap: var(--grid-gap); }
Each grid element has a draggable corner handle that lets users resize the element while snapping it to the grid. The drag-handle is styled like this:
.grid-element .drag-handle { position: absolute; right: 0; bottom: 0; width: 20px; height: 20px; background: skyblue; border-radius: 50%; cursor: nwse-resize; }
The resizing logic is implemented in JavaScript, snapping the size of the element to grid spans. Here’s a simplified snippet of how resizing works:
dragHandle.addEventListener('mousedown', (event) => { const startX = event.clientX; const startY = event.clientY; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); function onMouseMove(e) { const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; // Calculate new spans based on the grid dimensions const colSpan = Math.max(1, Math.round(deltaX / gridCellWidth)); const rowSpan = Math.max(1, Math.round(deltaY / gridCellHeight)); gridElement.style.gridColumnEnd = `span ${colSpan}`; gridElement.style.gridRowEnd = `span ${rowSpan}`; } function onMouseUp() { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } });
The custom properties --col-span and --row-span control the default size of each grid item. Here’s how they’re applied:
.grid-element { grid-column: span var(--col-span); grid-row: span var(--row-span); }
This approach simplifies styling and makes it easy to dynamically add or resize elements programmatically.
This project showcases the power of modern CSS combined with some light JavaScript to create interactive and dynamic layouts. By using @property and CSS grid features, we’ve created a foundation for a customizable, resizable grid system.
Future plans include adding drag-to-reorder functionality so users can rearrange elements, making the grid even more interactive.
For transparency, I’ve included baseline-status elements to show browser support for the experimental features used.
Here are some helpful links to learn more about the CSS features used in this project:
I’d love to hear your feedback or ideas for further improvements! Let me know what you think in the comments, or feel free to fork the Pen and make it your own. ?
Happy coding! ?✨
The above is the detailed content of Dynamic Grid-Layout with Custom Properties and Resizable Elements (@properties). For more information, please follow other related articles on the PHP Chinese website!