ویرگول
ورودثبت نام
Amirhosein Imeni
Amirhosein Imeni
Amirhosein Imeni
Amirhosein Imeni
خواندن ۹ دقیقه·۲ ماه پیش

توکن‌ها در دیزاین سیستم: نبرد بین توکن های «وضعیت پذیر» (Stateful) و «ترکیب‌ پذیر» (Composable)

اون لحظه‌ رو می‌تونی تصور کنی که سه ماه از عمر دیزاین سیستمت می‌گذره و می‌بینی که تعداد توکن های رنگ معنادارت (Semantic Token) به عدد ۳۴۷ رسیده؟ یه ذره ترسناکه و البته ۲۰۰ تای اون‌ها فقط برای وضعیت های هاور (Hover States) و فشرده (Pressed States) هستن.

فکر کنم همه‌ی متخصص‌های دیزاین سیستم این تجربه رو داشتیم.

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

این نبرد از اینجا شروع میشه: یک دکمه، چندین وضعیت

یک دکمه وضعیت های مختلفی داره که هر وضعیت به یک رنگ یکتا برای تمایز نیاز داره
یک دکمه وضعیت های مختلفی داره که هر وضعیت به یک رنگ یکتا برای تمایز نیاز داره

تصور کن داری کامپوننت دکمه رو طراحی می‌کنی. از دور به نظر ساده میاد، اما اشتباه نکن!
اون دکمه باید تمام وضعیت‌های کلیدی دکمه رو داشته باشه؛ وضعیت هاور (Hover State)، وضعیت فشرده (Pressed State)، وضعیت متمرکز (Focus State) و وضعیت غیرفعال (Disabled). همین‌جا کافی نیست، وضعیت در حال بارگذاری (Loading State) رو هم باید اضافه کنیم!
یه لحظه به خودت میای و می‌بینی فقط برای یک حالت «دکمه» باید ۵ تا واریانت از یک توکنت طراحی کنی؛ تازه هنوز پای دارک مود هم وسط نیومده.
خب اینجاست که مسیرها جدا میشن:


مسیر ۱: «همه توکن ها رو معنادار نامگذاری کن»

بعضی تیم‌های طراحی وقتی با این چالش روبرو می‌شن تیم لیدشون میگه: "برای هر توکن رنگی، یک اسم معنادار بذاریم"

پس در نهایت توی کالکشن توکن‌های معنادار‌تون به همچین توکن هایی می‌رسین:

bg-primary-hover bg-primary-pressed bg-primary-disabled bg-primary-focus text-error-hover border-success-disabled ...

... و ۱۹۴ تای دیگه.

من این استراتژی رو توکن های وضعیت پذیر (Stateful Tokens) نامگذاری می‌کنم (تو دیزاین سیستم ها بیشتر بهش Semantic Tokens یا Decision Tokens میگن).

چرا تیم‌های طراحی و فنی اول مسیر عاشقشن؟

  • به طرز احمقانه‌ای واضحه. وقتی یکی از اعضای تیم طراحی تون تو فیگما توکن bg-primary-hover رو می‌بینه، دقیقاً می‌دونه که چه کاری انجام میده. نه نیازه به صورت انتزاعی تو ذهنش تصورش کنه و نه شیرجه بزنه تو داکیومنت‌ها و تند تند دنبال این بگرده که: "صبر کن ببینم یادم رفت چطور وضعیت هاور رو مدیریت می‌کردیم؟"

  • وقتی دولوپر فرانت-اندتون CSS می‌نویسه، این توکن ها به صورت ۱:۱ مپ می‌شه:

css button { background: var(--bg-primary); } button:hover { background: var(--bg-primary-hover); }
  • اگه عضو جدیدی به تیمت اضافه شد در عرض چند دقیقه با خوندن داکیومنت توکن‌ها آنبورد می‌شه. تست QA ساده است و مثل هلو هندآف می‌کنی.

  • خروجی گرفتن ازش ساده‌ست فقط کافیه با استفاده از پلاگین ها فیگما توکن‌ها رو تو فرمت JSON خروجی بگیری و به دولوپرت بدی تا اون سریعا سورس کدش رو بروزرسانی کنه.


Untitled UI ، Atlassian Design System و Adobe Spectrum سه نمونه از دیزاین سیستم های بزرگ دنیا هستن که از این رویکرد استفاده میکنن.

چرا تیم‌های طراحی و فنی در نهایت ازش متنفر می‌شن؟

  • یه دفعه مدیر محصول‌تون وارد اتاق تون می‌شه و می‌گه: "ما تا کوارتر بعدی به دارک مود نیاز داریم" و بعد دلتون هُری می‌ریزه. حالا هر کدوم از اون ۲۰۰ تا توکن به یک نسخه دارک مود نیاز دارن. به این صورت که:

bg-primary-hover → bg-primary-hover-dark bg-primary-pressed → bg-primary-pressed-dark bg-primary-disabled → bg-primary-disabled-dark

به همین راحتی تعداد توکن‌های شما ۲ برابر میشه. و یا وقتی نیاز دارین که رفتار هاور رو در کل سیستم تغییر بدین؟ باید ۴۷ توکن مختلف رو دستکاری کنین.

  • بعد از مدیر محصول حالا مدیر تیم مارکتینگ میاد تو اتاقت و میگه: "هی، ما یک برند جدید داریم، آماده ای کاراشو بکنی و بلاه بلاه"

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

bg-primary-hover-dark-brand-x

من خوبم :)
من خوبم :)

مسیر ۲: «رنگ پایه + لایه کنترل کنتراست»

بعضی از تیم‌های طراحی وقتی به این مشکل میخورن این ایده به ذهن تیم لیدشون می‌رسه و میگه: "چی میشه اگه اصلاً اسم وضعیت‌ها رو، روی توکن هامون نذاریم؟"

تو این حالت شما به این توکن‌ها نیاز دارید:

  • یک توکن رنگ پایه (Base Color): bg-primary

  • یک توکن رنگ آلفا چنل با درصد روشنایی یا تیرگی متغیر (State Layer Color): state-hover (مثلا یک Overlay سفید ۸ درصدی)

توی این استراتژی وقتی به وضعیت هاور یک کامپوننت نیاز دارین، این توکن ها رو به صورت لایه ای با هم ترکیب می‌کنین:

bg-primary + state-hover-08 = ظاهر وضعیت هاور

من این استراتژی رو توکن های ترکیب پذیر (Compsoable Tokens) نامگذاری می‌کنم (تو دیزاین سیستم ها بیشتر بهش Layered Tokens یا Primitive + Modifier میگن).

چرا تیم‌های طراحی در نهایت عاشقش میشن؟

  • به طرز دیوانه‌واری مقیاس پذیره.

  • فقط توکن های پایه رو می‌سازید به جای ساختن ۲۰۰ تا واریانت از وضعیت های مختلف اون‌ها.

  • وقتی دارک‌ مود رو اضافه می‌کنین، صرفا توکن های رنگ پایه‌تون رو عوض می‌کنین و توکن های آلفا چنل شما به درستی کار می‌کنن.

  • به یک برند جدید نیاز دارین؟ یک مود جدید اضافه کنید رنگ‌های پایه رو تغییر بدین. منطق Hover/Pressed/Disabled دقیقاً همون‌طور می‌مونه و کار میکنه.

  • توکن های وضعیت (State Layer Tokens) شما در یک لایه جدا زندگی می‌کنن و مدیریت و نگه‌داریشون نظم بیشتری داره:

JSON { "state": { "hover": { "opacity": 0.08}, "pressed": { "opacity": 0.12}, "disabled": { "opacity": 0.38} } }

Material Design 3 گوگل و ShadCN دو تا از دیزاین سیستم های بزرگ دنیا هستن که از این رویکرد استفاده میکنن. هر سیستم چندتمی (Multi-Theme) بالغی که دیدم در نهایت به اینجا می‌رسه.

چرا تیم‌های طراحی در ابتدا باهاش مشکل دارن؟

  • قضیه اینه: از نظر مفهومی سخت‌تره و موارد استفاده‌ش (Use Cases) تو نگاه اول مشخص نیست.

  • وقتی یک دولوپر جدید این رو تو کد می‌بینه:

CSS button::after { content: ""; background: white; opacity: var(--state-hover); }

ممکنه یک دقیقه بهش خیره بشن. "صبر کنین، ما داریم از Pseudo-Elements (انتخاب‌گری در CSS برای استایل دهی به یک بخش خاص یک المنت) برای وضعیت‌ها استفاده می‌کنیم؟"

  • مدل ذهنی‌ش انتزاعی‌تره. نسبت به توکن های وضعیت‌پذیر به داکیومنت جامع‌تری نیاز داره. نیاز به بیان Use Case ها دارین. حتی باید توضیح بدین که چرا دارین لایه‌بندی (Layering) می‌کنین.

  • مشکل دسترس پذیری بوجود میاره که در ظاهر پنهانه و هیچ‌کس به شما هشدار نمی‌ده: توکن های آلفا چنل (State Layer Tokens) می‌تونن کنتراست رو از بین ببرن. مثلا اگه رنگ پایه برند جدید شما از قبلی روشن‌تر باشه، اضافه کردن یک Overlay سفید ۸ درصدی ممکنه شما رو به زیر آستانه غیر قابل قبول کنتراست چک برسونه یعنی نسبت کنتراست ۴.۵:۱ نقض بشه.

  • شما باید هر ترکیب جدید رو همیشه تست کنین.


نه اینوری نه اونوری: «توکن‌های هیبریدی»

ترکیبی پررو باشه :))
ترکیبی پررو باشه :))

لازم نیست صفر و یک فکر کنیم و حتما یکی از بین این دوتا رو انتخاب کنیم.

بسیاری از سیستم‌های بالغ از چیزی استفاده می‌کنن که من بهش می‌گم «توکن‌های هیبریدی» — اون‌ها هم توکن های وضعیت پذیر مثل bg-primary-hover دارن و هم توکن های آلفاچنل یا همون ترکیب پذیر (State Layer Tokens). برای یک سری از المان های اصلی شون از توکن وضعیت پذیر استفاده می‌کنن و توی باقی المان ها دست طراح رو برای کار با توکن های آلفاچنل باز میذارن. مزیت استفاده از این روش این هست که دقیقا میتونی بر اساس نیاز محصولت کالکشن توکن های معنادار (Semantic Tokens) رو تعریف کنی و زیاده روی نکنی و باقی موارد رو با استفاده از استفاده از توکن های آلفاچنل (State Layer Tokens) و داکیومنت کردن مدیریت کنی.

من این استراتژی رو توکن های هیبریدی (Hybrid Tokens) نامگذاری می‌کنم. این روش بیشتر وقتی قصد داشته باشین دیزاین سیستم یک سازمان رو بهینه تر کنیم بیشتر کاربرد داره یا وقتی چندتا دیزاین سیستم رو محصولات مختلف سازمان استفاده شده و شما بخواین یک دیزاین سیستم واحد انعطاف پذیر بسازید.


نمونه استفاده از این روش رو می‌تونیم توی دیزاین سیستم Untitled UI ببینیم. هرچند خودش تمام توکن هاش رو وضعیت پذیر تعریف کرده ولی اگه قصد داشته باشید کامپوننت جدیدی جدا از کتابخانه خودش طراحی کنید می‌تونید از توکن های آلفاچنل (State Layer Tokens) استفاده کنید بدون اینکه نیاز به توکن وضعیت پذیر جدیدی داشته باشید.


اوکی، حالا کدوم رو باید انتخاب کنم؟

من دیزاین سیستم‌ها رو به هر سه روش به ددلاین رسوندم. این چارچوب تصمیم‌گیری صادقانه منه:

وضعیت پذیر رو انتخاب کنین اگه:

  • تیم شما کمتر از ۱۰ نفره.

  • شما از یک برند پشتیبانی می‌کنین و هنوز برنامه چندتمی (Multi-Theme) ندارین.

  • باید تو ۲-۳ ماه آینده محصول رو لانچ کنین.

  • این اولین تجربه کاری دیزاین سیستم شماست.

  • تیم شما به وضوح (Clarity) بیشتر از انعطاف‌پذیری (Flexibility) نیاز داره.

تجربه شخصی: بیش از حد به سمت بیش-مهندسی (Over-Engineer) نرید. اگه توکن‌های معنادار شما رو به ددلاین می‌رسونن و همه می‌فهمنش، این یه بُرده. همیشه می‌تونین بعداً استراتژی‌تون رو تغییر بدین.

ترکیب پذیر رو انتخاب کنین اگه:

  • از ۲+ برند یا تم (Theme) پشتیبانی می‌کنین.

  • دارک مود تو رودمپ هست و تو این مسیر سرعت براتون اهمیت داره.

  • برای نگهداری طولانی‌مدت (۲+ سال) می‌سازین.

  • تیم شما تجربه کار روی دیزاین سیستم داره.

  • توکن‌های کمتر و قابلیت تم پذیری قوی‌تری نیاز دارین.

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

هیبریدی رو انتخاب کنین اگه:

  • تو یک سازمان بزرگ روی محصولات مختلف و با تیم های طراحی و توسعه در سطوح متفاوت بلوغ کار می‌کنید.

  • وضوح توکن‌ها رو می‌خواین اما انعطاف‌پذیری قوانین رو هم لازم دارین.

  • دارین از وضعیت پذیر به ترکیب پذیر به مرور زمان مهاجرت می‌کنین.

  • می‌خواین آینده‌نگری کنین بدون اینکه تیم فعلی‌تون رو گیج کنین.

تجربه واقعی: این همون چیزیه که اکثر سیستم‌های بالغ بهش تبدیل می‌شن. عملگراست و کار می‌کنه.


بررسی واقعیت تو محیط کد:

بذارین نشونتون بدم که این تو محیط پروداکشن واقعاً چه شکلیه.

توکن‌های وضعیت پذیر (JSON + CSS):

JSON "color": { "bg": { "primary": { "value": "#0057FF"}, "primary-hover": { "value": "#004AE0" }, "primary-pressed": { "value": "#003EC4"}, "primary-disabled": { "value": "#99B7FF" } } }
CSS button { background: var(--bg-primary); } button:hover { background: var(--bg-primary-hover); } button:disabled { background: var(--bg-primary-disabled); }

ساده‌ست، واضحه و دیباگ کردنش آسونه.

توکن‌های ترکیب پذیر (JSON + CSS):

JSON { "color": { "bg": { "primary": { "value": "#0057FF" } }, "state": { "hover": { "opacity": 0.08}, "pressed": { "opacity": 0.12}, "disabled": { "opacity": 0.38} } } }
CSS :root { --bg-primary: #0057FF; --state-hover: 0.08; } button { position: relative; background: var(--bg-primary); } button::after { content: ""; position: absolute; inset: 0; background: white; opacity: 0; transition: opacity 0.2s; pointer-events: none; } button:hover::after { opacity: var(--state-hover); }

پیچیده‌تره، قدرتمندتره و نیاز به درک شدن داره.

پس:

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

  • اگه دارین برای مقیاس پذیری، چند برندی، یا نگهداری طولانی‌مدت دیزاین سیستم طراحی می‌کنین: از روز اول ترکیب پذیر پیش برین. بله، راه اندازیش سخت‌تره. به داکیومنت‌های بیشتری نیاز دارین. اما یک سال دیگه تو دریای واریانت‌های مختلف توکن‌هاتون غرق نمی‌شین.

  • و اگه تو یه سازمان بزرگ هستین یا دارین دیزاین سیستم موجود رو به یک دیزاین سیستم بهینه‌تر تبدیل می‌کنین: روش هیبرید دوست شماست.


چیزی که هیچ‌کس به شما نمی‌گه

این چیزیه که آرزو می‌کردم وقتی داشتم اولین سیستمم رو طراحی می‌کردم، کسی بهم می‌گفت:

درک کردن توکن‌های دیزاین سیستم‌تون توسط دیزاینرهای تیم تون، بیشتر از کمال‌گرایی روی معماری اون اهمیت داره

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

دیزاین سیستمرابط کاربریطراحی محصولتجربه کاربریتفکر طراحی
۹
۱
Amirhosein Imeni
Amirhosein Imeni
شاید از این پست‌ها خوشتان بیاید