Advertisement

Interactive Drag-and-Drop Jigsaw Puzzle

| by Vladimir | 2 min read | code by Temani Afif
Advanced

Tech & Dependencies

Pug SCSS

Features

  • Zero JS
  • Geometric Masking
  • State Retention

Browser Support

Chrome 84+ Edge 84+ Firefox 90+ Safari 15.4+

Core

This is an Interactive Drag-and-Drop Jigsaw Puzzle. It dissects a single raster image into an interlocking grid of movable pieces without relying on a single line of JavaScript. Its function is to gamify visual content, converting passive image consumption into a tactile, logic-driven interaction.

Specs

  • Weight: < 4 KB (Zero dependencies).
  • Performance: GPU-intensive. Relies heavily on concurrent hardware-accelerated radial-gradient masks and matrix transformations.
  • Theming: Strict mathematical control. Driven by two SCSS variables: $n (grid dimension) and --s (piece size).
  • Responsiveness: Fixed physical dimensions. Scaling requires adjusting the root CSS variables via media queries.
  • Graceful Degradation: [!] Accessibility is non-existent. Keyboard navigation is impossible. If CSS masks are unsupported, the pieces render as solid overlapping squares, breaking the visual mechanics.

Anatomy

  • HTML: A Pug-generated matrix. The <g> tag acts as the board, holding <z> cells. Each cell contains an invisible trigger <a> and the visual puzzle piece <b>.
  • CSS: The absolute core of the system. SCSS loops calculate the precise background offset for each item based on its grid coordinate. Complex mask: radial-gradient(...) rules carve out the tabs and blanks of the jigsaw edges.
  • JS: Absent. State and memory are simulated entirely through CSS cascading logic.

Logic

The drag-and-drop mechanism is an ingenious exploitation of CSS transition delays and sibling selectors.

z a:hover ~ b {
    transform: translate(0);
    filter: none;
    transition: 0s;
}
z b {
    transition: 9999s 9999s;
}

When a scrambled piece (<b>) is dragged near its correct cell drop-zone, the invisible trigger (<a>) activates on hover. The sibling selector (~) instantly snaps the piece to its true origin (translate(0)) with zero transition time. When the user releases the mouse, the piece logically attempts to return to its scrambled state. However, a massive transition delay (9999s) freezes the element in its solved position indefinitely. It is simulated application memory.

Feel

Mechanical and magnetic. Dragging a piece feels slightly detached, as it relies on native HTML drag rendering rather than JS cursor tracking. However, hovering over the correct target cell triggers an instant, satisfying snap. It feels like locking strong magnets onto a rigid metal grid.

Advertisement