DEV Community

Cover image for Dynamic Grid-Layout with Custom Properties and Resizable Elements (@properties)
Kuraikari
Kuraikari

Posted on

Dynamic Grid-Layout with Custom Properties and Resizable Elements (@properties)

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
  }
});
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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:


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)