Under the Hood: Drag, Touch, and CSS Cascade

Building a resizable UI panel is harder than it looks. You have to manage layouts, touch events, and CSS rules all at once.

Here are three technical lessons from my recent redesign of a visual-diff UI.

  1. Stop using window width for layouts

Do not use window.innerWidth to decide if your layout is vertical or horizontal. If a user resizes the window, your logic breaks.

Instead, use the actual CSS state. Use getComputedStyle to check the flex-direction. This reads the real value after all media queries apply. It ensures your drag logic matches what the user actually sees.

  1. Handle touch and mouse events together

To make dragging work on both desktop and mobile, you need a unified approach.

  • Use optional chaining to extract coordinates. This lets one function handle both mouse and touch events.
  • Use { passive: false } for touchmove. Browsers default touch events to passive to help scrolling. If you do not set this to false, you cannot call e.preventDefault(). Without that call, the page scrolls while you try to drag.
  • Attach move and end listeners to the document. If a user moves their finger too fast, they might leave the divider. Attaching to the document ensures the drag continues even if the pointer drifts.
  1. Avoid fighting your visibility system

I ran into a CSS specificity bug. I had one class to hide panels and another to set the layout direction.

The problem:

  • .view-panel { display: none; }
  • .diff-layout { display: flex; }

Because these had equal specificity, the last one in the file won. This meant my panels stayed visible even when they should have been hidden.

The fix: Never let a layout helper class set the display property. Let the visibility class own that.

Instead of: .diff-layout { display: flex; flex-direction: column; }

Use: .view-panel.diff-layout { flex-direction: column; }

This increases specificity and ensures the layout class only changes direction, not visibility.

Source: https://dev.to/bonzai2carn/under-the-hood-drag-touch-and-css-cascade-in-a-real-diff-ui-1b66