نگاهی به جزئیات فنی: Drag، Touch و Cascade در CSS

ساخت یک پنل UI تغییراندازه پذیر (resizable) سخت‌تر از آن چیزی است که به نظر می‌رسد. شما باید چیدمان‌ها (layouts)، رویدادهای لمسی (touch events) و قوانین CSS را هم‌زمان مدیریت کنید.

در اینجا سه درس فنی از بازطراحی اخیر من در یک رابط کاربری visual-diff آورده شده است.

۱. از استفاده از عرض پنجره برای چیدمان‌ها خودداری کنید

برای تصمیم‌گیری در مورد اینکه چیدمان شما عمودی است یا افقی، از window.innerWidth استفاده نکنید. اگر کاربر اندازه پنجره را تغییر دهد، منطق شما از کار می‌افتد.

در عوض، از وضعیت واقعی CSS استفاده کنید. از getComputedStyle برای بررسی flex-direction استفاده کنید. این کار مقدار واقعی را پس از اعمال تمام media queryها می‌خواند و تضمین می‌کند که منطق کشیدن (drag) شما با آنچه کاربر واقعاً می‌بیند مطابقت دارد.

۲. رویدادهای لمسی و ماوس را با هم مدیریت کنید

برای اینکه قابلیت کشیدن (dragging) هم در دسکتاپ و هم در موبایل کار کند، به یک رویکرد یکپارچه نیاز دارید.

  • از optional chaining برای استخراج مختصات استفاده کنید. این کار اجازه می‌دهد یک تابع هم رویدادهای ماوس و هم رویدادهای لمسی را مدیریت کند.
  • برای touchmove از { passive: false } استفاده کنید. مرورگرها رویدادهای لمسی را به صورت پیش‌فرض passive تنظیم می‌کنند تا به اسکرول کردن کمک کنند. اگر این را روی false تنظیم نکنید، نمی‌توانید e.preventDefault() را فراخوانی کنید. بدون این فراخوانی، در حالی که سعی می‌کنید چیزی را بکشید، صفحه اسکرول می‌شود.
  • شنونده‌های (listeners) move و end را به document متصل کنید. اگر کاربر انگشت خود را خیلی سریع حرکت دهد، ممکن است از جداکننده (divider) خارج شود. متصل کردن به document تضمین می‌کند که حتی اگر نشانگر (pointer) از مسیر خارج شد، عملیات کشیدن ادامه یابد.

۳. از درگیری با سیستم نمایش (visibility) خودداری کنید

من با یک باگ مربوط به اولویت (specificity) در CSS مواجه شدم. من یک کلاس برای مخفی کردن پنل‌ها و کلاس دیگری برای تعیین جهت چیدمان داشتم.

مشکل:

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

از آنجایی که این‌ها اولویت (specificity) یکسانی داشتند، آخرین مورد در فایل برنده شد. این یعنی پنل‌های من حتی زمانی که باید مخفی می‌شدند، نمایش داده می‌شدند.

راه حل: هرگز اجازه ندهید یک کلاس کمکی چیدمان (layout helper class)، ویژگی display را تنظیم کند. اجازه دهید کلاس مربوط به نمایش (visibility class)، مسئول این کار باشد.

به جای: .diff-layout { display: flex; flex-direction: column; }

استفاده کنید از: .view-panel.diff-layout { flex-direction: column; }

این کار اولویت (specificity) را افزایش می‌دهد و تضمین می‌کند که کلاس چیدمان فقط جهت را تغییر می‌دهد، نه وضعیت نمایش را.

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