IlmHamroh
JavaScript Full-stack/5-qism. CSS asoslari va layout62/63-dars18 daqiqa
Mundarija (36)

Mobil CSS tuzoqlari: notch, ekran klaviaturasi va sensorli ekran

Qisqacha: Telefon kompyuterdan kichik ekran bilangina farq qilmaydi. iPhone'ning "burni" va yumaloq burchaklari kontentni yopmasligi uchun viewport-fit=cover va env(safe-area-inset-bottom) ishlatiladi. Forma maydonida shrift 16 pikseldan kichik bo'lsa, iPhone'dagi Safari sahifani kattalashtirib yuboradi — yechim font-size: 1rem. Sensorli ekranda :hover bosilgandan keyin "yopishib" qoladi — hover'ni @media (hover: hover) ichiga oling. Ekran klaviaturasi ochilganda brauzerlar sahifani qisqartirmaydi, faqat ko'rinadigan qismini; kerak bo'lsa interactive-widget=resizes-content. Bularning ko'pini faqat haqiqiy telefonda ko'rasiz.

Bu darsda

  • Kompyuterdagi emulyatsiya qaysi tuzoqlarni ko'rsatadi va qaysilarini ko'rsatmasligini bilasiz.
  • "Burun" va yumaloq burchaklar uchun xavfsiz chegara (env()) yozasiz.
  • iPhone'da forma maydoni bosilganda sahifa nega kattalashishini tushuntirib, uni to'g'ri yo'l bilan tuzatasiz.
  • touch-action, -webkit-tap-highlight-color va -webkit-text-size-adjust nima qilishini bilasiz.
  • Yopishib qoladigan hover va ekran klaviaturasi muammolarini hal qilasiz.

Oldin bilishingiz kerak: Viewport birliklari va mobil "100vh" muammosi, Foydalanuvchi afzalliklari, head anatomiyasi va viewport, O'lchamlar, fixed va sticky.

1. Nega bu kerak?

Siz «Bahor» saytini kompyuterda DevTools qurilma rejimida (Chrome DevTools I) telefon eniga moslab tekshirdingiz. Hammasi joyida. Keyin Jasur aka saytni o'z iPhone'ida ochdi va to'rtta shikoyat bilan qo'ng'iroq qildi:

  1. Pastdagi "Stolni band qilish" tugmasi telefon pastidagi chiziqqa tegib turibdi, bosish noqulay.
  2. Bron formasida ism maydonini bossa, butun sahifa kattalashib ketadi va qaytmaydi.
  3. Menyuda taomni bossa, u yashil bo'lib qoladi — boshqa joyni bosmaguncha.
  4. Telefon raqamini yozayotganda "Yuborish" tugmasi klaviatura ortida qolib ketadi.

Viewport birliklari darsida bir qoidani aytgan edik: qurilma rejimi manzil panelini chizmaydi, svh va dvh farqini faqat haqiqiy telefonda ko'rasiz. Bu dars — shu qoidaning kengaytmasi. Emulyator — mashina haydashni o'yinda o'rganish kabi. Rul va pedallar joyida, lekin chuqur yo'l va yomg'irni faqat haqiqiy ko'chada sezasiz.

Darsda har bir tuzoq uchun aytib boramiz: nimani Chrome'da o'zimiz tekshirdik, nima esa brauzer ishlab chiqaruvchilarining hujjatlaridan (MDN, WebKit, Chrome blogi). Oxirida umumiy jadval bor.

2. "Burun" va yumaloq burchaklar: xavfsiz hudud

2.1 Muammo

Zamonaviy telefonlar ekranining hammasi to'rtburchak emas. Tepada kamera va datchiklar uchun o'yiq — "burun" (notch) yoki "orolcha", burchaklar yumaloq, pastda esa ilovalar orasida o'tish uchun uy chizig'i (home indicator). Ekranning bu qismlari kontent uchun "xavfli". Ulardan tashqari qism — xavfsiz hudud (safe area).

WebKit jamoasining "Designing Websites for iPhone X" maqolasiga ko'ra, Safari standart holatda sahifani o'zi xavfsiz hudud ichiga siqadi. Telefon yotiq holatda bo'lsa, chap va o'ng chetda bo'sh "hoshiya" qoladi. U sahifaning fon rangi bilan to'ldiriladi. Ya'ni standart holatda xavf yo'q, faqat joy isrof bo'ladi.

2.2 viewport-fit=cover va env()

head anatomiyasi darsidagi jadvalda viewport-fit=cover ni ko'rgan edik: "sahifa ekranning burun va yumaloq burchaklari ostigacha chiziladi. CSS bilan xavfsiz chegaralar qo'shiladi". Mana o'sha CSS.

Avval HTML'da ruxsat:

html
<meta name="viewport"
      content="width=device-width, initial-scale=1,
               viewport-fit=cover">

Endi sahifa butun ekranga cho'ziladi va xavfli joylarni o'zingiz chetlab o'tishingiz kerak. Buning uchun brauzer to'rtta qiymat beradi:

css
.bron-havola {
  padding-bottom: env(safe-area-inset-bottom);
}

env() — muhit o'zgaruvchisi (environment variable): brauzer yoki qurilma beradigan qiymat. U var() ga o'xshaydi, lekin qiymatni siz emas, qurilma yozadi. safe-area-inset-top, -right, -bottom, -left — xavfsiz hudud chetidan ekran chetigacha masofa.

Baseline ma'lumotiga ko'ra env() va safe-area qiymatlari — Baseline, 2022-yildan keng tarqalgan. MDN ma'lumotiga ko'ra, viewport-fit ni iPhone'dagi Safari 11 dan, Android'dagi Chrome esa faqat 135 dan qo'llaydi.

2.3 max() bilan: kamida odatiy bo'sh joy

Oddiy telefonda yoki kompyuterda env(safe-area-inset-bottom) — nol. Chrome'da tekshirdik: kompyuterda ham, DevTools'ning iPhone emulyatsiyasida ham to'rttala qiymat 0 piksel. Demak padding-bottom: env(...) tugma ichidagi bo'sh joyni butunlay yo'qotadi. WebKit maslahati — Matematik funksiyalar darsidagi max():

html
<style>
  body {
    margin: 0;
    padding-bottom: 5rem;
    font-family: system-ui, sans-serif;
  }
  main {
    padding: 0 1rem;
  }
  footer {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    padding: 0.75rem 1rem;
    padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
    background-color: #fffaf0;
    border-top: 1px solid #c9d6cf;
  }
  .bron-havola {
    display: block;
    padding: 0.75rem;
    border-radius: 0.5rem;
    background-color: #2f6b3a;
    color: #fffaf0;
    text-align: center;
    text-decoration: none;
  }
</style>
<main>
  <h1>Menyu</h1>
  <p>Osh — 35 000 so'm</p>
  <p>Lag'mon — 28 000 so'm</p>
</main>
<footer>
  <a class="bron-havola" href="bron/">Stolni band qilish</a>
</footer>

Nimaga qarang: pastga yopishgan panel (fixed va sticky), ichida "Stolni band qilish" tugmasi. Kompyuterda panel ostida 0.75rem bo'sh joy. viewport-fit=cover li iPhone'da esa uy chizig'i balandligi — shundan kattasi. body dagi padding-bottom — oxirgi taom panel ostida qolib ketmasin deb.

Uch nozik joy:

  • Zaxira qiymat. env(safe-area-inset-bottom, 20px) — vergul bilan ikkinchi qiymat. Chrome'da tekshirdik: brauzer bu o'zgaruvchini bilsa, zaxira ishlamaydi — kompyuterda natija 0, 20 emas. Zaxira faqat noma'lum nomda ishladi. Shuning uchun max() — to'g'ri vosita, zaxira emas.
  • Faqat fixed va chetga tegadigan elementlarga. Oddiy oqimdagi matn sahifa bilan aylanadi — uni xavfli joyga tushirishni sahifa o'zi hal qiladi. Muammo — ekran chetiga yopishgan panel, menyu, tugma.
  • Yotiq holatda chap va o'ngga ham: padding-inline: max(1rem, env(safe-area-inset-left)). Chap va o'ng qiymatlar har xil bo'lishi mumkin — "burun" faqat bir tomonda.

Tekshirib ko'ring: viewport-fit=cover yozilmagan. iPhone'da env(safe-area-inset-bottom) necha bo'ladi?

Javob

WebKit maqolasiga ko'ra, cover bo'lmasa Safari sahifani o'zi xavfsiz hudud ichiga joylaydi. Sahifa chetlari xavfli joyga yetmaydi, shuning uchun qo'shimcha chegara kerak emas. env() qiymatlari esa aynan cover bilan ma'noga ega bo'ladi. Haqiqiy qiymatni DevTools emas, faqat telefon ko'rsatadi: biz tekshirgan Chrome emulyatsiyasida u doim 0 edi.

3. iOS forma zoom'i: 16 pikseldan kichik shrift

3.1 Muammo va nega

head anatomiyasi darsida va'da bergan edik: "iPhone'da mayda shriftli maydon bosilganda Safari sahifani avtomatik kattalashtiradi. Buning to'g'ri yechimi — maydon shriftini kamida 16 piksel qilish. Bu CSS ishi." O'sha darsda bu yechimni keyinroq, forma stili darsida berishni aytgan edik — mazmunan u mobil tuzoqlarga tegishli, shuning uchun hozir, shu yerda beramiz.

iPhone'dagi Safari foydalanuvchi mayda matnni yozayotganda uni ko'rsin deb o'ylaydi: maydon shrifti 16 pikseldan kichik bo'lsa, fokusda sahifani o'sha maydonga kattalashtiradi. Maydondan chiqqanda esa sahifa kattalashgan holicha qoladi — Jasur akaning ikkinchi shikoyati.

Halol aytamiz: bu xatti-harakat Apple'ning rasmiy hujjatlarida qoida sifatida yozilmagan. U Safari'ning uzoq yillik xulqi, va 16 piksel chegarasi amaliyotda keng ma'lum. Biz uni kompyuterda tekshira olmadik — Chrome ham, uning iPhone emulyatsiyasi ham zoom qilmaydi. Haqiqiy iPhone'da sinab ko'ring.

3.2 Nega forma kichik bo'lib qoladi

Forma maydonlari sahifa shriftini meros olmaydi. Chrome'da o'lchadik: input, select, textarea va button — hammasi 13.33 piksel, body shrifti 16 bo'lsa ham. Shrift oilasi ham boshqa: input da Arial, textarea da monospace. Boshqa brauzerlarning, jumladan iPhone Safari'ning boshlang'ich qiymatlari boshqacha bo'lishi mumkin — bunga tayanmang, o'lchamni o'zingiz bering.

3.3 Yechim

css
input,
select,
textarea,
button {
  font: inherit;
}

font — shriftning qisqa yozuvi (Shrift asoslari), inherit esa Meros darsidagi kalit so'z: "otangdan ol". Endi maydon sahifa matni bilan bir xil — «Bahor»da body 1rem, ya'ni 16 piksel. Zoom sababi yo'qoladi, forma sahifa bilan bir uslubda bo'ladi.

html
<style>
  body {
    font-family: system-ui, sans-serif;
  }
  input {
    display: block;
    margin-bottom: 0.75rem;
  }
  .kichik {
    font-size: 14px;
  }
  .togri {
    font: inherit;
  }
</style>
<label for="ism1">❌ Ism (14px — iPhone zoom qiladi)</label>
<input id="ism1" class="kichik" value="Ali">
<label for="ism2">✅ Ism (sahifa shrifti — 16px)</label>
<input id="ism2" class="togri" value="Ali">

Nimaga qarang: pastki maydon kattaroq va sahifa matni bilan bir xil shriftda. Kompyuterda ikkalasi ham oddiy ishlaydi. Telefoningizda ochib, ikkala maydonni navbat bilan bosing — iPhone'da faqat birinchisi sahifani kattalashtiradi. kichik va togri — faqat shu namoyish uchun nomlar.

Diqqat: Zoom'ni maximum-scale=1 yoki user-scalable=no bilan o'chirmang. head anatomiyasi darsidagi qoida: bu ko'zi zaif odamdan kattalashtirish imkonini oladi, Lighthouse uni xato deb belgilaydi. Muammoni foydalanuvchini emas, shriftni o'zgartirib hal qilamiz.

4. Barmoq bilan ishlash

4.1 Yopishib qoladigan hover

Holat pseudo-klasslari darsida "barmoq tekkanda brauzer :hover ni qisqa yoqadi, ba'zan esa u yopishib qoladi" degan edik. Mexanizm shunday. Eski saytlar faqat sichqoncha uchun yozilgan edi, shuning uchun sensorli brauzerlar tegishni sichqonchaga "tarjima" qiladi:

flowchart TD
  A["Barmoq kartaga tegdi"] --> B["Brauzer: kursor<br/>shu yerga keldi"]
  B --> C[":hover yoqildi —<br/>karta yashil"]
  C --> D["Barmoq ko'tarildi,<br/>kursor esa qoldi"]
  D --> E["Boshqa joyga tegmaguncha<br/>karta yashil"]

Nimaga qarang: barmoq ketdi, lekin "xayoliy kursor" joyida qoldi — shuning uchun hover ham o'chmaydi. Jasur akaning uchinchi shikoyati shu.

Yechim Foydalanuvchi afzalliklari darsidan: hover'ni faqat hover qila oladigan qurilmaga beramiz. Telefonda bosishga javobni :active beradi:

html
<style>
  body {
    font-family: system-ui, sans-serif;
  }
  .taom-karta {
    display: block;
    max-width: 16rem;
    margin-bottom: 0.75rem;
    padding: 0.5rem 1rem;
    border: 2px solid #2f6b3a;
    color: inherit;
    text-decoration: none;
  }
  @media (hover: hover) {
    .taom-karta:hover {
      background-color: #d8ecd9;
    }
  }
  .taom-karta:active {
    background-color: #b9dcbc;
  }
</style>
<a class="taom-karta" href="menyu/">Osh — 35 000 so'm</a>
<a class="taom-karta" href="menyu/">Manti — 30 000 so'm</a>

Nimaga qarang: kompyuterda karta ustiga kelganda och yashil fon chiqadi, bosganda — to'qroq. Telefonda esa karta faqat barmoq tekkan paytda to'qlashadi va barmoq ko'tarilishi bilan asl holiga qaytadi — hech narsa yopishmaydi. Namoyish uchun kartani havola qildik; real menyuda karta article, bosiladigan joyi esa uning ichidagi havola.

4.2 -webkit-tap-highlight-color

Telefonda havolani bossangiz, uning ustida qisqa rangli dog' paydo bo'ladi — brauzerning "bosildi" belgisi. Chrome'da o'lchadik: kompyuterda uning qiymati rgba(0, 0, 0, 0.18) (xira kulrang), telefon emulyatsiyasida — rgba(51, 181, 229, 0.4) (havorang).

css
.bron-havola {
  -webkit-tap-highlight-color: transparent;
}
.bron-havola:active {
  background-color: var(--rang-asosiy-toq);
}

Dog'ni olib tashlash mumkin — lekin faqat o'rniga o'z :active holatingizni bersangiz. Aks holda Jasur aka tugmani bosdimi-yo'qmi, bilmaydi. Bu xususiyat standart emas: MDN ma'lumotiga ko'ra u Chrome, Edge va iPhone Safari'da bor, Firefox'da yo'q. Baseline ma'lumotlarida umuman yo'q — Baseline'dan tashqarida. Tushunmagan brauzer uni tashlab ketadi, zarari yo'q.

4.3 touch-action: barmoq harakatini kim boshqaradi

Barmoq bilan sahifada ko'p ish qilinadi: aylantirish, ikki barmoq bilan kattalashtirish, ikki marta tegib kattalashtirish. touch-action shu harakatlardan qaysilarini brauzer o'zi bajarishini aytadi:

Qiymat Brauzer nimani qiladi
auto Hammasini (boshlang'ich qiymat)
manipulation Aylantirish va kattalashtirish, ikki marta tegish — yo'q
pan-y Faqat vertikal aylantirish
none Hech narsa — harakatni sahifaning o'zi boshqaradi
  • manipulation — tez-tez bosiladigan tugmalarda (sanagich, kalkulyator): ikki marta tez bosish sahifani kattalashtirib yubormaydi. MDN yozishicha, tarixan u bosishdagi taxminan 300 millisekundlik kutishni ham olib tashlardi. Zamonaviy brauzerlar width=device-width li sahifada bu kutishni allaqachon olib tashlagan.
  • pan-y — gorizontal suriladigan karusel. Vertikal harakatni brauzer bajaradi (sahifa aylanadi), gorizontalini — karusel skripti.
  • none — rasm chizish maydoni yoki interaktiv xarita. Ehtiyot bo'ling: bu elementda sahifani aylantirib ham, kattalashtirib ham bo'lmaydi. Butun ekranni egallagan touch-action: none — foydalanuvchini qamab qo'yadi.

Baseline ma'lumotiga ko'ra touch-action — Baseline, 2022-yildan keng tarqalgan. Uni DevTools'da to'liq sinab bo'lmaydi: sichqoncha bilan qilingan "teginish" ikki barmoqli harakatni bermaydi.

5. Ekran klaviaturasi

5.1 Klaviatura ochilganda nima bo'ladi

Viewport birliklari darsida "klaviatura ochilganda viewport yana o'zgaradi — buni keyinroq ko'ramiz" degan edik. Chrome blogidagi "Prepare for viewport resize behavior changes" maqolasiga ko'ra, bugun ikkala asosiy mobil brauzer bir xil ishlaydi:

  • Sahifaning o'lchami o'zgarmaydi. Klaviatura faqat ko'rinadigan qismni kichraytiradi — sahifaning pastki qismi uning ortida qoladi.
  • Viewport birliklari o'zgarmaydi. 100dvh ham klaviatura ochilganda qisqarmaydi.
  • position: fixed elementlar joyida qoladi va klaviatura ularni yopishi mumkin.

iPhone'dagi Safari shunday ishlaydi, Android'dagi Chrome esa 108-versiyadan (2022-yil noyabr) shunga o'tdi. Jasur akaning to'rtinchi shikoyati aynan shu: pastga yopishgan tugma klaviatura ortida.

head anatomiyasi darsidagi viewport jadvalida bu xulqni o'zgartiradigan qiymat bor edi — interactive-widget:

Qiymat Klaviatura ochilganda
resizes-visual Faqat ko'rinadigan qism kichrayadi (standart)
resizes-content Sahifa ham qisqaradi, dvh ham
overlays-content Hech narsa kichraymaydi, klaviatura ustidan chiqadi
html
<meta name="viewport"
      content="width=device-width, initial-scale=1,
               interactive-widget=resizes-content">

resizes-content bilan chat oynasi kabi height: 100dvh li interfeys klaviatura ustiga siqiladi — pastdagi yozish maydoni va "Yuborish" tugmasi ko'rinib turadi.

5.2 Qo'llab-quvvatlash — halol holat

MDN ma'lumotlariga ko'ra, interactive-widget Android'dagi Chrome 108 va Firefox 133 da bor. iPhone Safari'da yo'q: u baribir faqat ko'rinadigan qismni kichraytiradi. Bu imkoniyat Baseline ma'lumotlarida alohida yozilmagan — bitta mobil brauzer yetishmagani uchun uni Baseline deb bo'lmaydi.

Shuning uchun «Bahor» uchun eng ishonchli yechim — tuzilmaning o'zi:

  • Muhim tugmani fixed panelga emas, forma oxiriga qo'ying. Oddiy oqimdagi tugma sahifa bilan aylanadi — mehmon klaviatura ochiqligida ham unga yetib boradi.
  • Klaviatura ochilganda keraksiz fixed panelni yashirmoqchi bo'lsangiz — bu JavaScript ishi. Chrome'da buning uchun alohida VirtualKeyboard API bor. U env(keyboard-inset-height) ni beradi, lekin Baseline ma'lumotiga ko'ra Baseline emas — faqat Chrome va Edge'da. JavaScript'ni kursda keyinroq o'rganamiz, hozir bilish shart emas.

Tekshirib ko'ring: Chat sahifasi height: 100dvh va pastda yozish maydoni. iPhone'da klaviatura ochilganda yozish maydoni ko'rinadimi? interactive-widget=resizes-content yordam beradimi?

Javob

Ko'rinmasligi mumkin. Klaviatura sahifani qisqartirmaydi, faqat ko'rinadigan qismni — 100dvh o'zgarmaydi va pastki qism klaviatura ortida qoladi. Brauzer fokusdagi maydonni ko'rinadigan joyga siljitishga harakat qiladi, lekin tartib buziladi. interactive-widget=resizes-content Android'da yordam beradi, iPhone Safari esa uni qo'llamaydi. Shuning uchun haqiqiy iPhone'da sinash shart.

6. Matn o'lchami va skroll "sakrashlari"

6.1 -webkit-text-size-adjust

Mobil brauzerlarda matnni avtomatik kattalashtirish (text inflation) algoritmi bor. MDN tushuntirishicha, u telefon uchun moslanmagan, kompyuter kengligida chizilgan sahifalardagi mayda matnni o'qiladigan qiladi. Sizning sahifangiz esa viewport meta bilan telefonga moslangan — bu "yordam" kerak emas. U ba'zan kutilmagan joyda ishlaydi: iPhone'da ekran yotiq holatga burilganda shrift kattalashib ketadi.

Buni reset fayllar hal qiladi — brauzerlar orasidagi kichik farqlarni tekislaydigan tayyor CSS fayllar. Eng mashhurlaridan biri — normalize.css; uning izohida aynan shu iPhone muammosi yozilgan. Ko'p zamonaviy reset fayllarida shu qator bor (CSS reset darsida to'liq o'rganamiz, hozir bilish shart emas):

css
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

100% — "o'zim bergan o'lchamni o'zgartirma". MDN misolida none ham bor, lekin normalize.css va ko'p reset'lar aynan 100% ni tanlaydi — biz ham shunga ergashamiz. Baseline ma'lumotiga ko'ra text-size-adjust — Baseline emas: prefikssiz shaklini faqat Chrome va Edge biladi. MDN'ga ko'ra iPhone Safari faqat -webkit- prefiksli shaklni tushunadi. Shuning uchun ikkala qator ham kerak.

6.2 Skroll "sakrashlari"

Telefonda sahifa siz aylantirmagan holda siljisa, sababi odatda to'rttadan biri:

  • Manzil paneli yashirinib-chiqqanda dvh bilan o'lchangan bloklar o'zgaradi (Viewport birliklari). Oddiy sahifada svh ni tanlang.
  • O'lchamsiz rasm yuklanganda matnni pastga suradi — CLS (Rasm va media, Rasmlar CSS tomoni).
  • Ichki skroll oxiriga yetganda butun sahifa aylana boshlaydi — skroll zanjiri, uni overscroll-behavior: contain to'xtatadi (Overflow).
  • Yopishgan sarlavha ostida havolaga sakraganda sarlavha matnni yopadi — scroll-margin-top (Skroll xulqi).

7. Nimani qayerda tekshirdik

Tuzoq Chrome DevTools Manba
Xavfsiz hudud env() = 0, burun chizilmaydi WebKit, MDN
iOS forma zoom'i Ko'rinmaydi Safari xulqi
Yopishgan hover Qisman, telefonda aniq MDN, oldingi dars
Klaviatura Ko'rinmaydi Chrome blogi, MDN

Chrome'da o'zimiz o'lchaganlar: env() qiymatlari va zaxirasi, forma maydonlarining boshlang'ich shrifti (13.33 piksel), tap highlight rangi, telefon emulyatsiyasida hover: none va pointer: coarse (Foydalanuvchi afzalliklari). Qolgani — manbalardan va har biri telefonda sinashni talab qiladi.

Telefonda sinashning eng oson yo'li — saytni internetga joylash (Birinchi deploy) va telefoningizda ochish. Android telefonda dasturchi rejimini yoqib, USB bilan ulasangiz, kompyuterdagi Chrome'da chrome://inspect orqali uning sahifasini DevTools bilan tekshirasiz. iPhone uchun esa Mac'dagi Safari'ning "Develop" menyusi kerak.

8. Ko'p uchraydigan xatolar

8.1 viewport-fit=cover bor, env() yo'q

Sahifa burun ostigacha cho'zildi, pastdagi panel uy chizig'i ostida qoldi. Tuzatish: chetga yopishgan elementlarga max(odatiy, env(safe-area-inset-...)).

8.2 padding: env(...) odatiy bo'sh joysiz

Oddiy telefonda qiymat 0 — tugma matni chetga yopishdi. Tuzatish: max(0.75rem, env(safe-area-inset-bottom)).

8.3 Zoom'ni o'chirib "tuzatish"

user-scalable=no — ko'zi zaif odam matnni kattalashtira olmaydi. Tuzatish: forma maydonlariga font: inherit yoki font-size: 1rem.

8.4 Hover'da muhim holat

Telefonda bosilgan karta rangli bo'lib qoldi. Tuzatish: @media (hover: hover) va bosish uchun :active.

8.5 Tap highlight o'chirildi, o'rniga hech narsa

Tugma bosilganini sezib bo'lmaydi. Tuzatish: :active holatini bering.

8.6 touch-action: none katta blokda

Sahifani aylantirib bo'lmay qoldi. Tuzatish: none faqat chizish maydoni yoki xarita kabi kichik joyda; karuselda — pan-y.

9. Mashqlar

Mashqlarni kurs/mashqlar/05/ papkasida bajaring.

1-mashq (oson): Kompyuterda ko'rinadimi?

Har tuzoqni Chrome DevTools qurilma rejimida ko'rish mumkinmi (ha / yo'q)?

  1. Forma maydoni bosilganda iPhone sahifani kattalashtiradi.
  2. env(safe-area-inset-bottom) qiymati.
  3. Forma maydonining shrifti 13.33 piksel.
  4. Klaviatura fixed tugmani yopadi.
Yechim
  1. Yo'q — Safari xulqi, Chrome emulyatsiyasi zoom qilmaydi.
  2. Qisman — qiymatni Computed'da ko'rasiz, lekin u doim 0; haqiqiy qiymat — telefonda.
  3. Ha — Computed'da font-size: 13.3333px. Aynan shu sabab tuzoqni oldindan topish mumkin.
  4. Yo'q — DevTools ekran klaviaturasini chizmaydi.

2-mashq (o'rta): Bron formasi telefonda

«Bahor»ning bron formasi (bron/index.html) telefonda qulay bo'lsin. asosiy.css ga yozing:

  1. Hamma forma maydonlari va tugma sahifa shriftida bo'lsin.
  2. .bron-havola va forma tugmasida sichqoncha hover'i faqat hover bor qurilmada; bosilganda hamma qurilmada --rang-asosiy-toq fon.
  3. Tugmalarda brauzerning tap dog'i bo'lmasin.

Ishora: forma zoom'i «Yechim» bo'limi, yopishib qoladigan hover va tap dog'i bo'limlari. Forma tugmasi — form button.

Yechim
css
input,
select,
textarea,
button {
  font: inherit;
}

.bron-havola,
form button {
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) {
  .bron-havola:hover,
  form button:hover {
    background-color: oklch(
      from var(--rang-asosiy) calc(l - 0.08) c h
    );
  }
}

.bron-havola:active,
form button:active {
  background-color: var(--rang-asosiy-toq);
}
  • font: inherit — maydonlar 16 piksel, iPhone zoom qilmaydi.
  • Hover rangi — Ranglar 3 darsidagi nisbiy rang, faqat hover: hover da. Nisbiy rang — yangi Baseline (2024-yil sentabr): eski brauzerda hover rangi o'zgarmaydi, lekin :active baribir ishlaydi.
  • :active @media dan tashqarida — u barmoq va sichqoncha uchun ham kerak. Tap dog'i olib tashlandi, chunki o'rniga :active bor.

3-mashq (qiyin): Pastki panelning uch xatosi

Stajyor telefonda pastga yopishgan "Qo'ng'iroq qilish" panelini yozdi:

css
footer {
  position: fixed;
  bottom: 0;
  width: 100vw;
  padding-bottom: env(safe-area-inset-bottom, 1rem);
  touch-action: none;
}
footer a:hover {
  background-color: #d8ecd9;
}

HTML'da viewport-fit=cover bor. Uchta muammoni toping va tuzating.

Yechim
  1. env(..., 1rem) — iPhone bo'lmagan telefonda va kompyuterda brauzer o'zgaruvchini biladi, qiymat 0 — zaxira ishlamaydi, panel pastida bo'sh joy yo'q («max() bilan» bo'limi). To'g'risi — max(1rem, env(...)).
  2. touch-action: none — panel ustida barmoq bilan sahifani aylantirib bo'lmaydi. Panelda maxsus harakat yo'q — bu qator kerak emas.
  3. :hover himoyasiz — telefonda bosilgan havola yashil bo'lib qoladi. @media (hover: hover) ichiga olinadi.

Bonus: width: 100vw — Viewport birliklari darsidagi skrollbar tuzog'i. inset-inline: 0 yaxshiroq.

css
footer {
  position: fixed;
  bottom: 0;
  inset-inline: 0;
  padding: 0.75rem 1rem;
  padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
}
@media (hover: hover) {
  footer a:hover {
    background-color: #d8ecd9;
  }
}

4-mashq: Portfolio qadami — telefonga tayyorlash

Portfoliongizni haqiqiy telefonda sinashga tayyorlang:

  1. Aloqa formasidagi input, textarea va button sahifa shriftini olayotganini tekshiring — iPhone zoom'ining yechimi aynan shu.
  2. Mantiqiy pseudo-klasslar va Ranglar 3 darslarida yozgan menyu hover qoidangiz telefonda yopishmasin.
  3. html ga matnni avtomatik kattalashtirishni o'chiradigan ikki qatorni qo'shing.
  4. Saytni qayta joylang (Birinchi deploy) va telefoningizda tekshiring: aloqa formasidagi ism maydoni bosilganda sahifa kattalashadimi? Menyu havolasini bosib, boshqa sahifadan "orqaga" qayting — havola rangli bo'lib qolmadimi? Telefonni yotiq holatga burib ko'ring.

Ishora: O'lchamlar darsida button ga min-height va padding bergan edingiz — ular qoladi, faqat shrift qo'shiladi.

Yechim
css
/* Telefon: forma shrifti, matn o'lchami, hover */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

input,
textarea,
button {
  font: inherit;
}

@media (hover: hover) {
  header nav a:not([aria-current="page"]):hover {
    color: oklch(from var(--rang-asosiy) calc(l - 0.1) c h);
  }
}
  • Oldingi hover qoidasini (a:not([aria-current="page"]):hover yoki Ranglar 3 darsidagi header nav a:hover) faylingizda toping va shu @media ichiga ko'chiring — ikki nusxa qolmasin. Rang — o'sha darsdagi nisbiy rang: yangi Baseline, eski brauzerda hover rangi shunchaki o'zgarmaydi.
  • font: inherit qoidasini Meros darsida yozgan edingiz — faylda bo'lsa, ikkinchi nusxa kerak emas. Shu qoida tufayli maydonlar va tugma 16 piksel: iPhone zoom qilmaydi, O'lchamlar darsidagi min-height: 2.75rem ham tugmaga mos.
  • Portfolio'da fixed panel yo'q, viewport-fit=cover ham kerak emas — standart holatda Safari sahifani o'zi xavfsiz hududga joylaydi.
  • Telefonda tekshirganda natijani yozib qo'ying — Yakuniy loyiha darsida hamma tekshiruvlarni bir ro'yxatga yig'amiz.

10. Real ishda

  • Mobil trafik — ko'p saytlarda tashriflarning katta qismi telefondan. Shuning uchun jamoalar sahifani chiqarishdan oldin kamida bitta iPhone va bitta Android'da tekshiradi. Buning uchun real qurilmalar "fermasi" xizmatlari ham bor (BrowserStack kabi, kursda keyinroq).
  • Yetkazib berish va taksi saytlari pastga yopishgan "Buyurtma berish" tugmasini deyarli doim env(safe-area-inset-bottom) bilan yozadi.
  • Forma zoom'i — mobil formalar auditidagi eng birinchi tekshiruvlardan biri.
  • Intervyuda so'raladi: "iPhone'da input bosilganda sahifa nega kattalashadi?", "env(safe-area-inset-bottom) nima uchun?", "Sensorli ekranda hover muammosini qanday hal qilasiz?".

Xulosa

  • DevTools qurilma rejimi enni sinaydi, lekin burun, klaviatura, forma zoom'i va Safari xulqini ko'rsatmaydi — haqiqiy telefonda sinang.
  • viewport-fit=cover + max(odatiy, env(safe-area-inset-*)) — chetga yopishgan elementlar uchun.
  • Forma maydonlari font: inherit — 16 piksel va undan katta, iPhone zoom qilmaydi; zoom'ni o'chirmang.
  • Hover — @media (hover: hover) ichida, bosishga javob — :active; tap dog'ini olib tashlasangiz, :active bering.
  • Klaviatura faqat ko'rinadigan qismni kichraytiradi; interactive-widget iPhone'da yo'q — muhim tugma oddiy oqimda tursin.

Keyingi dars: Yakuniy loyiha: portfolio'ni CSS bilan bezash va responsive qilish — 05-qismda o'rganilgan hamma narsani portfoliongizda yig'amiz va Lighthouse bilan tekshiramiz.

Manbalar

  • MDN: "env()", "viewport meta tag" (viewport-fit, interactive-widget), "touch-action", "-webkit-tap-highlight-color", "text-size-adjust", "VirtualKeyboard API" — developer.mozilla.org
  • WebKit: "Designing Websites for iPhone X" (2017) — webkit.org/blog/7929
  • Chrome for Developers: "Prepare for viewport resize behavior changes coming to Chrome on Android" — developer.chrome.com/blog/viewport-resize-behavior
  • normalize.css (text-size-adjust izohi) — github.com/necolas/normalize.css
  • web-features (Baseline ma'lumotlari): "safe-area-inset", "touch-action", "text-size-adjust", "virtual-keyboard" — github.com/web-platform-dx/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Mobil CSS tuzoqlari: notch, ekran klaviaturasi va sensorli ekran — IlmHamroh