web design uiNovember 5, 20267 min read

رنگ‌های گرادینت در CSS: چرا وسط گرادینت خاکستری می‌شود و ۳ راه برای رفع آن

آبی را در زرد حل کنید، وسطش خاکستری می‌شود، چون رنگ‌های hex در RGB ترکیب می‌شوند. یک stop میانی اضافه کنید، در OKLCH ترکیب کنید یا همسایه‌های روی چرخه رنگ را انتخاب کنید. پنج گرادینت آماده همراه مقاله است.

By Boone
XLinkedIn
CSS Gradient Colors: Why Gradients Turn Gray in the Middle and 3 Ways to Fix It

وسط گرادینت خاکستری می‌شود چون مرورگر رنگ‌های hex را در RGB ترکیب می‌کند و دو رنگ مقابل هم در نیمه راه همدیگر را خنثی می‌کنند. راه حل این است که عمداً به وسط یک رنگ بدهید، یا نحوه محاسبه ترکیب را عوض کنید. اینجا سه راه حل و پنج گرادینت قابل کپی دارید.

چرا وسط خاکستری می‌شود

به گرادینتی که گل‌آلود به نظر می‌رسد نگاه کنید و انتهاها را نادیده بگیرید. انتهاها خوب‌اند. شما انتخابشان کرده‌اید. وسط همان بخشی است که هیچ‌کس انتخابش نکرده.

گرادینت یک ترکیب است و ترکیب به ریاضی نیاز دارد. رنگ‌های hex مقادیر RGB هستند، پس مرورگر به‌طور پیش‌فرض آن‌ها را کانال به کانال ترکیب می‌کند.

در نیمه راه آبی و زرد، قرمز میانه 0 و 255 است، سبز میانه 0 و 255 است و آبی میانه 255 و 0 است. هر کانال نزدیک 128 می‌نشیند. قرمز، سبز و آبی برابر یعنی تعریف خاکستری.

#0000FF به #FFFF00

گرادینتی از آبی به زرد که وسطش خاکستری مات می‌شود

با stop میانی #0EBAAE

همان گرادینت آبی به زرد با وسط فیروزه‌ای که در تمام مسیر رنگی می‌ماند
دو انتهای یکسان. در سمت چپ ترکیب مستقیم از #808080 رد می‌شود. در سمت راست وسط یک فیروزه‌ای است، پس گرادینت در تمام مسیر زنده می‌ماند.

این تقصیر مانیتور شما یا مشکل فشرده‌سازی نیست. حساب و کتاب است و هر وقت دو رنگ روی چرخه رنگ از هم دور باشند پیدا می‌شود. آبی و زرد تقریباً دقیقاً مقابل هم‌اند، که بدترین حالت است.

راه حل ۱: یک stop میانی اضافه کنید

مستقیم‌ترین راه این است که وسط را به شانس نسپارید. یک color stop سوم در 50% اضافه کنید که رنگش را خودتان انتخاب کرده‌اید.

css
background: linear-gradient(90deg, #0000FF, #0EBAAE, #FFFF00);

#0EBAAE فیروزه‌ای است که در رنگ ادراکی بین آبی و زرد قرار می‌گیرد. حالا ترکیب از آبی به فیروزه‌ای و بعد فیروزه‌ای به زرد می‌رود و هیچ نیمه‌ای از خاکستری عبور نمی‌کند.

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

راه حل ۲: در OKLCH ترکیب کنید

راه دیگر به جای افزودن رنگ، ریاضی را عوض می‌کند. CSS اجازه می‌دهد فضای رنگی ترکیب را انتخاب کنید و OKLCH رنگ را با روشنایی، chroma و hue توصیف می‌کند. Chroma نشان می‌دهد رنگ چقدر پرجلوه است، پس ترکیبی که chroma را حفظ کند رنگی می‌ماند.

css
background: linear-gradient(in oklch, #0000FF, #FFFF00);

با in oklch مرورگر به جای عبور مستقیم از مرکز خاکستری، دور چرخه رنگ می‌چرخد و از سبزها و فیروزه‌ای‌ها می‌گذرد. دو رنگ نگه می‌دارید و کد کوتاه می‌ماند. MDN این را به عنوان روش interpolation رنگ داخل تابع گرادینت مستند کرده است و رنگ‌های hex قدیمی وقتی چیزی انتخاب نکنید فقط از RGB استفاده می‌کنند تا با صفحه‌های قدیمی‌تر سازگار بمانند.

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

راه حل ۳: همسایه‌ها را انتخاب کنید

راه سوم به کد دست نمی‌زند. رنگ‌هایی انتخاب می‌کند که نمی‌توانند همدیگر را خنثی کنند.

#0066FF به #FF8800

گرادینتی از آبی به نارنجی که وسطش خاکستریِ مایل به قهوه‌ای کدر می‌شود

#6440E0 به #E040A0

گرادینتی از بنفش به صورتی که در تمام مسیر درخشان می‌ماند
آبی و نارنجی مقابل هم‌اند، پس در #807780 کدر به هم می‌رسند. بنفش و صورتی همسایه‌اند، پس در #A240C0 پرمایه به هم می‌رسند.

رنگ‌های مقابل به خاکستری ترکیب می‌شوند. همسایه‌ها به چیزی بین خودشان می‌رسند که هنوز رنگ است. اگر یک برند دو رنگ مقابل را کنار هم گذاشته، باز هم می‌توانید در گرادینت از آن‌ها استفاده کنید: یک stop میانی بینشان بگذارید یا در OKLCH ترکیب کنید.

آبی به نارنجی، ترکیب پیش‌فرض

گرادینت آبی به نارنجی با وسط خاکستریِ مایل به قهوه‌ای

آبی به نارنجی، در oklch

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

گرادینت خودتان را چطور بررسی کنید

  1. به وسط نگاه کنید، نه انتهاها.
  2. رنگی را که آنجا می‌بینید اسم ببرید. اگر اسمش خاکستری، قهوه‌ای یا گل است، مثل #808080 یا #807780، مشکل همین است.
  3. یکی از راه حل‌های بالا را انتخاب کنید و دو نسخه را کنار هم مقایسه کنید.

گرادینت فقط به اندازه بدترین نقطه‌اش خوب است و بدترین نقطه‌اش تقریباً همیشه وسط است.

پنج گرادینت برای برداشتن

هر کدام بررسی شده که وسطش رنگی بماند. اولی یک stop میانی داخلی دارد. چهار تای دیگر از hueهای همسایه استفاده می‌کنند. روی یک کد بزنید تا کپی شود.

گرادینتی از آبی از میان فیروزه‌ای به زرد
آبی، فیروزه‌ای، زرد. روی یک رنگ بزنید تا کدش کپی شود.
گرادینتی از بنفش به صورتی
بنفش به صورتی. روی یک رنگ بزنید تا کدش کپی شود.
گرادینتی از آبی به فیروزه‌ای
آبی به فیروزه‌ای. روی یک رنگ بزنید تا کدش کپی شود.
گرادینتی از نارنجی به صورتی تند
نارنجی به صورتی تند. روی یک رنگ بزنید تا کدش کپی شود.
گرادینتی از سبز به لیمویی
سبز به لیمویی. روی یک رنگ بزنید تا کدش کپی شود.
گرادینتشروعوسطپایانچرا کار می‌کند
آبی، فیروزه‌ای، زرد#0000FF#0EBAAE#FFFF00انتهاهای مقابل، نجات‌یافته با یک stop میانی واقعی
بنفش به صورتی#6440E0ندارد#E040A0همسایه‌ها روی چرخه رنگ
آبی به فیروزه‌ای#2F5BEAندارد#14B8A6همسایه‌ها روی چرخه رنگ
نارنجی به صورتی تند#FF7A00ندارد#FF2E93همسایه‌ها روی چرخه رنگ
سبز به لیمویی#00A86Bندارد#C6F432همسایه‌ها روی چرخه رنگ

این را به توسعه‌دهنده‌تان بدهید

css
.gradient-sunrise { background: linear-gradient(90deg, #0000FF, #0EBAAE, #FFFF00); } .gradient-violet { background: linear-gradient(90deg, #6440E0, #E040A0); } .gradient-ocean { background: linear-gradient(90deg, #2F5BEA, #14B8A6); } .gradient-sunset { background: linear-gradient(90deg, #FF7A00, #FF2E93); } .gradient-meadow { background: linear-gradient(90deg, #00A86B, #C6F432); } /* Two opposite colors, no middle stop: choose the blend space instead. */ .gradient-opposites { background: linear-gradient(in oklch, #0066FF, #FF8800); }

اگر مرورگری in oklch را نفهمد، کل declaration را نادیده می‌گیرد. اول یک خط linear-gradient(...) ساده به عنوان fallback بنویسید و بعد خط OKLCH را بعدش بیاورید.

سوالات متداول

چرا وسط گرادینت من خاکستری می‌شود؟

رنگ‌های hex در RGB ترکیب می‌شوند و دو رنگی که روی چرخه رنگ از هم دورند میانگینشان خاکستری می‌شود. آبی #0000FF و زرد #FFFF00 در #808080 به هم می‌رسند.

چطور جلوی گل‌آلود شدن گرادینت CSS را بگیرم؟

یک color stop میانی با رنگ واقعی اضافه کنید، با linear-gradient(in oklch, ...) در OKLCH ترکیب کنید، یا دو رنگی انتخاب کنید که روی چرخه کنار هم‌اند.

«in oklch» در گرادینت CSS چه کار می‌کند؟

به مرورگر می‌گوید رنگ‌ها را به جای RGB در فضای رنگی OKLCH ترکیب کند، پس وسط گرادینت رنگش را نگه می‌دارد و به خاکستری سقوط نمی‌کند.

چه رنگ‌های گرادینتی با هم خوب به نظر می‌رسند؟

همسایه‌های روی چرخه رنگ، مثل بنفش #6440E0 به صورتی #E040A0 یا سبز #00A86B به لیمویی #C6F432. ترکیبشان در تمام مسیر روشن می‌ماند.

آیا همه مرورگرها از گرادینت در OKLCH پشتیبانی می‌کنند؟

مرورگرهای مدرن بله، ولی مرورگری که پشتیبانی نکند declaration را حذف می‌کند. قبل از آن یک خط گرادینت ساده به عنوان fallback اضافه کنید.

چرا آبی به زرد خاکستری می‌شود و سبز نمی‌شود؟

چون ترکیب مسیر مستقیم را از RGB می‌رود، جایی که میانگین آن دو خاکستری است. وسط سبز فقط وقتی پیدا می‌شود که آن را به عنوان stop اضافه کنید یا در OKLCH ترکیب کنید.

منابع

  • CSS Color Module Level 4, interpolation: رنگ‌های قدیمی sRGB مثل hex به‌طور پیش‌فرض در sRGB interpolate می‌شوند و فضاهای دیگر با روش interpolation رنگ انتخاب می‌شوند.
  • MDN, linear-gradient(): سینتکس <color-interpolation-method> و in oklch.
  • MDN, OKLCH color: روشنایی، chroma و hue.
  • نقطه میانی (0, 0, 255) و (255, 255, 0) برابر (127.5, 127.5, 127.5) است، یعنی #808080 با chroma صفر در OKLCH. نقاط میانی #0066FF به #FF8800 (برابر #807780) و #6440E0 به #E040A0 (برابر #A240C0) را خودمان در sRGB محاسبه کردیم. نوارهای این صفحه از همین محاسبات رندر شده‌اند و نوار OKLCH رنگ‌های خارج از محدوده صفحه را مثل مرورگرها clip می‌کند.
  • اولین بار به صورت کروسل در UX Brainy منتشر شد.

Want gradients, color and every other detail designed as one system? Our team designs and builds product UI that holds up on every screen.

Get Started

More from Brainy Papers

Keep reading