راهنمای طراحی
چگونه ranui را روی یک صفحهٔ واقعی به کار ببرید: نقش و وضعیت را انتخاب کنید و مقدارها را به توکنها بسپارید.
خودِ قواعد در دو جا آمدهاند و این صفحه بهجای تکرارشان به آنها پیوند میدهد:
راهنمای طراحی برای روشی که در هر محصولی کاربرد دارد، و
آداپتور پیادهسازی ranui
برای توکنها، سطحها و قواعد کامپوننتهای ranui. هر دو در node_modules/ranui/docs/DESIGN.md همراه بسته منتشر میشوند.
سیستم طراحی همهٔ توکنها و مقدارشان را فهرست میکند،
پوستهبندی بازنویسی در زمان اجرا را پوشش میدهد و
معماری اطلاعات ساختار صفحه را.
کجا به کار میآید: وقتی برای صفحهای ساختهشده با عناصر
<r-*>رنگ، فاصله، تایپوگرافی، عمق یا حرکت انتخاب میکنید.
اصول
- روشنی پیش از شخصیت. نخست باید کار اصلی و کنش اصلی بیابهام باشند.
- از کنترلهای موجود استفاده کنید.
r-button،r-input،r-selectوr-modalرفتار فرم، صفحهکلید و دسترسپذیری را از پیش دارند؛ ظاهرشان را تغییر دهید، نه اینکه از نو بسازیدشان. - با نقش و وضعیت تصمیم بگیرید. «این متن چیست؟» پاسخ دارد؛ «چه اندازهای خوب به نظر میرسد؟» ندارد. توکنِ آن نقش مقدار را تعیین میکند و آن مقدار از پوسته پیروی میکند.
- هر وضعیت دستیافتنی را طراحی کنید و نتیجه را ببینید. وضعیت پیشفرض یکی از هشت تاست، و سایهای که هیچکس نمیبیند فقط در مرورگر آشکار میشود.
اینها نقطهٔ شروعاند. اگر صفحه با کنار گذاشتن یکی از آنها بهتر میشود، کنارش بگذارید و دلیلش را بگویید.
انتخاب رنگ
نردبان از پیش تعیین کرده هاور و فعال چه شکلیاند؛ کار شما نامگذاری نقش است.
| این عنصر… | این را به کار ببرید |
|---|---|
| پسزمینه صفحه یا یک سطح | --ran-color-bg / -bg-subtle / -bg-elevated / -bg-muted |
| زیر نشانگر / در حال فشرده شدن | --ran-color-bg-hover / -bg-active |
| متن | --ran-color-text / -text-secondary / -text-disabled |
| یک کادر | --ran-color-border / -hover / -active |
| همان کنشی که صفحه برایش هست | --ran-color-primary (و روی آن --ran-color-primary-text) |
| یک وضعیت | --ran-color-success / -warning / -danger |
| یک پیوند | --ran-color-link |
هر رنگ تأکیدی فقط یک معنا دارد. رنگ اصلی تکرنگ است، پس آبی برای پیوندها و حلقهٔ فوکوس میماند؛ سبز یعنی موفقیت، کهربایی هشدار و قرمز خطر. اگر قرمز را برای تأکید به کار ببرید، بعداً رنگی برای گفتن «خطر» باقی نمیماند.
یک کد هگز خام، مقدار جایگزینی که با پوسته عوض نمیشود، یا جایگزینی که به توکنی ناموجود اشاره میکند،
در حالت تیره بیصدا خراب میشود یا کل اعلان را از کار میاندازد؛
قواعد رنگ آداپتور
هر کدام را توضیح میدهند و verify:design آنها را در کد منبع خودِ ranui پیدا میکند.
فاصله و ریتم
فاصلهها را از مقیاس ۴ پیکسلی بردارید و بگذارید خودِ فاصله معنا برساند:
- ۸ پیکسل میان عناصر درون یک گروه.
- ۱۶ پیکسل میان گروهها.
- ۲۴ تا ۳۲ پیکسل میان ناحیهها.
فاصلهٔ کمتر یعنی رابطهٔ نزدیکتر، پس یک فاصلهٔ بیرون از مقیاس کافی است تا ریتم بشکند. هر فاصله فقط یک مسئول داشته باشد: پیش از افزودن فاصلهٔ سوم میان دو عنصر، margin فرزند و padding والد را حساب کنید.
انتخاب تایپوگرافی
بپرسید متن چه نقشی دارد (عنوان، برچسب، بدنه، دکمه، تکعرض)؛ قلم، اندازه، وزن و ارتفاع خط از مقیاس تایپوگرافی درمیآیند. متنی که واقعاً یکباره است، مثل نمایش یک حرکت دست روی ویدیو، بهتر است توکن کامپوننتِ خودش را داشته باشد تا اینکه بهزور در نزدیکترین نقش جا داده شود.
عمق: سایه و چیدمان لایهها
سطح سایه را بر اساس چیستی عنصر انتخاب کنید: سطحی درون جریان صفحه، لایهای شناور یا دیالوگی که کار را متوقف میکند. لایهای که به سطح سایهٔ کارت برگردد، انگار به صفحه میخ شده است.
جاسازی لایههای ranui در قاب خودتان. نردبان z-index
از ۱۰۰۰ آغاز میشود، پس لایهای که پرتال شده خودش از قاب معمول صفحه بالاتر میرود. اما لایهای با position: fixed
که درون Shadow DOM خودش میماند (دیالوگ r-modal) تنها تا نزدیکترین زمینه چیدمانِ نیای خود
بیرون میزند. اگر محتوای جاسازیشده را در چیزی بپیچید که چنین زمینهای میسازد
(isolation، opacity < 1، transform، filter، will-change)، آن پوشش را فقط وقتی بالا ببرید که
لایهای واقعاً باز است:
.embed {
isolation: isolate; /* cheap: no z-index of its own, so nothing is promoted */
}
/* Escalate only while a real overlay is open — never "just in case" */
.embed:has(r-modal[open]),
.embed:has(r-modal[closing]) {
position: relative;
z-index: 100;
}یک z-index همیشگی روی پوشش، همهچیزِ درونش را، از جمله محتوای ایستا، در تمام مدت اسکرول بالای
سرصفحهٔ چسبان شما میبرد؛ این سایت یک بار همینطور منتشر شد. علاوه بر open با closing هم
تطبیق دهید: ماسک در طول گذار بسته شدن همچنان رسم میشود.
حرکت
بازخورد پرتکرار (هاور، فوکوس، فشردن) فوری است. وقتی حرکت تغییری را توضیح میدهد، بازخورد در
۰ تا ۱۰۰ میلیثانیه میماند، ورود ۲۵۰ تا ۴۰۰ میلیثانیه طول میکشد و کند میشود، و خروج ۱۵۰ تا ۲۰۰ میلیثانیه طول میکشد و تند میشود.
حرکت باید قابل قطع باشد و prefers-reduced-motion رعایت شود.
هرگز نگذارید ویژگیهای رنگ گذار کنند. CSS نمیداند رنگ چرا عوض شده، پس یک transition
روی background-color، color، border-color، box-shadow، fill یا stroke هنگام چرخش
پوسته هم شلیک میکند: صفحه دیگر عوض شده، اما هر عنصر با سرعت خودش محو میشود. بهجایش
transform و opacity را متحرک کنید. transition: all و یک transition: 0.2s لخت هم رنگ را شامل میشوند.
وضعیتها و متنها
هر وضعیت دستیافتنی بخشی از طراحی است: هاور، فعال، فوکوس، غیرفعال، در حال بارگذاری، خالی، خطا.
هاور به bg-hover / border-hover، فعال به bg-active و فوکوس به حلقهٔ فوکوس نگاشته میشود. چیزی که
کلیک نمیشود نباید کلیکشدنی به نظر برسد: r-card تنها با hoverable به هاور واکنش میدهد.
متن هم بخشی از سامانه است:
- دکمهها نتیجه را نام میبرند و اگر بافت مفعول را روشن نمیکند، مفعول را هم میآورند: «حذف عضو». دیالوگی که مفعولش روشن است میتواند «حذف» بگوید؛ از «تأیید» کلی پرهیز کنید.
- خطاها میگویند چه شد و سپس چگونه درستش کنیم. ✅ «ساخت شکست خورد: باندل از سقف حجم گذشته است. کوچکش کنید یا سقف را بالا ببرید.» ❌ «عملیات ناموفق بود، دوباره تلاش کنید.»
- تأییدها تغییر را بیان میکنند، نه موفقیت را، و فقط پس از قطعی شدن تغییر نمایش داده میشوند. ✅ «پروژه حذف شد» ❌ «عملیات موفق بود».
- بگذارید بافت، زیادیها را حذف کند: دیالوگی با عنوان «حذف پروژه» به دکمهای با نوشتهٔ «حذف کامل و همیشگی پروژه» نیاز ندارد.
دسترسپذیری
- کنتراست متن نسبت به پسزمینهاش را در حد WCAG AA برسانید.
- هرگز وضعیت را تنها با رنگ اعلام نکنید: آن را با آیکن، برچسب یا متن همراه کنید.
- هر عنصر تعاملی یک حلقه فوکوس دیدنی نگه میدارد (
--ran-focus-ring، یاoutline: 2px solid var(--ran-color-focus); outline-offset: 2px). - همهچیز با صفحهکلید دستیافتنی است.
- به
prefers-reduced-motionوprefers-color-schemeاحترام بگذارید.
ماوس و لمس، باریک و پهن
نه شیوه اشاره و نه اندازه قاب دید، هیچکدام هدف درجه دو نیستند.
- کشیدنها، لغزندهها و حرکتهای لمسی از Pointer Events استفاده میکنند، با
touch-action: noneدقیقاً روی سطح کشیدن.touch-action: noneبدون هیچ هندلر اشارهگری پشتش، کنترلی خراب است. - چیزی که فقط با هاور ظاهر میشود به جایگزین لمسی نیاز دارد.
trigger="hover"رویr-selectیاr-popoverدر دستگاههای لمسی به کلیک تبدیل میشود؛ هر چیزی که خودتان میسازید هم باید همینطور باشد. - اندازههای نسبی به viewport (
min(560px, calc(100vw - 32px))،clamp()) را به ساختن یک نقطهٔ شکست ترجیح دهید: ranui توکن نقطهٔ شکست ندارد، پس هر نقطهٔ شکست ثابت عددی است که کسی باید نگهداریاش کند. - هرگز تنها راه انجام کاری را در موبایل پنهان نکنید. بهجایش چیدمان را بازآرایی کنید.
- موقعیت اندازهگیریشده فقط تا بازچینش بعدی درست است. هر چیزی که از
getBoundingClientRect()به دست آمده با تغییر اندازهٔ پنجره، با بازچینش ظرف و، برای پنلی که پرتال شده، با اسکرول کهنه میشود. بارگذاری در عرض باریک، کوچک کردن تا آن عرض را نمیآزماید، و خرابی دقیقاً همانجاست.
آنچه کتابخانه ماشینی اجبار میکند
pnpm -F ranui verify:design نُه قاعده را در کد منبع خودِ ranui بررسی میکند: جایگزینهای رنگی که با پوسته
عوض نمیشوند، لیترالهای خام رنگ، مقیاسهای فاصله و اندازه، کشیدنهای فقط با ماوس، قواعد :host که
hidden را از کار میاندازند، جایگزینهایی که به توکنهای اعلامنشده اشاره میکنند، کامپوننتهایی که درخت shadow خودشان را میگردند، و درختهای shadow
که بیرون از سازنده ساخته میشوند. خطی که عمداً قاعدهای را میشکند این را با
design-ok: <rule> <reason> اعلام میکند. این بررسیها فقط ریشههای منبعِ پیکربندیشده را پوشش میدهند؛ برنامهای که
از ranui استفاده میکند بررسیهای خودش را اجرا میکند و صفحههای خودش را میبیند.
نمونههای طراحی
این نمودارها از توکنهای پایهٔ ranui ساخته شدهاند و مؤلفهٔ واقعی نیستند.
ردیفها را همتراز نگه دارید
وقتی محتوایی به یک ردیف اضافه میشود، ابتدای متن و ستون عملیات را با ردیفهای دیگر همتراز نگه دارید.
گوشههای تودرتو را هماهنگ کنید
اگر هر دو مرز داخلی و بیرونی لازماند، فاصلهٔ داخلی را از شعاع بیرونی کم کنید: ۱۶ − ۴ = ۱۲. منحنیها هممرکز میشوند و فاصلهای یکنواخت دارند.
--ran-radius-lg − --ran-space-1 = --ran-radius-mdکلیک روی نمادهای کوچک را آسان کنید
اندازهٔ نماد ۱۶ پیکسل است و ناحیهٔ کلیک آن تا ۳۲ پیکسل گسترش مییابد تا استفاده آسانتر شود. اندازه را متناسب با ماوس یا لمس انتخاب کنید و بین ناحیههای مجاور فاصله بگذارید.
--ran-size-1 · --ran-size-7شواهد و پذیرش
بخش وارسی یک تغییر در راهنما میگوید در یک مرورگر واقعی چه چیزی را بررسی کنید و چه گزارش دهید: آنچه مشاهده کردید، آنچه فقط استنباط کردید و آنچه نتوانستید بررسی کنید. بازبینی یک عامل، پذیرش کاربر نیست.