نمای کلی بنیادی از نحوه ایجاد آرایش رنگها پویا و قابلپیکربندی
در این پست میخواهم ایدههایی را درباره روشهای مدیریت آرایش رنگهای چندگانه در CSS همرسانی کنم. نسخه نمایشی را امتحان کنید.
اگر ویدیو را ترجیح میدهید، نسخه YouTube این پست را در اینجا ببینید:
نمای کلی
ما یک سیستم رنگی دسترسپذیر با ویژگیهای سفارشی و calc() خواهیم ساخت تا
صفحه وبی بسازیم که با اولویتهای کاربر سازگار باشد و درعینحال تجربه نوشتن را
به حداقل برساند. با رنگ اصلی نمانام شروع میکنیم و سیستمی از
انواع مختلف آن میسازیم: ۲ رنگ نوشتار، ۴ رنگ سطح، و سایه منطبق.
این راهنما با تعریف همه رنگها برای هر آرایش رنگها در ابتدا شروع میشود. تا پایان کار از آنها برای تغییر صفحه استفاده نمیشود.
نمانام
اغلب، رنگ نمانام ازقبل تعیین شده است و بهصورت
hex یا
rgb ارائه میشود. این چالش GUI
رنگ نمانام پایه #0af دارد. ابتدا، برای این سیستم رنگ، مقدار هگزادسیمال
باید به
hsl تبدیل شود.
* {
--brand: #0af;
--brand: hsl(200 100% 50%);
}
In order to enable a concept of darkening or lightening the brand color, by say 20%, the 3 channels of the hsl color value need extracted into their own custom properties, like this:
* {
--brand-hue: 200;
--brand-saturation: 100%;
--brand-lightness: 50%;
}
CSS میتواند روی آن ویژگیهای رنگ محاسبات ریاضی انجام دهد، برای مثال calc(var(--brand-lightness) -
20%) برای کاهش مقدار روشنایی تا ۲۰٪. این امر برای ساختن آرایش رنگها ضروری است، زیرا CSS میتواند با تنظیم مقادیر اشباع و روشنایی hsl، همه رنگها را در یک خانواده فام نگه دارد.
زمینه روشن
هر رنگ متفاوت با طرح منطبق با آن علامتگذاری میشود، در این مورد، هرکدام
با -light اضافه میشود.

نمانام
با شروع از رنگ نمانام، با قرار دادن ویژگیهای سفارشی --brand-hue، --brand-saturation،
و --brand-lightness در پرانتز تابع hsl ()،
بدون هیچ محاسباتی، بازسازی میشود:
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}
رنگهای نوشتار
سپس، ضروریات آرایش رنگها به رنگهای نوشتار نیاز دارد. در زمینه روشن، نوشتار باید بسیار تیره باشد. توجه کنید که روشنایی رنگهای زیر چقدر کم است، خیلی کمتر از ۵۰٪.
* {
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
}
--text1-light، ازآنجاییکه در روشنایی ۱۰٪ بسیار تیره است، اشباع سنگین ۱۰۰٪ را حفظ میکند تا رنگ نمانام همچنان بتواند در سرمهای بسیار تیره دیده شود.
--text2-light، این رنگ بهاندازه رنگ اول تیره نیست، که خوب است چون
رنگ ثانویه است، و همچنین اشباع بسیار کمتری دارد.
رنگهای سطح
رنگهای سطحی عبارتاند از پسزمینهها، حاشیهها، و دیگر سطوح تزئینی که نوشتار روی آنها یا درون آنها قرار میگیرد. در طرح زمینه روشن، اینها رنگهای روشن هستند، برخلاف رنگهای نوشتار که تیره بودند. برای ایجاد رنگهای روشن با hsl، از مقادیر درصد بالاتر در مقدار روشنایی سوم استفاده میکنیم. همچنین اشباع رنگ را کاهش میدهیم تا خاکستریهای روشن خیلی رنگی بهنظر نرسند.
* {
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
}
۴ رنگ سطح ایجاد شد زیرا رنگهای تزئینی معمولاً به انواع بیشتری نیاز دارند، برای لحظات تعاملی مانند :focus یا :hover یا برای ایجاد ظاهر لایههای کاغذی. در این سناریوها، خوب است که
--surface2-light در حالت نگه داشتن نشانگر روی آن به --surface3-light تبدیل شود، بنابراین نگه داشتن نشانگر روی آن منجر به
افزایش کنتراست میشود (۹۹٪ روشنایی به ۹۲٪ روشنایی؛ آن را تیرهتر میکند).
سایهها
سایهها در آرایش رنگها فراتر از حد انتظار هستند، اما ماهیتی واقعی به جلوه اضافه میکنند و کمک میکنند تا از سایههای غیرواقعی مبتنی بر رنگ سیاه متمایز شود. برای انجام این کار، رنگ سایه از ویژگی سفارشی فام استفاده میکند، کمی با فام اشباع میشود اما همچنان بسیار تیره است. اساساً ساختن یک سایه بسیار تیره کمی آبی.
* {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
--surface-shadow-light در تابع hsl قرار نگرفته است. دلیلش این است که مقدار --shadow-strength برای ایجاد مقداری ماتی ترکیب خواهد شد و CSS برای انجام محاسبات به این بخشها نیاز دارد. برای کسب اطلاعات بیشتر، به بخش سایه راد بروید.
رنگهای روشن باهم
No need to hunt around to find how any of the light colors are made, they are all in one place in the CSS.
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
--surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
--shadow-strength-light: .02;
}
زمینه تیره
اکثر نمانامها با زمینه تیره شروع نمیشوند، این زمینه نوعی از زمینه اصلی آنها است که معمولاً روشنتر است. ازسوی دیگر، کاربران اغلب زمینه تیره را برای بافتهای مختلف، مثل شب، انتخاب میکنند. این عوامل باعث شده است که دو چیز را در رابطه با زمینههای تیره در ذهن داشته باشم:
- کاربران معمولاً هنگام استفاده از این زمینه در تاریکی خواهند بود، بنابراین در تاریکی آزمایش کنید.
- رنگها باید اشباعزدایی شوند تا بهدلیل شدت بیشازحد روی صفحهنمایش نلرزند.

نمانام
زمینه روشن از مقادیر ۳ کانال رنگی hsl نمانام بدون تغییر استفاده میکند، زمینه تیره این کار را نمیکند. اشباع رنگ نصف میشود و روشنایی بهاندازه ۵۰٪ نسبی کاهش مییابد.
* {
--brand-dark: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 2)
calc(var(--brand-lightness) / 1.5)
);
}
رنگهای نوشتار
در زمینه تیره، رنگ نوشتار باید روشن باشد. رنگهای زیر مقدار بالایی از روشنایی دارند که آنها را به سفید نزدیکتر میکند.
* {
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
}
رنگهای سطح
در زمینه تیره، رنگهای سطح باید تیره باشند. رنگهای زیر روشنایی و اشباع کمی دارند و سطح اول با ۱۰٪ تیرهترین است.
* {
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
}
سایهها
در زمینه تیره، دیدن سایهها میتواند بسیار دشوار باشد. منطقی است چون تیره کردن چیزی که ازقبل نسبتاً تیره است کار سختی است. اینجا است که
--shadow-strength-dark بسیار مفید واقع میشود زیرا به ما امکان میدهد با تغییر یک متغیر،
سایهها را تیرهتر کنیم.
* {
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
همچنین، به میزان اشباع در آن سایه نگاه کنید. آیا وقتی به میانای کاربری نگاه میکنید متوجه رنگ میشوید؟ Try removing the saturation from the devtools, which do you prefer?!
رنگهای تیره باهم
* {
--brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
زمینه کمنور
این طرح رنگی کاملاً بر هماهنگی روشنایی و اشباع رنگ تمرکز دارد. باید اشباع کافی وجود داشته باشد تا رنگمایه همچنان قابلمشاهده باشد، اما همچنین باید بهسختی از امتیازهای کنتراست عبور کند زیرا بههرحال قرار است کمنور و با کنتراست پایین باشد.

نمانام
* {
--brand-dim: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 1.25)
calc(var(--brand-lightness) / 1.25)
);
}
رنگهای نوشتار
* {
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
}
رنگهای سطح
* {
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
}
سایهها
* {
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
کمنور کردن همه رنگها باهم
* {
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
رنگهای دسترسپذیر
توجه کنید که کمترین روشنایی در مجموعه رنگ نوشتار تیره ۶۵٪ و بیشترین روشنایی در سطوح تیره ۲۵٪ است. این یعنی ۴۰٪ روشنایی فضای تنفس بین آنها. در زمینه روشن، ۵۵٪ فضای تنفس در زمینه روشن وجود دارد. حفظ تفاوت روشنایی بین رنگهای نوشتار و سطح در حدود ۴۰ تا ۵۰ درصد میتواند به بالا نگه داشتن نسبتهای کنتراست رنگ کمک کند، درحالیکه اهرمی ظریف برای تنظیم درصورت ضعیف بودن امتیازها است.
من به آن «bump bump til ya pass» میگویم، که تعامل افزایش مقدار روشنایی است تا زمانی که ابزار نشان دهد که من قبول شدهام.
هریک از زمینههای ایجادشده در این چالش امتیازهای کنتراست را میگذرانند. طرح رنگ کمنور کمترین کنتراست را در بین آنها دارد، اما همچنان حداقل الزامات را برآورده میکند. برای کمک به دیگران در تیم برای استفاده از رنگهای متضاد خوب، ایده خوبی است که یک نام کلاس ایجاد کنید که رنگ سطح را با رنگ نوشتار قابلدسترس جفت کند.
.surface1 {
background-color: var(--surface1);
color: var(--text2);
}
.surface2 {
background-color: var(--surface2);
color: var(--text2);
}
.surface3 {
background-color: var(--surface3);
color: var(--text1);
}
.surface4 {
background-color: var(--surface4);
color: var(--text1);
}
سایه راد
این زمینهها از کلاس سودمندی بهنام .rad-shadow استفاده میکنند. این سایه در این ابزار Smooth Shadow تولید شده است که بسیار از آن قدردانی میکنم. من قطعه کد تولیدشده را برداشتم و آن را با رنگها و محاسبات شفافیت خودم سفارشیسازی کردم. دلیل این کار ایجاد سایهای بود که بتوانم آن را در هر آرایش رنگی تنظیم کنم.

برای انجام این کار، ۲ متغیر برای هر طرح رنگ ایجاد کردم تا تنظیم شود، یک رنگ سایه و یک قدرت سایه. رنگ برای تنظیمات اشباع و تیرگی است، درحالیکه قدرت برای راهی آسان برای افزایش شدت سایه در آرایش رنگهای تیره است. نتیجه نهایی چیزی شبیه این بود.
:root {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
.rad-shadow {
box-shadow:
0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
;
}
If I were to go further with shadows in my color scheme, I'd make the shadow angles a design token constant too, as the light direction should be the same between all the shadows of the design.
استفاده از آرایشهای رنگها
با تکمیل پیشتعریف رنگها، زمان تبدیل آنها به ویژگیهای مستقل از طرح فرا رسیده است. منظورم این است که بهعنوان نویسنده CSS در این پروژه طرح رنگ، بهندرت نیاز است که به مقدار طرح رنگ خاصی دسترسی داشته باشید. میخواهم کاری کنم که ماندن در زمینه آسان باشد.
برای رسیدن به این هدف، استفاده از طرح رنگ باید منحصراً ازطریق ویژگیهای سفارشی عمومی انجام شود که بهزودی آنها را تعریف خواهیم کرد. بهاینترتیب،
افرادی که از متغیرهای طراحی استفاده میکنند هرگز لازم نیست نگران این باشند که کدام آرایش رنگها
درحالحاضر تنظیم شده است، آنها فقط باید از رنگهای سطح و نوشتار استفاده کنند. بهجای
color: var(--text1-light) از color: var(--text1) استفاده کنید. همه سازگاریها و چرخشهای
رنگها در سطح بسیار بالاتری در CSS انجام میشود.
با بررسی دقیقتر، سبکهای اتصالی زمینه روشن در بلوک کد زیر،
یک ویژگی سفارشی عمومی را به رنگ خاص زمینه روشن متصل میکنند. اکنون همه
موارد استفاده از var(--brand) از رنگ روشن نمانام استفاده خواهند کرد.
زمینه روشن (خودکار)
:root {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
اکنون سایت از زمینه روشن استفاده میکند. این لحظه موفقیتآمیز بسیار سرگرمکننده است! Let's have a few more of those moments as we use our predefined colors in other color scheme contexts.
زمینه تیره (خودکار)
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
}
زمینه روشن
[color-scheme="light"] {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
زمینه تیره
[color-scheme="dark"] {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
زمینه کمنور
[color-scheme="dim"] {
color-scheme: dark;
--brand: var(--brand-dim);
--text1: var(--text1-dim);
--text2: var(--text2-dim);
--surface1: var(--surface1-dim);
--surface2: var(--surface2-dim);
--surface3: var(--surface3-dim);
--surface4: var(--surface4-dim);
--surface-shadow: var(--surface-shadow-dim);
--shadow-strength: var(--shadow-strength-dim);
}
در این مرحله، نویسندگان آزادند تا از آرایش رنگهای عمومی ارائهشده درصورت نیاز استفاده کنند و دیگر هرگز نباید نگران زمینهها باشند.
نتیجهگیری
حالا که میدانید من چطور این کار را کردم، شما چطور این کار را میکنید؟! 🙂
بیایید رویکردهایمان را متنوع کنیم و همه روشهای ساختن در وب را یاد بگیریم. یک Codepen ایجاد کنید یا نسخه نمایشی خود را میزبانی کنید، آن را برای من توییت کنید و من آن را به بخش ریمیکسهای انجمن در زیر اضافه خواهم کرد.
منبع
بازآمیزیهای انجمن
- @chris-kruining لغزنده رنگمایه،
رنگهای وضعیت، و حالتهای کنتراست را برای no-preference، more، و less اضافه کرد:
نسخه نمایشی.