box-sizing — content-box va border-box farqi

~10 daq · CSS · Box Model va Matn

Muammodan boshlaylik

Sahifani ikkita teng ustunga bo'lish kerak:

.ustun {
  width: 50%;
  float: left;
  padding: 20px;
}

Natija: ikkinchi ustun pastga tushib ketdi. Nega? Chunki har bir ustun 50% + 40px — jami 100% + 80px, ya'ni ekrandan kengroq.

Hisoblab chiqasiz: width: calc(50% - 40px). Ishladi. Keyin dizayner chegara qo'shishni so'raydi — yana qayta hisoblash: calc(50% - 42px). Har bir padding yoki border o'zgarishi — barcha kengliklarni qayta hisoblash.

7-darsda ko'rgan muammo: width faqat kontentni o'lchaydi. Buni bitta qator bilan butunlay hal qilish mumkin.


Ikki rejim

content-box — standart

.box {
  box-sizing: content-box;   /* standart — yozish shart emas */
  width: 300px;
  padding: 20px;
  border: 2px solid;
}
width (300) faqat content ga tegishli:

  ┌─ border 2 ─┬─ padding 20 ─┬──── content 300 ────┬─ padding 20 ─┬─ border 2 ─┐
  └──────────────────────────────── jami 344px ─────────────────────────────────┘

border-box — "width — butun quti"

.box {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid;
}
width (300) — chegara bilan birga butun quti, content qolgan joyni oladi:

  ┌─ border 2 ─┬─ padding 20 ─┬──── content 256 ────┬─ padding 20 ─┬─ border 2 ─┐
  └──────────────────────────────── jami 300px ─────────────────────────────────┘

Ko'rinadigan kenglik — aynan 300px. Padding va border ichkariga, content hisobidan "yeyiladi".

content-box border-box
width nima Faqat content content + padding + border
Padding qo'shilsa Element kengayadi Element o'lchami o'zgarmaydi, content kichrayadi
Hisoblash calc() kerak Oddiy
Qayerda standart Barcha elementlar Ba'zi forma elementlari (button, select)

[!INFO] margin hech qaysi rejimda width ga kirmaydi — u har doim qutidan tashqarida.

Darsning boshidagi muammo border-box bilan:

.ustun {
  box-sizing: border-box;
  width: 50%;
  padding: 20px;
  border: 1px solid #e2e8f0;
}

Har bir ustun — aniq 50%. Padding va border istalgancha o'zgarsin — kenglik buzilmaydi.


Universal qoida — har bir loyihada

Deyarli barcha zamonaviy loyihalar CSS faylining eng boshida shuni yozadi:

*,
*::before,
*::after {
  box-sizing: border-box;
}
  • * — barcha elementlar
  • ::before, ::after — pseudo-element lar * ga kirmaydi (3-dars), shuning uchun alohida

Tailwind, Bootstrap, normalize.css kabi barcha mashhur kutubxonalar buni allaqachon qiladi. 1-darsdagi "reset" da ham aynan shu qator bor edi.

Meros orqali variant

html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

Barcha elementlar ota dan meros oladi. Afzalligi: agar biror tashqi komponent (masalan, eski kutubxona) content-box ni talab qilsa, uning konteyneriga box-sizing: content-box berish yetarli — ichidagi hamma narsa ham shunga o'tadi.


Qachon content-box kerak

Kamdan-kam, lekin bor:

  • Kontent maydoni aniq o'lchamda bo'lishi kerak bo'lganda: masalan, 800×600 kanvas atrofida chegara qo'shilganda, rasm o'zi aniq o'lchamda qolishi kerak
  • Eski kodni o'zgartirishda — mavjud hisob-kitoblarni buzmaslik uchun

Qolgan barcha holatlarda — border-box.


height ham xuddi shunday

box-sizing height ga ham tegishli:

.input {
  box-sizing: border-box;
  height: 44px;
  padding: 10px 12px;
  border: 1px solid #cbd5e1;
}

Input aniq 44px balandlikda — padding qanday bo'lmasin. Forma elementlarini bir xil balandlikda tekislash uchun juda qulay (tugma va input yonma-yon — bir xil 44px).


Nima uchun shunday?

Agar border-box shunchalik qulay bo'lsa, nima uchun standart rejim — content-box?

Tarixiy sabab. 1990-yillarda CSS standarti content-box ni tanladi — "width kontent uchun" mantiqiy tuyuldi. Qizig'i, o'sha paytdagi Internet Explorer (5-versiya) standartga zid ravishda border-box usulida hisoblardi — va dasturchilar uni "xato" deb tanqid qilishdi. Yillar o'tib ma'lum bo'ldiki, IE ning "xatosi" amalda qulayroq ekan: dizaynerlar elementlarni ko'rinadigan o'lchami bilan o'ylaydi, kontent maydoni bilan emas. Lekin standartni o'zgartirish millionlab mavjud saytlarni buzardi. Shuning uchun box-sizing xususiyati qo'shildi — va endi har bir loyiha birinchi qatorda o'zi tanlaydi.


Xulosa

Eslab qoling:

  • content-box (standart): width = faqat content; padding va border qo'shiladi
  • border-box: width = butun ko'rinadigan quti; content qolgan joyni oladi
  • margin ikkala rejimda ham tashqarida
  • Har bir loyiha boshida: *, *::before, *::after { box-sizing: border-box; }
  • height ham shunday — forma elementlarini tekislash oson
  • content-box — faqat kontent maydoni aniq o'lchamda bo'lishi kerak bo'lganda

Keyingi dars

9-dars: Margin collapse muammosi va yechimi