IlmHamroh
JavaScript Full-stack/5-qism. CSS asoslari va layout19/63-dars21 daqiqa
Mundarija (34)

CSS color-mix() va nisbiy ranglar: hover, och fon va qorong'i rejim bitta rangdan

Qisqacha: color-mix(in oklch, A 20%, B) ikki rangni aralashtiradi: 20% A va 80% B. Nisbiy rang oklch(from var(--rang-asosiy) calc(l - 0.08) c h) asosiy rangning uch sonini olib, bittasini o'zgartiradi — masalan, to'qroq hover rangi hosil bo'ladi. Funksiya light-dark(yorug', qorong'i) sahifaning color-scheme iga qarab ikki rangdan birini tanlaydi. Yangi contrast-color() esa fon uchun oq yoki qora matnni tanlaydi. Aralashtirish hamma brauzerda ishlaydi, qolgan uchtasi esa yangi: eski brauzerlar uchun zaxira kerak. Hosil bo'lgan har rangning kontrastini alohida tekshiring.

Bu darsda

  • color-mix() bilan och, to'q va shaffof variantlar yasaysiz va aralashtirish fazosini tanlaysiz.
  • Nisbiy rang bilan asosiy rangdan hover rangini hisoblaysiz.
  • color-scheme xususiyati va light-dark() bilan «Bahor»ga qorong'i ranglar berasiz.
  • contrast-color() nima qilishini va uning chegaralarini bilasiz.
  • Hosil qilingan ranglarning kontrastini tekshirasiz va yangi imkoniyatlar uchun to'g'ri zaxira yozasiz.

Oldin bilishingiz kerak: Ranglar 2: oklch(), CSS o'zgaruvchilari 2, Favicon va color-scheme, Accessibility.

1. Nega bu kerak?

«Bahor» palitrasida oltita rang bor. Lekin sayt uchun har biridan bir nechta variant kerak: sichqoncha ustidagi to'qroq tugma, mashhur taom kartasining och foni, yarim shaffof soya, qorong'i rejim uchun alohida rang. Oltita rang × to'rt variant — 24 ta qiymat. Jasur aka brend yashilini o'zgartirsa, uning hamma variantini qaytadan hisoblash kerak.

Choyxonada choy qanday suzilishini eslang. Choynakda quyuq damlama bor. Kimga quyuqroq, kimga suyuqroq kerak bo'lsa — damlamaga kaynoq suv qo'shiladi. Har mehmon uchun alohida choy damlanmaydi.

Bu darsda CSS'ga xuddi shunday ishlashni o'rgatamiz: asosiy rang bitta, variantlarni brauzer o'zi "suzib beradi". Asosiy rang o'zgarsa — hamma variant o'zi yangilanadi.

2. color-mix(): ikki rangni aralashtirish

2.1 Sintaksis va foizlar

css
.taom-karta.mashhur {
  background-color: color-mix(
    in oklch,
    var(--rang-asosiy) 10%,
    var(--rang-fon)
  );
}

O'qilishi: "oklch fazosida 10% asosiy rang va qolgani fon rangini aralashtir".

  • in oklch — qaysi fazoda aralashtirish. Uni doim yozamiz; nega fazo muhimligini pastroqda, «Qaysi fazoda aralashtirish kerak» bo'limida ko'ramiz.
  • Ranglar vergul bilan, har birining yonida ulushi.
  • Faqat bittasining ulushi yozilsa, ikkinchisi — qolgani: 10% va 90%.
  • Ulush umuman yozilmasa — teng: 50% va 50%.
  • Ulushlar yig'indisi 100% dan kam bo'lsa, natija shaffoflashadi. Chrome'da tekshirdik: 30% va 30% — 60% shaffoflikdagi rang. Chalkashmaslik uchun yig'indi 100% bo'lsin.

2.2 Oq, qora va shaffof bilan

Oq bilan aralashtirsangiz — och variant, qora bilan — to'q variant, transparent bilan — yarim shaffof variant:

html
<style>
  :root {
    --rang-asosiy: oklch(47.5% 0.1 147.7);
    --rang-fon: oklch(98.6% 0.014 84.6);
  }
  p {
    font-family: system-ui, sans-serif;
  }
  span {
    padding: 8px 10px;
  }
</style>
<p>
  <span style="background: color-mix(in oklch,
    var(--rang-asosiy) 85%, black); color: var(--rang-fon)">
    85% + qora</span>
  <span style="background: var(--rang-asosiy);
    color: var(--rang-fon)">asosiy</span>
  <span style="background: color-mix(in oklch,
    var(--rang-asosiy), white)">50% + oq</span>
  <span style="background: color-mix(in oklch,
    var(--rang-asosiy) 15%, transparent)">15% + shaffof</span>
</p>

Nimaga qarang: to'rtala bo'lak bitta yashildan hosil bo'lgan. Birinchisi to'qroq, uchinchisi ochroq, oxirgisi yarim shaffof — orqasidagi oq fon ko'rinib turibdi. Hex kod yo'q — faqat --rang-asosiy. Qora va oqning o'z tusi yo'q, shuning uchun oklch da aralashtirilganda yashilning tusi 147.7-bob o'zgarmaydi. Chrome hisoblagan qiymatlarda buni tekshirdik.

2.3 Qaysi fazoda aralashtirish kerak

in dan keyingi so'z natijani sezilarli o'zgartiradi. Ko'k va sariqni teng aralashtiramiz:

html
<style>
  p {
    font-family: system-ui, sans-serif;
  }
  span {
    padding: 16px 12px;
    color: #1f2a24;
  }
</style>
<p>
  <span style="background: color-mix(in srgb, blue, yellow)">
    srgb</span>
  <span style="background: color-mix(in oklab, blue, yellow)">
    oklab</span>
  <span style="background: color-mix(in oklch, blue, yellow)">
    oklch</span>
</p>

Nimaga qarang: srgb da o'rtada xira kulrang chiqdi (#808080). oklab da — och havorang. oklch da — yorqin moviy-yashil. Uchta fazo — uchta javob.

Nega shunday? Birinchisi, srgb, ekran chiroqlarini hisoblaydi — ko'k va sariqning o'rtasi "hech narsa" bo'lib qoladi. Ikkinchisi, oklab, ko'zga teng fazoda to'g'ri chiziq bo'ylab yuradi. Uchinchisi, oklch, tusni rang doirasi bo'ylab aylantiradi: ko'kdan sariqqa yo'lda yashil tuslardan o'tadi va to'yinganlikni saqlaydi.

«Bahor»da bu farq real muammoga olib keldi. Mashhur kartaga och yashil fon kerak edi — 12% asosiy rang va 88% qaymoq fon. oklch da aralashtirdik va... fon yashil emas, och sarg'ish chiqdi. Sababi: qaymoq fonning ham o'z tusi bor 84.6-bob. Aralashtirish tusni ikki rang orasida aylantirdi, 88% fon tomonga — natijada tus 92 atrofida, sarg'ish bo'lib qoldi. Xuddi shu ulushlar oklab da aralashtirilsa, tus aylanmaydi — natija och yashil-kulrang chiqdi.

Qoida:

Nima qilyapsiz Qaysi fazo
Oq, qora yoki shaffof bilan aralashtirish in oklch — tus o'zgarmaydi
Rangni boshqa rang bilan (masalan, yashil + qaymoq fon) in oklab — tus aylanmaydi
"Xira" o'rtani ataylab olish in srgb — kamdan-kam

in so'zini doim yozing. Chrome'ning yangi versiyasida tekshirdik: in siz ham ishladi va oklab da aralashtirdi. Lekin bu yangi o'zgarish — eski brauzerlar bunday deklaratsiyani tashlab ketadi.

color-mix() ning o'zi Baseline ma'lumotiga ko'ra keng tarqalgan: hamma asosiy brauzerda 2023-yildan beri bor. Uch va undan ortiq rangni bittada aralashtirish esa hali Baseline emas — Chrome'da yo'q.

3. Nisbiy ranglar

3.1 Sintaksis: from

Aralashtirish har doim ham kerak emas. Ko'pincha bitta rangning "o'zini" olib, bitta sonini o'zgartirish kerak: "xuddi shu yashil, faqat biroz to'qroq". Bunga nisbiy rang (relative color) deyiladi:

css
.bron-havola:hover {
  background-color: oklch(
    from var(--rang-asosiy) calc(l - 0.08) c h
  );
}

O'qilishi: "--rang-asosiy ni ol. Uni oklch sonlariga ajrat: l, c, h. c va h ni o'zgartirmay qoldir, l dan 0.08 ayir."

  • from dan keyin — asl rang: istalgan formatda, o'zgaruvchi ham bo'ladi.
  • l, c, h — asl rangning sonlari. Ular Matematik funksiyalar darsidagi calc() ichida ishlatiladi.
  • alpha — shaffoflik soni, u ham bor.

Retsept kabi: tayyor oshni olasiz, hammasi o'sha, faqat tuzi kamroq.

Diqqat: Bu yerda l — foiz emas, 0 dan 1 gacha son. Chrome'da tekshirdik: calc(l - 10%) ishlamadi, rang umuman yo'qoldi. To'g'risi — calc(l - 0.1). Ranglar 2 darsidagi 47.5% = 0.475 ni eslang.

3.2 Hover rangi

CSS o'zgaruvchilari 2 darsidagi .bron-havola API'siga qaytamiz. U yerda sichqoncha ustida fon va matn o'rin almashardi. Endi hover — to'qroq fon:

html
<style>
  :root {
    --rang-asosiy: oklch(47.5% 0.1 147.7);
    --rang-urgu: oklch(53.7% 0.153 39.8);
    --rang-fon: oklch(98.6% 0.014 84.6);
  }
  .bron-havola {
    --_fon: var(--tugma-fon, var(--rang-asosiy));
    background-color: var(--_fon);
    color: var(--rang-fon);
    padding: 8px 16px;
  }
  .bron-havola:hover {
    background-color: oklch(
      from var(--_fon) calc(l - 0.08) c h
    );
  }
  .aksiya {
    --tugma-fon: var(--rang-urgu);
  }
</style>
<p><a class="bron-havola" href="bron/">Stolni band qilish</a></p>
<p class="aksiya">
  <a class="bron-havola" href="bron/">Aksiya: joy band qilish</a>
</p>

Nimaga qarang: sichqonchani ikkala tugma ustiga olib boring. Ikkalasi ham biroz to'qlashadi — yashil to'q yashilga, qizg'ish to'q qizg'ishga. Hover qoidasi bitta va unda birorta rang nomi yo'q. U tugmaning o'z rangidan hisoblaydi.

3.3 Shaffoflik

Rangning yarim shaffof nusxasi ikki yo'l bilan olinadi:

css
.taom-karta.mashhur {
  /* nisbiy rang */
  box-shadow: 0 4px 12px
    oklch(from var(--rang-asosiy) l c h / 25%);
  /* yoki color-mix — natija bir xil */
  box-shadow: 0 4px 12px
    color-mix(in oklch, var(--rang-asosiy) 25%, transparent);
}

Chrome'da ikkalasini hisoblatdik — bir xil rang chiqdi. box-shadow — element soyasi, uni Chegara va soyalar darsida o'rganamiz. Qaysi yo'lni tanlash kerak? color-mix() keng tarqalgan, nisbiy rang esa yangi — buni shu bo'limning oxirida, «Yangi imkoniyat va zaxira» qismida ko'ramiz. Shaffoflik uchun color-mix() xavfsizroq.

3.4 Boshqa funksiyalarda ham

from hamma rang funksiyasida ishlaydi, faqat son nomlari funksiyaga qarab o'zgaradi:

  • rgb(from ... r g b), hsl(from ... h s l), oklch(from ... l c h).
  • Tusni burish ham mumkin: oklch(from var(--rang-asosiy) l c calc(h + 180)) — rang doirasining qarama-qarshi tomonidagi rang. Buni Palitra qurish darsida ishlatamiz.

Nomlarni aralashtirib yubormang: oklch(from ... r g b) — xato, oklch da r yo'q.

3.5 Yangi imkoniyat va zaxira

Baseline ma'lumotiga ko'ra nisbiy ranglar — yangi Baseline: hamma asosiy brauzerda faqat 2024-yil sentabridan beri ishlaydi (Chrome 125, Firefox 128, Safari 18). Undan eski brauzerlarda ishlamaydi.

Zaxira yozishda CSS o'zgaruvchilari 2 dagi tuzoq kutib turibdi. Avval oddiy rang, keyin yangisi — bu usul var() bo'lsa ishlamaydi:

css
.bron-havola:hover {
  background-color: var(--rang-asosiy-toq);
  background-color: oklch(
    from var(--_fon) calc(l - 0.08) c h
  );
}

Eski brauzer ikkinchi deklaratsiyani ham qabul qiladi — ichida var() bor. Keyin hisoblashda yaroqsiz chiqadi va fon shaffof bo'lib qoladi. Birinchi qator qutqarmaydi. Buni zamonaviy Chrome'da ham ko'rsatdik: nisbiy rangni ataylab xato yozdik (fromm), var() bor holatda oldingi rang yo'qoldi, var() siz esa saqlanib qoldi.

To'g'ri yo'l — @supports: "brauzer shuni tushunsa, ichidagini qo'lla". Uni Brauzer mosligi darsida to'liq o'rganamiz:

css
.bron-havola:hover {
  background-color: var(--rang-asosiy-toq);
}

@supports (color: oklch(from red l c h)) {
  .bron-havola:hover {
    background-color: oklch(
      from var(--_fon) calc(l - 0.08) c h
    );
  }
}

Shartdagi rang ataylab var() siz yozilgan: var() bo'lsa, eski brauzer ham "tushundim" deb javob beradi.

4. Hosil qilingan ranglarning kontrasti

Brauzer rangni hisoblaydi, lekin o'qilishini tekshirmaydi. Bu — sizning ishingiz. Biz har variantni Chrome'da hisoblatdik va uning WCAG kontrastini o'lchadik (Accessibility darsidagi 4.5:1 talabi):

Fon Matn Kontrast
--rang-asosiy --rang-fon 6.1
l - 0.08 (hover) --rang-fon 8.7
l + 0.15 (ochroq hover) --rang-fon 3.3
12% asosiy + fon (oklch) --rang-urgu 4.4
oklch(from ... 0.95 0.025 h) --rang-urgu 4.8

Ikki xulosa:

  • Och matnli tugmada hover'ni ochartirmang. Fon ochargan sari och matn o'qilmay qoladi. To'qroq hover esa kontrastni oshiradi.
  • Och fonda eng zaif matnni tekshiring. Mashhur kartaning och fonida oddiy matn yaxshi o'qiladi (11.9:1), lekin narx — urg'u rangi — 4.4:1 ga tushib qoldi. Yechim — fonni aralashtirish emas, nisbiy rang bilan aniq yasash: tus asosiy rangdan, L va C esa qat'iy (0.95, 0.025). Bu fon ham och yashil, ham narxga 4.8:1 beradi.

Kontrastni o'zingiz qanday o'lchaysiz? DevTools rang tanlagichi matn rangi uchun kontrast ko'rsatkichini ko'rsatadi (DevTools'da CSS). To'liq tekshiruv usullarini CSS'da accessibility darsida o'rganamiz.

Tekshirib ko'ring: Qorong'i yashil tugmada och matn bor. Hover uchun calc(l - 0.08) va calc(l + 0.08) dan qaysi biri xavfsizroq?

Javob

calc(l - 0.08) — fon to'qlashadi, och matn bilan farq kattalashadi, kontrast oshadi. calc(l + 0.08) da fon ochlashadi va matnga yaqinlashadi — kontrast pasayadi. Qaysi yo'nalish xavfsiz ekanini matn rangi hal qiladi: och matn — fon to'qlashsin, to'q matn — fon ochlashsin.

5. color-scheme va light-dark()

5.1 color-scheme xususiyati

Favicon darsida «Bahor» head iga <meta name="color-scheme" content="light dark"> qo'ygan edik va "CSS'da ham xuddi shunday color-scheme xususiyati bor" degan edik. Mana u:

css
:root {
  color-scheme: light dark;
}

Ma'nosi meta teg bilan bir xil: "sahifa yorug' va qorong'i rejimni ham ko'tara oladi". Brauzer o'zining standart ranglarini — fon, matn, forma maydonlari, aylantirish chizig'i — foydalanuvchi rejimiga moslaydi. Qiymatlari ham o'sha: normal, light, dark, light dark, only light.

Farqi ikkita:

  • Meta teg ertaroq keladi. Brauzer uni HTML'dan, CSS fayl yuklanmasdan oldin o'qiydi. Shuning uchun qorong'i rejimda oq "chaqnash" bo'lmaydi.
  • CSS xususiyati istalgan elementga beriladi. footer { color-scheme: dark; } — faqat footer qorong'i. Meta teg esa faqat butun sahifaga.

«Bahor»da ikkalasi turadi: meta — erta signal, CSS — aniq nazorat.

5.2 light-dark()

light-dark(A, B) — element yorug' rejimda bo'lsa A rangni, qorong'i rejimda bo'lsa B ni beradi. Qaysi rejim ekanini elementning color-scheme i va foydalanuvchi sozlamasi hal qiladi.

Chrome'da tekshirdik:

  • color-scheme umuman berilmagan bo'lsa, light-dark() doim birinchi rangni beradi — hatto tizim qorong'i rejimda bo'lsa ham.
  • color-scheme: light dark (yoki meta teg) bo'lsa — tizim sozlamasiga qarab.
  • color-scheme: only light — doim birinchisi.

5.3 «Bahor»ning qorong'i ranglari

Palitradagi har rangga ikkinchi, qorong'i qiymatini qo'shamiz. Qorong'i fon va brend rangi — Favicon darsidagi theme-color (#16301b) va qorong'i favicon (#8fd19e) ranglari, oklch ga o'girilgan:

css
:root {
  color-scheme: light dark;
  --rang-fon: light-dark(
    oklch(98.6% 0.014 84.6),
    oklch(28.2% 0.05 148.6)
  );
  --rang-matn: light-dark(
    oklch(27.2% 0.019 161),
    oklch(98.6% 0.014 84.6)
  );
  --rang-asosiy: light-dark(
    oklch(47.5% 0.1 147.7),
    oklch(80.3% 0.098 150.8)
  );
  --rang-urgu: light-dark(
    oklch(53.7% 0.153 39.8),
    oklch(75% 0.13 39.8)
  );
  --rang-ikkinchi: light-dark(
    oklch(49.9% 0.016 162),
    oklch(80% 0.016 162)
  );
}

Qorong'i fondagi kontrastlarni hisobladik: matn 13.7:1, asosiy 8.0:1, urg'u 6.1:1, ikkinchi 7.7:1 — hammasi 4.5:1 dan yuqori.

asosiy.css ning qolgan qismi o'zgarmaydi. body baribir var(--rang-fon) ni o'qiydi — qiymat esa rejimga qarab o'zgaradi. Natija oynasi qurilmangiz rejimiga ergashadi: telefoningiz yorug' rejimda bo'lsa, qorong'i ranglarni ko'rmaysiz. Shuning uchun ularni footer'da majburan ko'rsatamiz — ikkala rejim ham bir vaqtda ko'rinsin:

html
<style>
  :root {
    color-scheme: light dark;
    --rang-fon: light-dark(
      oklch(98.6% 0.014 84.6), oklch(28.2% 0.05 148.6));
    --rang-matn: light-dark(
      oklch(27.2% 0.019 161), oklch(98.6% 0.014 84.6));
    --rang-asosiy: light-dark(
      oklch(47.5% 0.1 147.7), oklch(80.3% 0.098 150.8));
    --rang-urgu: light-dark(
      oklch(53.7% 0.153 39.8), oklch(75% 0.13 39.8));
  }
  body,
  footer {
    background-color: var(--rang-fon);
    color: var(--rang-matn);
    font-family: system-ui, sans-serif;
  }
  a {
    color: var(--rang-asosiy);
  }
  .narx {
    color: var(--rang-urgu);
  }
  footer {
    color-scheme: dark;
    padding: 4px 12px;
  }
</style>
<main>
  <p>Osh — <span class="narx">35 000 so'm</span></p>
  <p><a href="menyu/">To'liq menyu</a></p>
</main>
<footer>
  <p>Ko'k choy — <span class="narx">5 000 so'm</span></p>
  <p><a href="aloqa/">Aloqa</a></p>
</footer>

Nimaga qarang: yuqori qism — odatiy yorug' «Bahor» (qurilmangiz qorong'i rejimda bo'lsa, u ham qorong'i). Footer esa to'q yashil fonda: matn qaymoq, havola och yashil, narx och qizg'ish. Qoidalar ikkala qism uchun bir xil. Footer faqat color-scheme: dark dedi — qolganini light-dark() qildi. CSS o'zgaruvchilari 1 darsida xuddi shu footer uchun uchta rangni qo'lda qayta yozgan edik.

Qanday ishlaydi? :root dagi light-dark() o'sha yerda hal bo'lmaydi. U o'zgaruvchi ichida matn sifatida saqlanadi va var() o'qilgan elementda — masalan, footer'dagi havolada — hal bo'ladi. Havolaning rejimi esa qorong'i.

flowchart TD
  R[":root<br/>--rang-asosiy: light-dark(yashil, och yashil)"]
  R -->|"meros"| M["main ichidagi a<br/>rejim: yorug'"]
  R -->|"meros"| F["footer ichidagi a<br/>rejim: qorong'i"]
  M --> MY["yashil"]
  F --> FO["och yashil"]

Nimaga qarang: o'zgaruvchi ikkala havolaga bir xil yetib boradi. Qaysi rangni olishni har havola o'zi, o'z rejimiga qarab hal qiladi.

Bu CSS o'zgaruvchilari 1 darsidagi ogohlantirishni ham yopadi. O'shanda «Bahor»da meta teg bor edi, palitra esa faqat yorug' edi. Qorong'i rejimdagi telefonda forma maydonlari qorong'i, sahifa esa qaymoq ko'rinishi mumkin edi. Endi palitraning o'zi ham rejimga ergashadi.

To'liq qorong'i rejim — foydalanuvchi o'zi almashtiradigan tugma, tanlovni eslab qolish, rasmlar va soyalar — Qorong'i rejim darsida. Tizim sozlamasini @media (prefers-color-scheme: dark) bilan tekshirishni esa Foydalanuvchi afzalliklari darsida o'rganamiz.

5.4 Yangi imkoniyat va zaxira

Baseline ma'lumotiga ko'ra light-dark() — yangi Baseline: 2024-yil mayidan beri hamma asosiy brauzerda bor (Chrome 123, Firefox 120, Safari 17.5). Eski brauzerda u ishlamaydi. color-scheme xususiyati esa ancha eski va keng tarqalgan.

Bu yerda ham nisbiy ranglardagi zaxira tuzog'i bor. --rang-fon: light-dark(...) ni eski brauzer matn sifatida qabul qiladi, var(--rang-fon) esa hisoblashda buziladi — fon shaffof bo'lib qoladi. Zaxira:

css
:root {
  --rang-fon: oklch(98.6% 0.014 84.6);
  --rang-matn: oklch(27.2% 0.019 161);
}

@supports (color: light-dark(white, black)) {
  :root {
    color-scheme: light dark;
    --rang-fon: light-dark(
      oklch(98.6% 0.014 84.6),
      oklch(28.2% 0.05 148.6)
    );
    --rang-matn: light-dark(
      oklch(27.2% 0.019 161),
      oklch(98.6% 0.014 84.6)
    );
  }
}

Eski brauzer yorug' «Bahor»ni ko'radi, yangisi — foydalanuvchi tanlagan rejimni. color-scheme ni ham @supports ichiga oldik. Aks holda eski brauzer forma maydonlarini qorong'i qilib, sahifani yorug' qoldirardi.

Diqqat qiling: meta teg ham brauzerga "qorong'i rejimni bilaman" deydi. light-dark() ni tushunmaydigan brauzerda u ham shu nomuvofiqlikni beradi. «Bahor»da buni hisobga olish yoki olmaslik — Qorong'i rejim darsidagi qaror.

6. contrast-color(): oq yoki qora matn

Ba'zan fon rangi oldindan ma'lum emas — masalan, uni ma'lumotlar bazasidan olingan yorliq rangi belgilaydi. Matn qaysi rangda bo'lsin? contrast-color() shunga javob beradi:

html
<style>
  p {
    font-family: system-ui, sans-serif;
    font-weight: bold;
  }
  span {
    padding: 8px 10px;
    background-color: var(--fon);
    color: contrast-color(var(--fon));
  }
</style>
<p>
  <span style="--fon: #2f6b3a">Osh</span>
  <span style="--fon: #fffaf0">Choy</span>
  <span style="--fon: #b4461a">Aksiya</span>
  <span style="--fon: #e07b39">Yangi</span>
  <span style="--fon: #8fd19e">Parhez</span>
  <span style="--fon: #2a7ae2">Sovuq</span>
</p>

Nimaga qarang: to'q yashil va qizg'ish fonda matn oq, qaymoq, to'q sariq va och yashil fonda — qora. Oxirgi, o'rta ko'k fonda ham qora — va uni o'qish unchalik oson emas.

Nima bo'layotganini bilish kerak:

  • Faqat ikki javob: white yoki black. Brend rangini tanlamaydi.
  • Qaysi birini tanlaydi. Chrome'da tekshirdik: u WCAG kontrasti yuqori bo'lganini tanladi. Masalan, #777777 da qora (4.69 va 4.48), #747474 da oq (4.67 va 4.49). MDN yozishicha, brauzerlar boshqa, yaxshiroq algoritm ham ishlatishi mumkin.
  • Formal talab bajariladi, lekin o'qilish kafolatlanmaydi. WCAG formulasida oq va qora kontrastlari ko'paytmasi doim 21 ga teng. Demak ulardan kattasi hech qachon √21 ≈ 4.58 dan kichik bo'lmaydi — 4.5:1 doim bajariladi. Lekin o'rta ko'k (#2a7ae2) kabi fonda qora matn 5.0:1 bo'lsa ham, ko'zga og'ir. MDN ham shu haqda ogohlantiradi: contrast-color() ni juda och yoki juda to'q fonlar bilan ishlating.

Baseline ma'lumotiga ko'ra contrast-color() — juda yangi: hamma asosiy brauzerda faqat 2026-yil apreldan beri bor (Chrome 147, Firefox 146, Safari 26). Ko'p foydalanuvchida hali eski brauzer. Yuqoridagi natijada ham var() bor — eski brauzerda matn rangi otasidan olinadi. Muhim joyda zaxira bering: var() siz yozilgan rang uchun avval oddiy color, keyin contrast-color(). var() bilan esa @supports (color: contrast-color(red)) — nisbiy ranglarning zaxirasi kabi.

«Bahor»ning o'z tugmalarida contrast-color() shart emas: ularning ranglari ma'lum va kontrasti hisoblangan.

7. Ko'p uchraydigan xatolar

7.1 l ni foizda kamaytirish

oklch(from var(--rang-asosiy) calc(l - 10%) c h) — yaroqsiz, rang yo'qoladi. Tuzatish: calc(l - 0.1).

7.2 O'zgaruvchi o'zidan hisoblanadi

css
.bron-havola:hover {
  --_fon: oklch(from var(--_fon) calc(l - 0.08) c h);
}

--_fon o'zini o'qiydi — bu CSS o'zgaruvchilari 2 dagi aylanma bog'lanish. Chrome'da tekshirdik: fon butunlay shaffof bo'ldi. Tuzatish: yangi rangni o'zgaruvchiga emas, xususiyatga yozing: background-color: oklch(from var(--_fon) ...).

7.3 :root dagi hosila rang joyida yangilanmaydi

css
:root {
  --rang-asosiy: oklch(47.5% 0.1 147.7);
  --rang-chegara: color-mix(in oklch, var(--rang-asosiy) 25%, white);
}
footer {
  --rang-asosiy: oklch(53.7% 0.153 39.8);
}

Footer'dagi var(--rang-chegara) qizg'ish emas, yashil aralashma beradi. Chrome'da tekshirdik. var(--rang-asosiy) :root da, o'sha yerdagi qiymat bilan almashtirildi. Footer esa tayyor natijani meros oldi. Tuzatish: hosila rangni ham footer'da qayta e'lon qiling yoki uni ishlatiladigan joyda hisoblang.

7.4 in yozilmagan yoki noto'g'ri

color-mix(oklch, ...) — in so'zi yo'q, deklaratsiya tashlanadi. Yuqorida in siz yozuv ishladi degan edik-ku? U yerda fazo nomi ham yo'q edi: color-mix(blue, yellow). Bu yerda esa fazo nomi bor, in yo'q — brauzer oklch so'zini rang deb o'qiydi va yozuvni noto'g'ri deb tashlaydi. Chrome'da tekshirdik. Tuzatish: color-mix(in oklch, ...).

7.5 color-scheme siz light-dark()

light-dark() yozildi, lekin color-scheme yo'q — qorong'i rejimda ham yorug' rang chiqadi. Tuzatish: :root { color-scheme: light dark; } yoki meta teg.

7.6 Oddiy zaxira var() bilan

Avval hex, keyin var() li yangi funksiya — eski brauzerda ikkalasi ham yo'qoladi (nisbiy ranglarning «Yangi imkoniyat va zaxira» qismi). Tuzatish: @supports.

8. Mashqlar

1-mashq (oson): Ulushlar

Har ifodada asosiy rangning ulushi necha foiz?

  • color-mix(in oklch, var(--rang-asosiy) 30%, white) —
  • color-mix(in oklch, white 30%, var(--rang-asosiy)) —
  • color-mix(in oklch, var(--rang-asosiy), black) —
Yechim
  • 30 — ulush aynan asosiy rang yonida.
  • 70 — 30% oqqa berilgan, asosiy rang qolganini oladi.
  • 50 — ulushlar yozilmagan, teng bo'linadi.

2-mashq (o'rta): Mashhur karta foni

Mashhur taom kartasiga (.taom-karta.mashhur) asosiy rangdan och fon bering. Karta ichida narx bor (.narx, urg'u rangi). Ikki usulni sinang va qaysi biri narx uchun kontrast talabiga javob berishini ayting:

  1. color-mix(in oklch, var(--rang-asosiy) 12%, var(--rang-fon))
  2. oklch(from var(--rang-asosiy) 0.95 0.025 h)

Ishora: nisbiy rangda sonlar o'rniga aniq qiymat ham yozsa bo'ladi. «Hosil qilingan ranglarning kontrasti» bo'limidagi jadvalga qarang.

Yechim
html
<style>
  :root {
    --rang-asosiy: oklch(47.5% 0.1 147.7);
    --rang-urgu: oklch(53.7% 0.153 39.8);
    --rang-fon: oklch(98.6% 0.014 84.6);
  }
  .taom-karta {
    padding: 4px 12px;
    font-family: system-ui, sans-serif;
  }
  .taom-karta.mashhur {
    background-color: oklch(
      from var(--rang-asosiy) 0.95 0.025 h
    );
  }
  .narx {
    color: var(--rang-urgu);
    font-weight: bold;
  }
</style>
<article class="taom-karta mashhur">
  <h3>Osh — eng mashhur</h3>
  <p><span class="narx">35 000 so'm</span></p>
</article>

Ikkinchi usul. Birinchisida fon sarg'ish chiqadi (in oklch dagi tus aylanishi — «Qaysi fazoda aralashtirish kerak» bo'limi), narx kontrasti esa 4.4:1 — talabdan past. Ikkinchisida tus asosiy rangdan olinadi, L va C aniq berilgan: fon och yashil, narx kontrasti 4.8:1.

--rang-asosiy o'zgarsa ham, ikkinchi usulda karta foni yangi rangning och tusiga o'zi o'tadi. Lekin L va C qat'iy bo'lgani uchun kontrast deyarli o'zgarmaydi.

«Bahor»ning qorong'i ranglari bo'limidagi natijaga (qorong'i footer) footer ichida .bron-havola qo'shing. Tugma yorug' qismda — yashil fon va qaymoq matn. Qorong'i footer'da esa och yashil fon va to'q matn bo'lsin. Hover — ikkala rejimda ham matndan "uzoqlashsin": yorug'da fon to'qlashsin, qorong'ida ochlashsin.

Ishora: tugma matni uchun var(--rang-fon) — u ikkala rejimda ham asosiy rangga qarama-qarshi. Hover uchun nisbiy rangda light-dark() ni calc ichida ishlatib bo'lmaydi, lekin butun rangni light-dark() ga o'rash mumkin.

Yechim
html
<style>
  :root {
    color-scheme: light dark;
    --rang-fon: light-dark(
      oklch(98.6% 0.014 84.6), oklch(28.2% 0.05 148.6));
    --rang-asosiy: light-dark(
      oklch(47.5% 0.1 147.7), oklch(80.3% 0.098 150.8));
  }
  body,
  footer {
    background-color: var(--rang-fon);
    font-family: system-ui, sans-serif;
  }
  .bron-havola {
    background-color: var(--rang-asosiy);
    color: var(--rang-fon);
    padding: 8px 16px;
  }
  .bron-havola:hover {
    background-color: light-dark(
      oklch(from var(--rang-asosiy) calc(l - 0.08) c h),
      oklch(from var(--rang-asosiy) calc(l + 0.08) c h)
    );
  }
  footer {
    color-scheme: dark;
    padding: 12px;
  }
</style>
<p><a class="bron-havola" href="bron/">Stolni band qilish</a></p>
<footer>
  <p><a class="bron-havola" href="bron/">Stolni band qilish</a></p>
</footer>
  • Tugmaning ikkala qoidasi bitta, ranglar rejimga qarab keladi. Qorong'i footer'da fon — och yashil (#8fd19e), matn — to'q yashil fon rangi: kontrast 8.0:1.
  • Hover light-dark() bilan ikki yo'nalishni tanlaydi: yorug'da l - 0.08, qorong'ida l + 0.08. Har ikki holatda fon matndan uzoqlashadi, kontrast oshadi. Hisobladik: yorug' hover 8.7:1, qorong'i hover 10.4:1.
  • Hover'ning ikkala qiymati ichida ham var() bor. Eski brauzer uchun zaxira — nisbiy ranglar va light-dark() bo'limlaridagi @supports.

4-mashq: Portfolio qadami — hosila ranglar

Portfolio palitrasida ikkita rang aslida brend rangining "suyultirilgani": chegara (#c9d6cf) va och fon (#e8f1ec). Ularni --rang-asosiy dan hisoblang — shunda brend rangini almashtirsangiz, ular ham o'zi moslashadi.

  1. --rang-fon-och — 8% asosiy + fon, --rang-chegara — 25% asosiy + fon. Portfolio foni deyarli kulrang (C 0.004), shuning uchun in oklch tus muammosini bermaydi.
  2. Asosiy menyu havolasiga hover qo'shing: sichqoncha ustida rang biroz to'qlashsin (l - 0.1). Mantiqiy pseudo-klasslar darsidagi a:not([aria-current="page"]):hover qoidasi faqat fon beradi va joyida qoladi — menyu uchun alohida qoida yozing, joriy sahifa havolasi bunga tushmasin.
  3. Ochiq savol-javob blokidagi matn kontrastini tekshiring: --rang-matn va --rang-asosiy yangi och fonda 4.5:1 dan yuqorimi?

Ishora: :root ichida bir o'zgaruvchi boshqasidan hisoblansa bo'ladi. Faqat «:root dagi hosila rang joyida yangilanmaydi» xatosini eslang — portfolio'da brend rangi hech qayerda qayta aniqlanmaydi, shuning uchun muammo yo'q.

Yechim
css
:root {
  --rang-matn: oklch(27.2% 0.019 161);
  --rang-fon: oklch(98.2% 0.004 157.2);
  --rang-asosiy: oklch(48.4% 0.097 158.9);
  --rang-ikkinchi: oklch(49.9% 0.016 162);
  /* brend rangidan hisoblanadi */
  --rang-chegara: color-mix(
    in oklch,
    var(--rang-asosiy) 25%,
    var(--rang-fon)
  );
  --rang-fon-och: color-mix(
    in oklch,
    var(--rang-asosiy) 8%,
    var(--rang-fon)
  );
}

header nav a:not([aria-current="page"]):hover {
  color: oklch(from var(--rang-asosiy) calc(l - 0.1) c h);
}

Natijani tekshiramiz:

html
<style>
  :root {
    --rang-matn: oklch(27.2% 0.019 161);
    --rang-fon: oklch(98.2% 0.004 157.2);
    --rang-asosiy: oklch(48.4% 0.097 158.9);
    --rang-chegara: color-mix(
      in oklch, var(--rang-asosiy) 25%, var(--rang-fon));
    --rang-fon-och: color-mix(
      in oklch, var(--rang-asosiy) 8%, var(--rang-fon));
  }
  body {
    font-family: system-ui, sans-serif;
    color: var(--rang-matn);
    background-color: var(--rang-fon);
  }
  h2 {
    color: var(--rang-asosiy);
  }
  details[name="savollar"] {
    border: 1px solid var(--rang-chegara);
    padding: 4px 12px;
  }
  details[name="savollar"][open] {
    background-color: var(--rang-fon-och);
  }
</style>
<h2>Ko'p so'raladigan savollar</h2>
<details name="savollar" open>
  <summary>Qancha vaqtda javob berasiz?</summary>
  <p>Odatda bir kun ichida.</p>
</details>
<details name="savollar">
  <summary>Buyurtma olasizmi?</summary>
  <p>Kichik HTML sahifalar uchun — ha.</p>
</details>
  • Hosila ranglar namunadagi hex'larga juda yaqin: och fon #e6eee9 (namuna #e8f1ec), chegara #c2d6c9 (namuna #c9d6cf).
  • 3-band: hisobladik — yangi och fonda --rang-matn 12.6:1, --rang-asosiy 5.2:1. Ikkalasi ham talabdan yuqori.
  • Menyu hover'i: to'qroq yashil fonda 8.9:1 beradi — asosiy rangdan ham yaxshiroq o'qiladi.
  • Hover'dagi nisbiy rang — yangi Baseline. Eski brauzerda color hisoblashda buziladi va havola otasining rangini oladi — o'qiladi, faqat hover effekti ko'rinmaydi. Portfolio uchun bu qabul qilsa bo'ladigan zaxira. Qat'iy zaxira kerak bo'lsa — nisbiy ranglar bo'limidagi @supports.
  • Tekshiring: --rang-asosiy ni vaqtincha boshqa rangga o'zgartiring (CSS o'zgaruvchilari 2 dagi Console usuli). Chegara va och fon ham yangi rang tomonga o'tadi.

9. Real ishda

  • Dizayn tizimlari endi "har rang — o'nlab hex" o'rniga bitta asosiy rang va formula saqlaydi. Hover, faol holat, chegara, shaffof soya — color-mix() va nisbiy ranglardan.
  • Tailwind v4 (kursda alohida o'rganamiz) rangga shaffoflik qo'shishni ichida color-mix() bilan qiladi — generatsiya qilingan CSS'da buni ko'rasiz.
  • Qorong'i rejim — color-scheme + light-dark() + o'zgaruvchilar. Eski usul — har rang uchun @media blokida qayta yozish (Qorong'i rejim).
  • Accessibility audit — hosila ranglar ham tekshiriladi. Dizayn tizimi "hover rangi avtomatik" desa, uning kontrasti ham avtomatik talabga javob berishini isbotlash kerak.
  • Intervyuda so'raladi: "color-mix qaysi fazoda aralashtiradi va nega bu muhim?", "light-dark() ishlashi uchun nima kerak?", "Yangi CSS funksiyasiga qanday zaxira yozasiz?".

Xulosa

  • color-mix(in fazo, A ulush, B) — aralashtirish; oq/qora bilan oklch, rangli fon bilan oklab qulay.
  • Nisbiy rang oklch(from X calc(l - 0.08) c h) — bitta sonni o'zgartirish; l — 0 dan 1 gacha son.
  • color-scheme — sahifa yoki element qaysi rejimlarni biladi; light-dark(A, B) — shunga qarab rang.
  • contrast-color() — faqat oq yoki qora; o'rta tusli fonda ehtiyot bo'ling.
  • Hosil bo'lgan har rangning kontrastini tekshiring — ayniqsa och fondagi eng zaif matnni.
  • Nisbiy rang, light-dark() va contrast-color() — yangi; var() bilan zaxira faqat @supports orqali.

Keyingi dars: Box model — sahifadagi har element to'rt qatlamli quti: kontent, padding, border va margin.

Manbalar

  • MDN: "color-mix()", "Using relative colors", "light-dark()", "color-scheme", "contrast-color()" — developer.mozilla.org
  • W3C: "CSS Color Module Level 5" (color-mix, relative color, light-dark, contrast-color) — w3.org/TR/css-color-5
  • W3C: "Web Content Accessibility Guidelines 2.2", 1.4.3 Contrast (Minimum) — w3.org/TR/WCAG22
  • web-features (Baseline ma'lumotlari): "color-mix", "relative-color", "light-dark", "contrast-color", "color-scheme" — github.com/web-platform-dx/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS color-mix() va nisbiy ranglar: hover, och fon va qorong'i rejim bitta rangdan — IlmHamroh