CSS Functions — calc(), min(), max(), clamp()
Muammodan boshlaylik
Kurs davomida bu funksiyalar bilan bir necha marta uchrashdik: calc() — CSS o'zgaruvchilari bilan (6-dars), min() — Grid da (22-dars), clamp() — tipografiyada (27-dars). Ular CSS ni "statik qiymatlar ro'yxati" dan hisoblaydigan tilga aylantiradi: birliklarni aralashtirish, chegaralar qo'yish, moslashuvchan qiymatlar.
Bu dars — to'rttasini bir joyda, real vazifalar bilan: qachon qaysi biri va qanday xatolardan qochish kerak.
calc() — turli birliklarni hisoblash
CSS ning asosiy muammosi: 100% va 64px ni oddiy usulda qo'shib bo'lmaydi — biri otaga bog'liq, ikkinchisi qat'iy. calc() buni brauzer hisoblashiga topshiradi, sahifa chizilayotgan paytda:
.main {
height: calc(100dvh - 64px); /* ekran balandligi minus header */
}
.sidebar-layout .content {
width: calc(100% - 280px - 2rem); /* foiz, piksel va rem aralash */
}
To'rt amal: +, -, *, /.
[!WARNING]
+va-atrofida bo'shliq majburiy:calc(100% - 64px)✅,calc(100%-64px)❌ (brauzer-64pxni manfiy son deb o'qiydi va butun qoida ishlamaydi).*va/uchun shart emas, lekin izchillik uchun hamma joyda qo'yish yaxshi.
O'zgaruvchilar bilan — eng kuchli kombinatsiya
:root {
--space: 8px;
--header-h: 64px;
}
.section {
padding: calc(var(--space) * 4); /* 32px */
scroll-margin-top: calc(var(--header-h) + 16px); /* anchor havola header ostiga kirmasin */
}
Birliksiz o'zgaruvchiga birlik berish (6-dars):
:root { --ustunlar: 3; }
.grid {
grid-template-columns: repeat(var(--ustunlar), 1fr);
gap: calc(var(--ustunlar) * 8px);
}
Qoidalar
- Ko'paytirishda bitta qiymat birliksiz bo'lishi kerak:
calc(2 * 8px)✅,calc(8px * 8px)❌ - Bo'lishda bo'luvchi — birliksiz son:
calc(100% / 3)✅,calc(100% / 3px)❌ - Ichma-ich qavslar mumkin:
calc((100% - 2rem) / 3)
min() — eng kichigi
min(A, B, ...) — ro'yxatdagi eng kichik qiymat. Amalda: "maksimal chegara".
.container {
width: min(1200px, 100% - 2rem);
}
- Keng ekranda:
1200pxkichikroq → 1200px - Telefonda (375px):
100% - 2rem= 343px kichikroq → 343px, chetlarda 1rem bo'shliq
Bitta qator — width + max-width + padding-inline uchligining o'rniga.
[!INFO]
min()vamax()ichidacalc()siz ham hisob yozish mumkin:min(1200px, 100% - 2rem). Funksiya ichidagi ifoda avtomatik hisoblanadi.
Yana:
img {
width: min(100%, 600px); /* kamida konteynerga sig'adi, ko'pi bilan 600px */
}
.grid {
grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); /* 22-dars */
}
max() — eng kattasi
max(A, B, ...) — eng katta qiymat. Amalda: "minimal chegara".
.sidebar {
width: max(240px, 20%); /* 20%, lekin kamida 240px */
}
.btn {
padding-inline: max(16px, 1em); /* kichik shriftda ham kamida 16px */
}
iPhone dagi "chiqib turgan" ekran (notch) uchun xavfsiz bo'shliq:
.header {
padding-left: max(16px, env(safe-area-inset-left));
padding-right: max(16px, env(safe-area-inset-right));
}
env(safe-area-inset-*) — qurilmaning kesilgan joylari o'lchami; max() — kamida 16px, kesik kattaroq bo'lsa — o'shancha.
min/max — chalkashlikka qarshi qoida
Nom teskari tuyuladi, shuning uchun:
min(...) → "bundan KATTA bo'lmasin" → max-width ning o'rni
max(...) → "bundan KICHIK bo'lmasin" → min-width ning o'rni
clamp() — ikki chegara orasida
clamp(MIN, AFZAL, MAX) = max(MIN, min(AFZAL, MAX)). 27-darsda batafsil ko'rdik:
h1 {
font-size: clamp(2rem, 1rem + 4vw, 4rem);
}
.section {
padding-block: clamp(3rem, 2rem + 5vw, 8rem);
}
.card {
width: clamp(280px, 50%, 480px); /* 50%, lekin 280–480px oralig'ida */
}
Uchala qiymatda birliklar aralash bo'lishi mumkin. Afzal qiymatda doim ekran yoki konteynerga bog'liq birlik (vw, %, cqi) bo'ladi — aks holda clamp ma'nosiz.
Qaysi biri qachon
| Vazifa | Funksiya | Misol |
|---|---|---|
| Turli birliklarni qo'shish/ayirish | calc() |
calc(100dvh - 64px) |
| O'zgaruvchidan hisoblash | calc() |
calc(var(--space) * 3) |
| Yuqori chegara ("bundan katta emas") | min() |
min(1200px, 100% - 2rem) |
| Pastki chegara ("bundan kichik emas") | max() |
max(240px, 20%) |
| Ikkala chegara + silliq o'zgarish | clamp() |
clamp(2rem, 1rem + 4vw, 4rem) |
Boshqa foydali funksiyalar
/* Ranglar — zamonaviy sintaksis */
color: rgb(37 99 235 / 0.8); /* shaffoflik bilan */
color: hsl(220 90% 50%);
background: color-mix(in srgb, var(--rang-asosiy) 15%, white); /* asosiy rangning och tusi */
/* Atribut qiymati */
a::after { content: " (" attr(href) ")"; }
/* Muhit */
padding-bottom: env(safe-area-inset-bottom);
/* Gradient lar */
background: linear-gradient(135deg, #2563eb, #7c3aed);
color-mix() — bitta asosiy rangdan hover, fon va chegara tuslarini hosil qilish uchun juda qulay (6-darsdagi o'zgaruvchilar bilan birga):
.btn {
background: var(--rang-asosiy);
}
.btn:hover {
background: color-mix(in srgb, var(--rang-asosiy) 85%, black); /* biroz to'qroq */
}
Nima uchun shunday?
Nima uchun bu hisob-kitoblar CSS ning o'zida — Sass yoki JavaScript bilan hisoblab qo'ysa bo'lmaydimi?
Chunki natija oldindan ma'lum emas. 100% - 64px qancha piksel? Bu foydalanuvchining ekraniga, oyna o'lchamiga, konteyner kengligiga bog'liq — va ular sahifa ochiq turganda ham o'zgaradi (oynani torayttirish, telefonni burish). Sass faqat kompilyatsiya paytida, hech narsani bilmasdan hisoblaydi: u 100% va 64px ni qo'sha olmaydi. JavaScript esa har bir o'zgarishni kuzatib, qayta hisoblashi kerak — sekin va murakkab. CSS funksiyalari esa hisobni brauzerga, layout paytiga topshiradi — o'sha lahzada hamma qiymatlar ma'lum, va har bir o'zgarishda avtomatik qayta hisoblanadi. Siz munosabatni yozasiz, brauzer har lahzada raqamni topadi.
Xulosa
Eslab qoling:
calc()— turli birliklarni hisoblash;+va-atrofida bo'shliq majburiycalc(var(--x) * 8px)— o'zgaruvchiga birlik berishmin(A, B)— eng kichigi = yuqori chegara:min(1200px, 100% - 2rem)max(A, B)— eng kattasi = pastki chegara:max(240px, 20%)clamp(MIN, AFZAL, MAX)— ikki chegara orasida silliqenv(safe-area-inset-*)— telefon kesiklari;color-mix()— rang tuslari- Hisob brauzerda, layout paytida — har qanday ekran va o'zgarishda to'g'ri
Keyingi dars
33-dars: BEM — Block Element Modifier metodologiyasi