CSS Functions — calc(), min(), max(), clamp()

~15 daq · CSS · Animatsiya va Ilg'or mavzular

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 -64px ni 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: 1200px kichikroq → 1200px
  • Telefonda (375px): 100% - 2rem = 343px kichikroq → 343px, chetlarda 1rem bo'shliq

Bitta qator — width + max-width + padding-inline uchligining o'rniga.

[!INFO] min() va max() ichida calc() 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 majburiy
  • calc(var(--x) * 8px) — o'zgaruvchiga birlik berish
  • min(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 silliq
  • env(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