طراحی وب

طراحی Modal و Dialog با UX صحیح

انتخاب آگاهانه Dialog و جایگزین‌ها، عنوان و اقدام دقیق، مسیر focus و Escape؛ نمونه مستقل dialog با حذف و بازگردانی نمایشی.

1404/12/11 3 دقیقه مطالعه 669 بازدید

کاربر روی حذف یک پیش‌نویس کلیک می‌کند و پنجره‌ای باز می‌شود: «مطمئن هستید؟» دو دکمه «بله» و «خیر» دیده می‌شود، اما نام پیش‌نویس و پیامد حذف مشخص نیست. وجود یک مرحله تأیید به‌تنهایی از اشتباه جلوگیری نمی‌کند. Dialog باید اطلاعات لازم برای تصمیم را ارائه دهد و مسیر تأیید یا انصراف را روشن نگه دارد. شکل شناور آن تنها بخشی از این قرارداد است.

Modal معمولاً تعامل با زمینه را تا زمان بسته شدن محدود می‌کند. این وقفه هزینه دارد: مخاطب از کار فعلی جدا می‌شود و باید در محیط تازه تصمیم بگیرد. برای برخی کارها این تمرکز مفید است؛ برای هر اعلان یا فرم کوتاه لازم نیست. انتخاب باید از نیاز عمل، میزان اطلاعات و رابطه آن با صفحه فعلی بیاید، نه از اینکه یک مؤلفه آماده در کتابخانه وجود دارد.

Modal و Dialog یک معنی کامل ندارند

Dialog به ناحیه‌ای برای تعامل یا ارائه محتوا اشاره دارد؛ حالت modal مشخص می‌کند آیا کار با زمینه محدود شده است. یک پنجره شناور می‌تواند غیرmodal باشد. وقتی چنین ناحیه‌ای فقط ظاهر modal دارد ولی صفحه‌کلید همچنان به زمینه می‌رود، تجربه متناقض می‌شود. نقش برنامه‌ای، رفتار واقعی و ظاهر باید با هم هماهنگ باشند. افزودن aria-modal به تنهایی تعامل زمینه را متوقف نمی‌کند.

Drawer و Bottom Sheet نیز همیشه جایگزین غیرmodal نیستند. ممکن است همان محدودیت زمینه را با شکل دیگری ایجاد کنند. تغییر محل پنجره از مرکز به کناره، مسئولیت مدیریت focus و بستن را حذف نمی‌کند. مقایسه گزینه‌ها باید بر اساس رفتار باشد: آیا مخاطب همزمان به زمینه نیاز دارد، آیا محتوا طولانی است و آیا بازگشت به کار قبلی مسیر روشن دارد؟

از هدف و پیامد عمل شروع کنید

برای حذف برگشت‌ناپذیر، نام مورد و پیامد عمل را مشخص کنید. برای تغییر ساده و قابل بازگرداندن، شاید Undo مناسب‌تر از تأیید پیش از عمل باشد. برای فرم طولانی، صفحه مستقل می‌تواند فضا و امکان بازگشت بهتری داشته باشد. برای توضیح کوتاه نزدیک یک فیلد، نمایش inline ممکن است ارتباط محتوا را حفظ کند. هیچ‌کدام برای همه موقعیت‌ها برتری ثابت ندارند.

اطلاعات هم گاهی می‌توانند در Dialog قرار بگیرند؛ منع مطلق «Modal فقط برای اقدامات مهم است» دقیق نیست. با این حال، خبر عمومی که نیازی به تصمیم ندارد معمولاً نباید کار را قطع کند. درباره انتخاب پیام وضعیت، راهنمای طراحی اعلان به تفکیک خبر و اقدام کمک می‌کند. هر وقفه باید دلیل قابل توضیحی در جریان کار داشته باشد.

عنوان، توضیح و دکمه‌ها باید یک عمل را بیان کنند

عنوان «حذف پیش‌نویس جلسه» و دکمه «حذف پیش‌نویس» از عبارت عمومی «تأیید» روشن‌ترند. توضیح باید پیامد اصلی را بدون بزرگ‌نمایی یا تهدید بیان کند. اگر حذف فقط از دستگاه فعلی است، آن را با حذف کامل حساب مخلوط نکنید. عنوان نباید وعده‌ای بدهد که متن یا رفتار دکمه نقض می‌کند. فرد باید با یک نگاه بداند چه تصمیمی از او خواسته شده است.

عمل اصلی و انصراف باید از نظر نام و ظاهر قابل تشخیص باشند. برای عملیات حساس، focus اولیه روی گزینه کم‌خطر می‌تواند مناسب باشد. ترتیب دکمه‌ها را در محصول ثابت و با جهت زبان هماهنگ نگه دارید. استفاده از رنگ هشدار، جای متن دقیق را نمی‌گیرد. دکمه بستن هم باید نام قابل دسترس داشته باشد؛ یک علامت ضربدر بدون توضیح برنامه‌ای کافی نیست.

نمونه کامل با عنصر dialog

فایل زیر را با نام dialog.html و encoding برابر UTF-8 ذخیره و در مرورگری که dialog و showModal را پشتیبانی می‌کند باز کنید. CSS و JavaScript داخل همان فایل‌اند و تصویر، API یا بسته خارجی ندارد. عملیات فقط یک پیش‌نویس نمایشی را در همین صفحه حذف می‌کند؛ هیچ درخواست شبکه‌ای یا حذف پایدار داده انجام نمی‌شود. با بارگذاری دوباره فایل، نمونه به حالت اولیه برمی‌گردد.

<!doctype html>
<html lang="fa" dir="rtl"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>تأیید حذف پیش‌نویس</title>
<style>body{font-family:Tahoma,Arial,sans-serif;line-height:1.9;margin:0;background:#f2f4f7;color:#17243b}main{max-width:40rem;margin:auto;padding:2rem 1rem}article{padding:1rem;border:1px solid #a6b1c2;background:white}button{font:inherit;padding:.65rem 1rem;margin:.3rem;border:1px solid #6b7890;border-radius:.4rem;background:white;color:#17243b;cursor:pointer}.danger{background:#9f2424;color:white}dialog{box-sizing:border-box;width:min(30rem,calc(100% - 2rem));max-height:calc(100vh - 2rem);overflow:auto;border:1px solid #8290a5;border-radius:.65rem;padding:1.5rem;color:#17243b}dialog::backdrop{background:rgb(15 23 42 / .6)}:focus-visible{outline:3px solid #946000;outline-offset:3px}[hidden]{display:none!important}</style></head>
<body><main><h1>پیش‌نویس‌ها</h1><article id="draft"><h2>یادداشت جلسه</h2><p>این پیش‌نویس فقط محتوای نمایشی همین فایل است.</p><button id="open-dialog" type="button">حذف پیش‌نویس</button></article><button id="restore" type="button" hidden>بازگرداندن نمونه</button><p id="status" role="status" aria-atomic="true"></p></main>
<dialog id="confirmation" aria-labelledby="dialog-title" aria-describedby="dialog-description"><h2 id="dialog-title">حذف پیش‌نویس یادداشت جلسه؟</h2><p id="dialog-description">پیش‌نویس از این نمایش حذف می‌شود. فایل یا اطلاعاتی روی سرور تغییر نمی‌کند.</p><button id="cancel" type="button" autofocus>انصراف</button><button id="confirm" class="danger" type="button">حذف پیش‌نویس</button></dialog>
<script>
const dialog=document.getElementById('confirmation');const opener=document.getElementById('open-dialog');const draft=document.getElementById('draft');const restore=document.getElementById('restore');const cancel=document.getElementById('cancel');const status=document.getElementById('status');
opener.addEventListener('click',()=>{dialog.returnValue='';dialog.showModal();cancel.focus();});
cancel.addEventListener('click',()=>dialog.close('cancel'));
document.getElementById('confirm').addEventListener('click',()=>dialog.close('confirmed'));
dialog.addEventListener('close',()=>{if(dialog.returnValue==='confirmed'){draft.hidden=true;restore.hidden=false;status.textContent='پیش‌نویس نمایشی حذف شد.';restore.focus();}else{opener.focus();}});
restore.addEventListener('click',()=>{draft.hidden=false;restore.hidden=true;status.textContent='نمونه بازگردانده شد.';opener.focus();});
</script></body></html>

پیش‌نویس در یک article قرار دارد و دکمه حذف پنجره را باز می‌کند. dialog با عنوان قابل مشاهده نام‌گذاری شده و توضیح کوتاه آن از طریق aria-describedby مرتبط است. در شروع، focus به دکمه انصراف می‌رود. تأیید، فقط محتوای نمایشی را پنهان می‌کند؛ پس از حذف، focus به دکمه بازگرداندن نمونه می‌رود، چون کنترل آغازکننده دیگر دیده نمی‌شود.

focus بخشی از مسیر کار است

الگوی Modal Dialog در W3C درباره focus داخل پنجره، حرکت با Tab، Escape و بازگشت به مسیر منطقی توضیح می‌دهد. در فرم کوتاه، یک ورودی می‌تواند مقصد اولیه باشد؛ در محتوای بلند، آغاز متن ممکن است مناسب‌تر باشد. انتخاب focus باید کمک کند فرد زمینه تصمیم را بفهمد و ابتدای محتوا از دید خارج نشود.

پس از بستن، مقصد focus را بر اساس جریان کار تعیین کنید. وقتی عمل فقط لغو شده، کنترل آغازکننده معمولاً مقصد منطقی است. وقتی همان کنترل حذف شده، یک گزینه بعدی یا عنوان بخش می‌تواند مناسب باشد. رها شدن focus روی عنصر ناموجود یا ابتدای نامرتبط صفحه، ادامه کار را دشوار می‌کند. تصمیم بازگشت را همراه نتیجه هر دکمه در مشخصات مؤلفه بنویسید.

رفتار native را با ظاهر سفارشی اشتباه نگیرید

مرجع dialog در MDN تفاوت باز کردن modal با showModal و نمایش غیرmodal را شرح می‌دهد. در نمونه، از رفتار native برای محدود کردن زمینه استفاده شده است و یک focus trap دستی جدا نوشته نشده است. عنصر HTML مسئولیت طراحی نام، محتوا و جریان نتیجه را از توسعه‌دهنده نمی‌گیرد. سیاست سازگاری پروژه نیز باید برای محیط هدف مشخص باشد.

در ساخت Dialog سفارشی، قرار دادن یک div روی صفحه کافی نیست. جلوگیری از تعامل زمینه، ترتیب Tab، نام پنجره و مسیر خروج نیاز به پیاده‌سازی دارند. تکرار ناقص رفتار native می‌تواند در شرایط مختلف مشکل بسازد. اگر کتابخانه‌ای این مسئولیت‌ها را فراهم می‌کند، قرارداد استفاده و نسخه آن را بشناسید. ظاهر مؤلفه دلیل کافی برای فرض دسترس‌پذیری کامل آن نیست.

بستن با کلیک بیرون یک انتخاب است

برای پنجره توضیح کوتاه، بستن با انتخاب زمینه ممکن است مناسب باشد. برای فرم با داده واردشده، همان رفتار می‌تواند اطلاعات را از دسترس خارج کند. قانون عمومی «همه Modalها با کلیک بیرون بسته شوند» کافی نیست. رفتار را بر اساس خطر از دست رفتن کار و انتظار مخاطب انتخاب کنید. دکمه آشکار بستن یا انصراف باید مستقل از شناخت gesture وجود داشته باشد.

نمونه این مقاله برای کلیک بیرون رفتار سفارشی ندارد و Escape یا دکمه انصراف مسیر خروج‌اند. اگر بعداً خروج با زمینه اضافه می‌کنید، کلیک داخل محتوا نباید به اشتباه پنجره را ببندد. برای داده ویرایش‌شده، سیاست حفظ پیش‌نویس یا تأیید خروج را روشن کنید. پنهان شدن پنجره با پاک شدن داده یکی نیست و نتیجه هرکدام باید قابل پیش‌بینی باشد.

فرم و عملیات شبکه‌ای حالت‌های بیشتری دارند

در محصول واقعی، تأیید ممکن است یک درخواست شبکه‌ای آغاز کند. تا مشخص شدن نتیجه، متن دکمه و حالت انتظار باید روشن باشند و ارسال تکراری کنترل شود. خطا را داخل همان مسیر نمایش دهید و داده واردشده را حفظ کنید. بستن پنجره به محض شروع درخواست، اگر نتیجه هنوز معلوم نیست، می‌تواند کاربر را از وضعیت عمل بی‌خبر کند. موفقیت فقط پس از تأیید مربوط اعلام شود.

اگر کار طولانی است، نگه داشتن مخاطب در یک پنجره اجباری شاید مناسب نباشد. امکان ادامه در زمینه همراه با وضعیت پایدار می‌تواند انتخاب دیگری باشد. این تصمیم به ماهیت کار وابسته است؛ بعضی عملیات نیاز به حفظ تمرکز دارند. حالت شکست جزئی نیز باید توضیح داده شود، به‌ویژه اگر بخشی از داده تغییر کرده و بخش دیگر نیاز به اصلاح دارد. عبارت کلی «خطا» برای ادامه کار کافی نیست.

محتوای بلند و صفحه کوچک

پنجره باید در فضای باریک و با متن بزرگ‌تر قابل خواندن بماند. ارتفاع ثابت و پنهان کردن overflow می‌تواند دکمه‌ها یا توضیح لازم را حذف کند. در نمونه، ارتفاع حداکثری و اسکرول وجود دارد و عرض با فضای صفحه محدود می‌شود. برای فرم طولانی، رفتار صفحه‌کلید نرم‌افزاری و محل کنترل‌های پایان کار را در طراحی لحاظ کنید. اگر محتوا پیچیده است، صفحه مستقل را دوباره بررسی کنید.

پنجره‌های تو در تو بار شناختی و مدیریت بازگشت را بیشتر می‌کنند. پیش از افزودن پنجره دوم، ببینید آیا می‌توان همان ناحیه را به مرحله بعد برد یا جزئیات را در خود آن باز کرد. ارتباط میان مراحل باید روشن بماند. برای انتخاب‌های مرتبط با فرم، راهنمای جستجو و فیلتر نمونه‌ای از کنترل‌های ساده‌تر در جریان طبیعی صفحه ارائه می‌کند.

در تحویل، هدف پنجره، محتوای عنوان، focus اولیه، مسیر خروج و نتیجه تأیید را ثبت کنید. برای حالت لغو، موفقیت، خطا و حذف کنترل آغازکننده رفتار مشخص داشته باشید. Modal مناسب وقفه‌ای قابل فهم ایجاد می‌کند و پس از تصمیم، فرد را به جای منطقی کار برمی‌گرداند. این کیفیت از هماهنگی رفتار و محتوا می‌آید، نه فقط از سایه، گوشه گرد و انیمیشن ورود.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!