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

CSS'da responsive rasmlar: image-set(), fon rasmlari va aspect-ratio

Qisqacha: <img> uchun faylni HTML tanlaydi (srcset, sizes, <picture>), lekin sizes dagi raqamlar CSS layout'dan olinadi: ustun min(100% - 2rem, 64rem) bo'lsa, sizes ham shuni aytishi kerak. Fon rasmi uchun HTML yo'q — uni CSS tanlaydi: image-set() ekran zichligi va format bo'yicha, @media esa ekran eni bo'yicha. Brauzer faqat mos kelgan fon rasmini yuklaydi. Fon rasmli bannerning o'z bo'yi yo'q — uni aspect-ratio beradi.

Bu darsda

  • sizes atributini CSS layout'dan qadamma-qadam hisoblaysiz va Chrome'da tekshirasiz.
  • Fon rasmini ekran zichligi, format va ekran eniga qarab image-set() va @media bilan almashtirasiz.
  • Qaysi fon rasmi qachon yuklanishini bilasiz — va <img> dan farqini.
  • Fon rasmli bannerga aspect-ratio bilan bo'y berasiz va uning tuzog'ini bilasiz.
  • Portfoliongizdagi rasmga to'g'ri srcset va sizes yozasiz.

Oldin bilishingiz kerak: Responsive rasmlar I: srcset va sizes, Responsive rasmlar II: picture, Fonlar, Rasm va media stili, Media queries.

1. Nega bu kerak?

HTML qismida rasmlarni ekranga moslashni o'rgangan edik. srcset va sizes darsida brauzerga bir nechta fayl berdik, picture darsida esa telefon uchun boshqa kadr. Lekin uchta savol ochiq qolgan edi:

  1. sizes ga qaysi raqamni yozish kerak? srcset va sizes darsida "sizes sahifaning haqiqiy joylashuviga mos bo'lishi kerak. Joylashuvni esa CSS belgilaydi" degan edik. "CSS tayyor bo'lgach, sizes ni aniqlashtirasiz" deb va'da ham bergan edik. CSS tayyor.
  2. Fon rasmi-chi? «Bahor» bosh sahifasidagi keng banner — fon rasmi. Unda srcset yo'q, telefon ham kompyuterdagi 2000 piksellik faylni yuklaydi.
  3. Bannerning bo'yi qayerdan keladi? <img> o'lchamini fayldan biladi, fon rasmi esa — yo'q. Matnsiz banner bo'yi nolga teng.

Uchala savolga javob — CSS'da. Xuddi choyxonadagi qozon kabi: mehmon soniga qarab kichik yoki katta qozon olinadi, lekin qancha mehmon kelishini oshpaz emas, zal ma'muri — layout — aytadi.

Vazifa <img> (HTML) Fon rasmi (CSS)
Zichlik (1x, 2x) srcset + x image-set() + x
Format (AVIF, WebP) <picture> + type image-set() + type()
Ekran eni srcset + sizes @media
Nisbat, sakrashsiz width/height aspect-ratio

2. sizes ni CSS'dan hisoblash

2.1 Muammo: brauzer CSS'ni kutmaydi

srcset va sizes darsidan eslang: brauzer rasm faylini sahifani chizishdan oldin tanlaydi. U CSS fayl yuklanishini kutmaydi, shuning uchun rasm qancha joy olishini bilmaydi. sizes — sizning brauzerga bergan "va'dangiz": "bu rasm ekranda shuncha enda chiqadi". Va'da CSS bilan mos kelmasa:

  • sizes katta bo'lsa — keragidan og'ir fayl yuklanadi, sekin internetda sahifa sekinlashadi.
  • sizes kichik bo'lsa — kichik fayl cho'ziladi, rasm xira ko'rinadi.

2.2 Qadamma-qadam: «Bahor» menyusi

Menyu sahifasida taom kartalari to'ri. CSS (Grid'ga kirish, Mobile-first):

css
main {
  display: grid;
  gap: 1rem;
  width: min(100% - 2rem, 64rem);
  margin-inline: auto;
}

@media (width >= 40rem) {
  main {
    grid-template-columns: 1fr 1fr;
  }
}

.taom-karta img {
  width: 100%;
}

body ning brauzer margin'i olib tashlangan (body { margin: 0; }). Kartadagi surat karta enini to'liq egallaydi. Endi surat enini har holat uchun topamiz:

Ekran Ustun eni Surat eni
40rem dan tor 100vw - 2rem 100vw - 2rem
40rem — 66rem 100vw - 2rem (100vw - 3rem) / 2 = 50vw - 1.5rem
66rem va keng 64rem (64rem - 1rem) / 2 = 31.5rem

Qayerdan keldi:

  • Ustun eni — min(100% - 2rem, 64rem). Ekran tor bo'lsa, birinchisi kichik: ekran minus 2rem. Ustun 64rem ga yetadigan chegara: 64rem + 2rem = 66rem ekran eni.
  • Ikki ustunda ustun eni ikkiga bo'linadi, lekin avval oradagi gap (1rem) ayiriladi: (100vw - 2rem - 1rem) / 2.

Endi jadvalni sizes ga ko'chiramiz. Tartib muhim: brauzer birinchi mos kelgan shartni oladi, shuning uchun eng keng ekran — birinchi:

html
<img src="../assets/images/osh-800.jpg"
     srcset="../assets/images/osh-400.jpg 400w,
             ../assets/images/osh-800.jpg 800w,
             ../assets/images/osh-1200.jpg 1200w"
     sizes="(width >= 66rem) 31.5rem,
            (width >= 40rem) calc(50vw - 1.5rem),
            calc(100vw - 2rem)"
     width="1200" height="900"
     alt="Bir tarelka Toshkent oshi, ustida bedana tuxumi">
  • Shartlar — @media dagi kabi, range sintaksisi bilan (Media queries). Chrome'da tekshirdik: sizes ichida ham ishlaydi.
  • calc() — Matematik funksiyalar darsidagi kabi. min() ni ham yozsa bo'ladi, lekin shartli ro'yxat odatda tushunarliroq.
  • Oxirgi qiymat shartsiz — "boshqa hamma holatda".

2.3 Chrome'da tekshirdik

Shu sahifani turli ekran va zichlikda ochib, suratning haqiqiy enini va brauzer tanlagan faylni o'lchadik:

Ekran Zichlik Surat eni Fayl
360 1x 328 osh-400
360 2x 328 osh-800
360 3x 328 osh-1200
768 1x 360 osh-400
1280 1x 504 osh-800
1280 2x 504 osh-1200

Nimaga qarang: "Surat eni" — DevTools o'lchagan haqiqiy en, va u har qatorda sizes va'dasiga teng («Qadamma-qadam» bo'limidagi jadvalni hisoblab ko'ring: 360 − 32 = 328, 768 ÷ 2 − 24 = 360, 31.5 × 16 = 504). Zichlik 2x bo'lsa, brauzer ikki barobar ko'p piksel kerak deb hisoblaydi: 360 enda 328 × 2 = 656 → eng yaqin katta fayl 800. Bu — srcset va sizes darsidagi "CSS piksel va qurilma pikseli" farqi.

Taqqoslash uchun, sizes ni olib tashladik va 1600 piksellik variant qo'shdik. Brauzer "rasm butun ekran enida" deb hisobladi va 1280 enli ekranda eng katta faylni — 1600 ni — yukladi. Haqiqatda esa surat 504 piksel.

2.4 Ikki nozik joy

  • sizes dagi rem sizning CSS'ingizga bo'ysunmaydi. Tekshirdik: html { font-size: 40px; } bo'lsa ham, sizes="30rem" 480 piksel (16 × 30) deb hisoblandi. Sabab o'sha — brauzer CSS'ni kutmaydi va brauzerning boshlang'ich shriftini oladi. html shriftini o'zgartirgan loyihada sizes ni pikselda yozing.
  • sizes="auto" — srcset va sizes darsida tilga olingan yangi qiymat. U faqat loading="lazy" rasmlarda ishlaydi: lazy rasm CSS tayyor bo'lgandan keyin yuklanadi, brauzer uning enini o'zi o'lchaydi. Baseline ma'lumotiga ko'ra u — juda yangi Baseline: hamma asosiy brauzerda faqat 2026-yil 14-sentabrdan (Chrome 126, Firefox 150, Safari 27). Eski brauzer uchun zaxira bilan yozing: sizes="auto, (width >= 40rem) 50vw, 100vw" — tushunmagan brauzer auto ni tashlab, qolganini o'qiydi.

2.5 O'zingiz tekshiring: DevTools

Elements panelida img ni toping va ustiga sichqonchani olib boring. Chiqqan oynada uch qator bor: Rendered size — sahifadagi haqiqiy o'lcham, Intrinsic size — fayl o'lchami, Current source — brauzer tanlagan fayl. Qurilma rejimida (Ctrl + Shift + M) ekran enini va zichlikni (DPR) o'zgartirib, uchalasini kuzating (Chrome DevTools I).

Bitta ogohlantirish. Chrome'da tekshirdik: 1280 enda osh-800 yuklangach, oynani 360 ga toraytirdik — brauzer osh-400 ga qaytmadi. Kattasi allaqachon yuklangan, kichigini qayta so'rashga hojat yo'q. Toza tekshiruv uchun sahifani yangi yorliqda, kerakli enda oching.

Tekshirib ko'ring: Blog maqolasidagi rasm main { width: min(100% - 2rem, 45rem); } ustunida to'liq enda turibdi, body margin'i 0. sizes ni yozing.

Javob

sizes="(width >= 47rem) 45rem, calc(100vw - 2rem)". Ustun 45rem ga yetadigan chegara — 45 + 2 = 47rem ekran. Undan tor ekranda rasm eni — ekran minus 2rem. Tartib: avval keng holat, oxirida shartsiz qiymat.

3. Fon rasmi: CSS o'zi tanlaydi

3.1 image-set() — eslatma

Fonlar darsida image-set() ni ko'rgan edik: bir nechta fayl, har biri yonida 1x yoki 2x, yoki type("image/avif"). Brauzer ekraniga mosini tanlab, faqat shuni yuklaydi. Ikkalasini birga ham yozsa bo'ladi:

css
header {
  background-color: #2f6b3a;
  background-image: image-set(
    "../images/banner-keng.avif" type("image/avif") 1x,
    "../images/banner-keng@2x.avif" type("image/avif") 2x,
    "../images/banner-keng.jpg" type("image/jpeg") 1x,
    "../images/banner-keng@2x.jpg" type("image/jpeg") 2x
  );
  background-size: cover;
}

Brauzer AVIF'ni bilsa — AVIF'lardan, bilmasa JPEG'lardan tanlaydi. Zichlik bo'yicha tanlovni o'z ko'zingiz bilan ko'ring — quyidagi fonning har varianti o'z nomini yozadi:

html
<style>
  p {
    padding: 2rem 1rem;
    font: bold 1.25rem system-ui, sans-serif;
    color: #fffaf0;
    background-color: #2f6b3a;
    background-image: image-set(
      url("data:image/svg+xml,<svg xmlns='http://www.w3.org/\
2000/svg' width='120' height='40'><text x='4' y='28' \
font-size='20' fill='%23d8ecd9'>1x fayl</text></svg>") 1x,
      url("data:image/svg+xml,<svg xmlns='http://www.w3.org/\
2000/svg' width='240' height='80'><text x='8' y='56' \
font-size='40' fill='%23f6d2c6'>2x fayl</text></svg>") 2x
    );
    background-position: right center;
    background-repeat: no-repeat;
  }
</style>
<p>«Bahor»</p>

Nimaga qarang: o'ng tomonda brauzer tanlagan fon yozuvi turibdi. Oddiy kompyuter ekranida — "1x fayl", telefonda va zich noutbuk ekranida — "2x fayl". Kod bitta — tanlovni ekran qiladi. Nomlar url() siz — image-set() ichida oddiy satr ham fayl manzili. Yo'l esa, Fonlar darsidagi kabi, CSS faylning o'ziga nisbatan (../images/). AVIF va WebP fayllarni img asoslari darsidagi Squoosh bilan tayyorlaysiz.

background-color — rasm yuklanmaguncha yoki umuman yuklanmasa, ustidagi matn o'qilsin deb (Fonlar darsidagi qoida).

Eski kodda -webkit-image-set() ni uchratasiz — Safari va Chrome'ning eski, prefiksli nomi. Baseline ma'lumotiga ko'ra image-set() 2023-yil sentabrdan Baseline, 2026-yil martdan esa keng tarqalgan — prefiks endi kerak emas.

3.2 Ekran eniga qarab: @media bilan boshqa kadr

image-set() zichlik va formatni tanlaydi, lekin ekran enini emas. Telefonda keng bannerni kichraytirsangiz, choyxona surati ingichka tasmaga aylanadi. picture darsidagi "art direction" — telefonga boshqa kadr — fon uchun @media bilan qilinadi:

css
/* Telefon: tik kadr */
header {
  background-image: image-set(
    "../images/banner-tik.jpg" 1x,
    "../images/banner-tik@2x.jpg" 2x
  );
}

/* 40rem dan: keng kadr */
@media (width >= 40rem) {
  header {
    background-image: image-set(
      "../images/banner-keng.jpg" 1x,
      "../images/banner-keng@2x.jpg" 2x
    );
  }
}

Mobile-first (Mobile-first): oddiy qoida — telefon uchun, @media — kattaroq ekran uchun.

3.3 Qaysi fayl yuklanadi? Chrome'da tekshirdik

Bu sahifani ochib, DevTools Network panelida qaysi rasmlar so'ralganini kuzatdik (DevTools II):

Ekran Zichlik Yuklangan fon fayli
360 1x faqat banner-tik.jpg
360 2x faqat banner-tik@2x.jpg
768 1x faqat banner-keng.jpg
1280 2x faqat banner-keng@2x.jpg

Har holatda — bitta fayl. Yutgan background-image qoidasigina yuklanadi, bekor bo'lganlari — yo'q. Telefon katta faylni umuman so'ramaydi.

Yana bir farqni tekshirdik. display: none elementning fon rasmi yuklanmadi. display: none berilgan <img> esa yuklandi. <img> HTML'da turgani uchun brauzer uni ko'rinish-ko'rinmasligidan qat'i nazar oladi. Fon rasmi esa element haqiqatda chizilganda so'raladi. Demak, "telefonda bu surat kerak emas" desangiz — fon rasmi bilan buni bepul olasiz. <img> uchun esa <picture> yoki loading="lazy" kerak (Rasm unumdorligi).

Ikki yo'lni yonma-yon ko'ring:

flowchart TD
  A["Brauzer HTML'ni o'qiydi"] --> B["img topildi"]
  B --> C["srcset + sizes bo'yicha<br/>fayl darhol yuklanadi"]
  A --> D["CSS fayl yuklanadi"]
  D --> E["Element chiziladimi?"]
  E -->|"ha"| F["Yutgan qoidadagi<br/>fon rasmi yuklanadi"]
  E -->|"display: none"| G["Fon rasmi<br/>yuklanmaydi"]

Nimaga qarang: <img> fayli CSS'ni kutmasdan tanlanadi — shuning uchun unga sizes kerak va display: none uni to'xtatmaydi. Fon rasmi esa CSS'dan keyin, faqat chiziladigan element uchun so'raladi.

3.4 Eski usul: resolution media

image-set() dan oldin zichlikni media query bilan tekshirishardi:

css
@media (resolution >= 2x) {
  header {
    background-image: url("../images/banner-keng@2x.jpg");
  }
}

resolution — ekranning zichligi. Birligi x yoki dppx ("bir CSS pikselga necha nuqta"), eski kodda dpi ham uchraydi. Baseline ma'lumotiga ko'ra resolution media query Baseline, 2025-yil martdan keng tarqalgan. Eski loyihalarda -webkit-min-device-pixel-ratio: 2 ni ham ko'rasiz — bu uning prefiksli ajdodi. Yangi kodda image-set() qulayroq: hamma variant bir joyda.

3.5 Muhim banner va LCP

Rasm unumdorligi darsidan eslang: ekrandagi eng katta element — LCP. Katta banner ko'pincha aynan LCP bo'ladi. Muammo: brauzer fon rasmini HTML'dan emas, CSS faylni yuklab o'qigandan keyin topadi (Fonlar darsida ko'rganimizdek). Muhim banner uchun Resurs maslahatlari darsidagi preload kerak. U ham zichlik va ekran enini biladi:

html
<link rel="preload" as="image"
      imagesrcset="assets/images/banner-keng.jpg 1x,
                   assets/images/banner-keng@2x.jpg 2x"
      media="(width >= 40rem)">

media va zichliklar CSS'dagi bilan bir xil bo'lsin. Aks holda brauzer bitta faylni oldindan, boshqasini CSS'dan yuklaydi — ikki barobar trafik.

Tekshirib ko'ring: Telefonda display: none bilan yashirilgan katta dekorativ surat bor. U <img> bo'lsa va fon rasmi bo'lsa — qaysi holatda telefon uni yuklaydi?

Javob

<img> bo'lsa — yuklaydi: brauzer HTML'dagi rasmni display ga qaramay oladi. Fon rasmi bo'lsa — yuklamaydi: element chizilmaydi, uning fon rasmi so'ralmaydi. Dekorativ surat uchun fon rasmi ham to'g'riroq tanlov (figure darsidagi test).

4. aspect-ratio: bannerga bo'y berish

4.1 Muammo: fon rasmi joy egallamaydi

<img> o'z o'lchamini fayldan va width/height atributlaridan oladi (Rasm va media). Fon rasmi esa elementning o'lchamiga hech qanday ta'sir qilmaydi. Bannerda matn bo'lmasa, uning bo'yi — 0, fon rasmi ko'rinmaydi. Matn bo'lsa — bo'y matnga teng: telefonda yuqori, kompyuterda past tasma.

Eski yechim — height: 300px. U O'lchamlar darsidagi qat'iy o'lcham muammosini qaytaradi. Yaxshi yechim — nisbat: aspect-ratio.

4.2 Har ekranga o'z nisbati

Kadrlar nisbati bilan bir xil nisbat beramiz: telefonda tik kadr 4:3, kattaroq ekranda keng kadr 3:1.

html
<style>
  body {
    margin: 0;
    font-family: system-ui, sans-serif;
  }
  header {
    aspect-ratio: 4 / 3;
    padding: 1rem;
    color: #fffaf0;
    background-color: #2f6b3a;
    background-image: url("data:image/svg+xml,<svg \
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'>\
<rect width='400' height='300' fill='%232f6b3a'/>\
<circle cx='200' cy='215' r='75' fill='%23b4461a'/>\
<text x='200' y='225' font-size='28' text-anchor='middle' \
fill='%23fffaf0'>tik kadr</text></svg>");
    background-size: cover;
    background-position: center bottom;
  }
  @media (width >= 40rem) {
    header {
      aspect-ratio: 3 / 1;
      background-image: url("data:image/svg+xml,<svg \
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 900 300'>\
<rect width='900' height='300' fill='%232f6b3a'/>\
<circle cx='650' cy='150' r='110' fill='%23b4461a'/>\
<text x='650' y='160' font-size='28' text-anchor='middle' \
fill='%23fffaf0'>keng kadr</text></svg>");
    }
  }
  header h1 {
    margin: 0;
  }
</style>
<header>
  <h1>Choyxona «Bahor»</h1>
  <p>Har kuni 7:00 dan 23:00 gacha ochiqmiz.</p>
</header>

Nimaga qarang: telefon enida banner tik, qizg'ish "qozon" pastda va markazda. Kompyuter enida banner keng tasma, qozon o'ngda — matn chapda bemalol turibdi. Bannerda height yo'q: bo'y endan hisoblanadi. Chrome'da o'lchadik: 360 enda 360 × 278, 1280 enda 1280 × 448. Nisbat padding ichidagi qutiga tegishli, 1rem li padding'lar ustiga qo'shildi (box-sizing bilan bu farq yo'qoladi). Surat o'rnida — data: SVG (Fonlar dagi kabi), real saytda image-set() bilan fayllar.

background-position: center bottom — kadrning qaysi qismi muhimligini aytadi: cover kesishi kerak bo'lsa, qozonni emas, osmonni kessin.

4.3 Tuzoq: matn ko'p bo'lsa

aspect-ratio — "afzal ko'rilgan" nisbat, qat'iy emas. Matn qutiga sig'masa, quti o'sadi. Chrome'da tekshirdik: 4:1 nisbatli 300 piksellik banner (bo'yi 75 bo'lishi kerak) ichiga sarlavha va paragraf qo'ydik — bo'yi 76.4 piksel bo'ldi. Bu yaxshi: foydalanuvchi shriftni kattalashtirsa, matn qirqilmaydi.

Lekin ikki holatda nisbat "g'olib" chiqadi va matn qirqiladi yoki tashqariga chiqadi:

  • Bannerga overflow: hidden bersangiz — tekshirdik, bo'y 75 da qoldi, matn kesildi.
  • height ham yozilgan bo'lsa — height yutadi, aspect-ratio e'tiborga olinmaydi.

Qoida: matnli bannerga overflow: hidden bermang. Eng kichik bo'y kerak bo'lsa — min-height. Tekshirdik: aspect-ratio: 4 / 1 va min-height: 6rem birga bo'lsa, katta qiymat — 96 piksel — yutadi.

4.4 <picture> bilan ham

picture darsida har source ga o'z width va height ini yozgan edik. Brauzer ulardan xuddi <img> dagi kabi aspect-ratio yasaydi — telefonda tik kadr, kompyuterda keng kadr uchun joy oldindan to'g'ri ajratiladi. CSS'dan faqat bittasi kerak: height: auto (Rasm va media reset'i). Usiz img dagi height atributi amal qiladi va kadr cho'ziladi.

Tekshirib ko'ring: Stajyor bannerga aspect-ratio: 16 / 9; height: 200px; yozdi. 1280 enli ekranda banner bo'yi qancha?

Javob

200 piksel. height berilgan bo'lsa, aspect-ratio hech narsa qilmaydi — ikkala o'lcham ham aniq. Nisbat ishlashi uchun o'lchamlardan bittasi auto bo'lishi kerak. height ni o'chiring — bo'y 1280 × 9 / 16 = 720 bo'ladi.

5. Ko'p uchraydigan xatolar

5.1 sizes shablondan ko'chirilgan

Internetdagi misoldan sizes="(max-width: 600px) 100vw, 50vw" olindi, sizning layout'ingiz esa boshqa. Rasm keragidan og'ir yoki xira. Tuzatish: «Qadamma-qadam» bo'limidagi kabi jadvalni o'z CSS'ingiz bo'yicha tuzing, DevTools'da haqiqiy enni o'lchab solishtiring.

5.2 Keng ekran oxirida

sizes="calc(100vw - 2rem), (width >= 40rem) 50vw" — birinchi qiymat shartsiz, brauzer har doim uni oladi. Tuzatish: shartli qiymatlar oldinda, shartsizi — oxirida.

5.3 Fon rasmi yo'li HTML'ga nisbatan

image-set("assets/images/banner.jpg" 1x) — CSS fayl ichida bu assets/css/assets/images/... bo'lib qoladi. Tuzatish: ../images/banner.jpg (Fonlar).

5.4 Banner bo'yi 0

Matnsiz fon rasmli blok ko'rinmaydi. Tuzatish: aspect-ratio yoki min-height.

5.5 aspect-ratio va height birga

Nisbat ishlamaydi. Tuzatish: height ni olib tashlang, eng kichik bo'y kerak bo'lsa — min-height.

5.6 Fon rasmi ustidagi matnda background-color yo'q

Rasm yuklanmaguncha oq matn oq fonda — o'qilmaydi. Tuzatish: rasm bilan bir xil tusli background-color bering.

6. Mashqlar

Mashqlarni kurs/mashqlar/05/ papkasida bajaring.

1-mashq (oson): Qaysi fayl?

srcset da 400w, 800w, 1200w, 1600w bor. sizes bo'yicha rasm eni 500 piksel. Brauzer qaysi faylni tanlaydi: (a) 1x ekranda, (b) 2x ekranda, (c) 3x ekranda?

Yechim

Brauzer kerakli piksellarni hisoblaydi: en × zichlik, keyin shundan kichik bo'lmagan eng yaqin faylni oladi.

  • (a) 500 × 1 = 500 → 800w.
  • (b) 500 × 2 = 1000 → 1200w.
  • (c) 500 × 3 = 1500 → 1600w.

«Chrome'da tekshirdik» jadvali ham shu qoidani ko'rsatdi. Brauzerlar juda zich ekranlarda biroz kichikroq faylni ham tanlashi mumkin — standart bunga ruxsat beradi.

2-mashq (o'rta): Uch ustunli menyu

«Qadamma-qadam» bo'limidagi menyuni kengaytiring: 64rem dan keng ekranda uch ustun, ustun eni min(100% - 2rem, 70rem), gap — 1rem. sizes ni yozing.

Ishora: uch ustunda oradagi ikkita gap ayiriladi. Ustun 70rem ga yetadigan ekran — 72rem.

Yechim
Ekran Surat eni
72rem va keng (70rem - 2rem) / 3 ≈ 22.7rem
64rem — 72rem (100vw - 2rem - 2rem) / 3 = 33.33vw - 1.33rem
40rem — 64rem 50vw - 1.5rem
40rem dan tor 100vw - 2rem
html
<img src="../assets/images/osh-800.jpg"
     srcset="../assets/images/osh-400.jpg 400w,
             ../assets/images/osh-800.jpg 800w,
             ../assets/images/osh-1200.jpg 1200w"
     sizes="(width >= 72rem) 22.7rem,
            (width >= 64rem) calc(33.33vw - 1.33rem),
            (width >= 40rem) calc(50vw - 1.5rem),
            calc(100vw - 2rem)"
     width="1200" height="900"
     alt="Bir tarelka Toshkent oshi, ustida bedana tuxumi">

Yaxlitlash bir-ikki piksel farq qilsa — muammo emas: sizes fayl tanlash uchun, rasm o'lchamini CSS baribir aniq beradi. Muhimi — va'da haqiqatdan ancha katta yoki kichik bo'lmasin.

3-mashq (qiyin): Bannerning to'rt xatosi

Stajyor assets/css/asosiy.css ga shunday yozdi:

css
header {
  height: 250px;
  aspect-ratio: 3 / 1;
  overflow: hidden;
  color: #fffaf0;
  background-image: image-set(
    "assets/images/banner-keng.jpg" 1x,
    "assets/images/banner-keng@2x.jpg" 2x
  );
}
@media (width >= 40rem) {
  header {
    background-image: url("../images/banner-tik.jpg");
  }
}

Telefonda banner qirqilgan, kompyuterda tor kadr, ba'zida umuman rasm yo'q. To'rtta xatoni toping.

Yechim
  1. height va aspect-ratio — height yutadi, nisbat ishlamaydi («Tuzoq: matn ko'p bo'lsa» bo'limi). height o'chiriladi.
  2. overflow: hidden — matn ko'paysa yoki shrift kattalashsa, kesiladi. O'chiriladi.
  3. Yo'l — CSS fayldan assets/... noto'g'ri, ../images/... kerak. Rasm umuman chiqmasligi shundan.
  4. Kadrlar almashgan — mobile-first'da oddiy qoida telefon uchun (tik), @media — keng ekran uchun (keng). Bu yerda teskari. Yana background-color yo'q — rasm kelguncha qaymoq matn o'qilmaydi.
css
header {
  aspect-ratio: 4 / 3;
  color: #fffaf0;
  background-color: #2f6b3a;
  background-image: image-set(
    "../images/banner-tik.jpg" 1x,
    "../images/banner-tik@2x.jpg" 2x
  );
  background-size: cover;
}
@media (width >= 40rem) {
  header {
    aspect-ratio: 3 / 1;
    background-image: image-set(
      "../images/banner-keng.jpg" 1x,
      "../images/banner-keng@2x.jpg" 2x
    );
  }
}

4-mashq: Portfolio qadami — rasmga srcset va sizes

Portfoliongizning bosh sahifasidagi rasm (ish-joyi.jpg, 480×320) hozircha bitta fayl. Zich telefon ekranida u xira: 2x ekranga 480 piksel kam. srcset va sizes darsida va'da qilgandik — CSS tayyor bo'lgach sizes ni aniqlashtiramiz.

  1. Squoosh bilan rasmning 960 piksellik nusxasini tayyorlang: assets/images/ish-joyi-960.jpg.
  2. img ga srcset (480w va 960w) qo'shing.
  3. sizes ni o'z CSS'ingizdan hisoblang. Eslatma: main ustuni — min(100% - 2rem, 70ch) (Matematik funksiyalar), rasm — max-width: 100% (Rasm va media) va 480 pikseldan kattalashmaydi. body margin'i Flex naqshlari darsidan beri 0.
  4. DevTools'da tekshiring: 360 enda ustun va rasm necha piksel? Network'da qaysi fayl yuklandi?

Ishora: 70ch ni DevTools'da o'lchang — u 480 dan kengmi? Agar kengroq bo'lsa, rasm 480 da to'xtaydi va ustun eni sizes uchun ahamiyatsiz bo'lib qoladi.

Yechim

Hisob:

  • Ustun: 100% - 2rem, bu yerda 100% — body eni, margin'siz — 100vw. Demak ustun 100vw - 2rem.
  • Chrome'da o'lchadik (Windows, system-ui — Segoe UI): 70ch = 603.75 piksel — 480 dan keng. Demak kengroq ekranda rasmni ustun emas, uning o'zi — 480 — cheklaydi.
  • Rasm 480 ga yetadigan ekran: 480 + 32 = 512 piksel = 32rem.
html
<img src="assets/images/ish-joyi.jpg"
     srcset="assets/images/ish-joyi.jpg 480w,
             assets/images/ish-joyi-960.jpg 960w"
     sizes="(width >= 32rem) 480px, calc(100vw - 2rem)"
     alt="Noutbukda ochiq turgan HTML kod"
     width="480" height="320" fetchpriority="high">

Chrome'da tekshirdik: 360 enda sizes 328 piksel va'da qiladi. 1x ekranda 480 piksellik fayl yuklandi, 2x ekranda — 960 (328 × 2 = 656). 1280 enda 1x — 480, 2x — yana 960. Oddiy src esa srcset ni bilmaydigan juda eski brauzer uchun.

width va height atributlari o'zgarmaydi — ular faylning emas, nisbatning va'dasi (3:2). HTML'ga faqat ikki atribut qo'shildi — portfolio loyihasi darsidagi "HTML deyarli o'zgarmaydi" va'dasi saqlandi.

Bosh sahifada rasm hozir ustundan torroq. Telefonda uni Normal oqim darsidagi float 45 foizga siqadi. 40rem dan esa u grid-template-areas darsidagi rasm ustunida. sizes kattaroq va'da qilsa, brauzer keragidan kattaroq faylni oladi — rasm xira bo'lmaydi, faqat trafik ortadi. Layout'ni yakuniy loyihada yig'ib bo'lgach, sizes ni shu usul bilan qayta hisoblaymiz. sizes va CSS doim birga o'zgaradi.

7. Real ishda

  • Rasm CDN'lari (Cloudinary, imgix va boshqalar — kursda keyinroq) URL parametri bilan istalgan o'lchamni yasab beradi. srcset ni ular to'ldiradi, sizes esa baribir sizning ishingiz — CDN layout'ingizni bilmaydi.
  • Freymvorklar — masalan, Next.js'ning rasm komponenti (kursda alohida o'rganamiz) — srcset ni avtomatik yasaydi, lekin sizes ni sizdan so'raydi. Noto'g'ri sizes — Lighthouse'dagi "Properly size images" ogohlantirishining eng keng tarqalgan sababi.
  • Landing sahifalar deyarli doim katta banner bilan boshlanadi: image-set(), telefon uchun alohida kadr, aspect-ratio va preload.
  • Intervyuda so'raladi: "sizes nima uchun kerak va uni qanday hisoblaysiz?", "Fon rasmini ekranga qarab qanday almashtirasiz?", "display: none rasm yuklanadimi?".

Xulosa

  • sizes — brauzerga rasm eni haqidagi va'da; raqamlar CSS layout'dan olinadi, tartib — keng ekrandan torga.
  • sizes dagi rem doim 16 piksel hisoblanadi — sizning html shriftingizdan emas.
  • Fon rasmi: image-set() — zichlik va format, @media — ekran eni; faqat yutgan qoidaning fayli yuklanadi.
  • display: none elementning fon rasmi yuklanmaydi, <img> esa yuklanadi.
  • Fon rasmli banner bo'yini aspect-ratio beradi; height va overflow: hidden bilan birga ishlatmang.

Keyingi dars: Foydalanuvchi afzalliklari va qurilma media'lari — CSS'ni foydalanuvchining qorong'i rejimi, kamroq harakat, yuqori kontrast, sensorli ekran va chop etishga moslaymiz.

Manbalar

  • MDN: "Responsive images", "image-set()", "aspect-ratio", "resolution" (media feature), "sizes" (img atributi) — developer.mozilla.org
  • HTML Standard: "Images" (srcset va sizes tanlash algoritmi) — html.spec.whatwg.org
  • web-features (Baseline ma'lumotlari): "image-set", "aspect-ratio", "resolution", "sizes-auto" — github.com/web-platform-dx/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS'da responsive rasmlar: image-set(), fon rasmlari va aspect-ratio — IlmHamroh