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:
Grid with Custom Properties and Resizable Elements
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! 🎉
🛠️ How It Works
@property
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);
}
Drag-to-Resize
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);
}
});
col-span and row-span
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.
Test it out yourself!
📌 Conclusion
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.
📚 Resources
Here are some helpful links to learn more about the CSS features used in this project:
- MDN: @property
- MDN: CSS Grid Layout
- MDN: Cascade Layers
- MDN: Starting Styles
- MDN: Relative Colors: Simplify color adjustments directly in CSS.
- MDN: Logical Properties: Write direction-agnostic CSS for multi-language support.
- MDN: Container Queries: Adapt layouts based on a container's size rather than the viewport.
-
MDN:
currentColor
Keyword: Use the current text color in other CSS properties like borders or backgrounds. - MDN: -web-kit-Line Clamp: Control the maximum number of lines displayed in a block element.
- MDN: Transition Behavior - Allow-Discrete: Define how discrete values change during transitions.
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! 💻✨
Top comments (0)