Box Model (ყუთის მოდელი)

ბოქს მოდელი არის HTML-ისა და CSS-ის ფარგლებში ელემენტების გააზრებისა და გამოყენების ერთგვარი სქემა. ამ თავში განვიხილავთ რა არის ბოქს მოდელი და როგორ გვეხმარება ის ელემენტების განლაგებაში.

ბლოკური და ინლაინ ელემენტები

ზოგადად CSS-ში გვაქვს ელემენტები რომლებიც ერთიანდებიან ბლოკურ (block) და ინლაინ (inline) ტიპის ელემენტებში. ეს ტიპი განსაზღვრავს როგორ განლაგდება ელემენტი დოკუმენტის დინებაში სხვა ელემენტებთან მიმართებაში. ელემენტი შეგვიძლია გავხადოთ ბლოკური ან ინლაინ მისთვის display - ანუ გამოსახვის - თვისების შეცვლით block-ზე ან inline-ზე. display-ს კიდევ სხვა მნიშვნელობებიც გააჩნია;

ბლოკებს გააჩნიათ შიდა და გარე გამოსახვის ტიპები.

გარე გამოსახვის ტიპი

თუ ელემენტს გარე გამოსახვის ტიპი აქვს block, მაშინ:

  • ელემენტი ახალ სტრიქონზე გადმოვა.
  • width და height თვისებებს ყურადღება მიექცევა.
  • padding, margin და border აიძულებენ სხვა ელემენტებს, რომ გაიწიონ.
  • თუ width გაწერილი არ აქვს, ელემენტი გაიწელება მთელ სტრიქონზე და დაიკავებს მის კონტეინერში არსებულ მთელ სივრცეს.

თქვენ შეიძლება უკვე იცნობდეთ ელემენტებს, როგორებიცაა <h1> და <p>. მათ ავტომატურად display თვისებაზე უყენიათ block.

თუ ელემენტს გარე გამოსახვის ტიპი აქვს inline, მაშინ:

  • ელემენტი არ შეიქმნება ახალ სტრიქონზე.
  • width და height თვისებები არ იმუშავებს.
  • ზედა და ქვედა margin, padding და border იმუშავებს, თუმცა არ გაწევს სხვა ელემენტებს.
  • მარცხენა და მარჯვენა margin, padding და border იმუშავებს და სხვა ელემენტებს მოშორებით გაწევს.

ინლაინ გარე გამოსახვის ელემენტებია <a>, <span>, <em> და სხვები.

შიდა გამოსახვის ტიპი

ელემენტებს ასევე აქვთ შიდა გამოსახვის ტიპი. შიდა გამოსახვის ტიპი გულისხმობს ელემენტის შიგნით როგორ განლაგდებიან სხვა ელემენტები. ჩვეულებრივ, დამატებითი სტილების გარეშე, ბოქსის შიგნით განლაგებულები არიან ინლაინ ან ბლოკურად.

შიდა გამოსახვის ტიპის შეცვლა შესაძლებელია display თვისების მნიშვნელობის შეცვლით. მაგალითად flex და grid ელემენტს გარე გამოსახვაზე მიანიჭებენ ბლოკს, თუმცა შეიცვლება მათი შიდა გამოსახვა flex-ზე ან grid-ზე. ფლექსისა და გრიდს ამ სახელმძღვანელოში მოგვიანებით გავეცნობით.

გამოსახვის ტიპის მაგალითები

ნიმუშის მთლიანი კოდი იხილეთ აქ.

index.html-ში ჩვენ გვაქვს შემდეგი ელემენტები:

HTML
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./style.css" />
    <title>Box Model</title>
  </head>
  <body>
    <p>ესაა პარაგრაფი</p>
    <ul>
      <li>სიაში პირველი</li>
      <li>სიაში მეორე</li>
      <li>სიაში მესამე</li>
    </ul>
    <p>ამ პარაგრაფში რომელიღაც ჩვეულებრივ <span>ინლაინ</span> ელემენტი <span class="block">გადაიქცევა ბლოკად</span> და შესაბამისად თავისთვის დაიკავებს მთლიან სტრიქონს.</p>
  </body>
</html>

style.css-ში:

CSS
p,
ul {
  border: 2px solid blue;
  padding: 12px;
}

ul {
  list-style: none;
  display: flex;
}

li,
span {
  border: 2px solid paleturquoise;
  padding: 12px;
}

.block {
  display: block;
}

ყურადღება მივაქციოთ შემდეგ ფაქტებს:

  • პირველი პარაგრაფი, რომელიც პადინგით და ჩარჩოებით გავსტილეთ, ავტომატურად ბლოკურია, ამიტომ ის ახალ სტრიქონზე იქმნება და მთლიანი სტრიქონის სიგანეს იკავებს.
  • სიის ელემენტზე შიდა გამოსახვა მითითებული გვაქვს flex-ზე, რის გამოც მისი შიდა li ელემენტები განსხვავებულად (flex-ისებრად) ლაგდებიან.
  • შემდეგ პარაგრაფში ტექსტში გვაქვს ორი span ელემენტი, რომელიც ავტომატურად ინლაინ არის, თუმცა მეორე span-ს აქვს მინიჭებული block კლასი, რომლის სტილებიც ელემენტს ბლოკად აქცევს display: block-ით, ამიტომ ის ახალ სტრიქონზე განთავსდება.
  • პირველი span ელემენტი, რადგან ინლაინ არის, მიიღებს პადინგს, რომელიც ჩვენ მას სტილებში მივანიჭეთ, თუმცა ვერტიკალური პადინგები არ გაწევს სხვა ელემენტებს მისგან მოშორებით, ამიტომ პირველი და მეორე span-ის ბოქსები ერთმანეთს კვეთავენ! ამისგან განსხვავებით, ჰორიზონტალური პადინგები მის გვერდით არსებულ ელემენტებს მოშორებით წევენ.

სტილის ფაილებში ul ელემენტი ახლა ვაქციოთ inline-flex-ად და ასევე შემოვიტანოთ inline კლასი, რომლის ელემენტზე მინიჭებითაც მას ინლაინ ელემენტად ვაქცევთ. .block სტილები კომენტარად ვაქციოთ რათა მისი ეფექტი გავაუქმოთ:

CSS
ul {
  list-style: none;
  display: inline-flex;
}

/* ... სხვა სტილები ...*/

/* .block {
    display: block;
} */

.inline {
  display: inline;
}

და ახლა ყველა პარაგრაფს მივცეთ inline კლასი, :

HTML
<p class="inline">ესაა პარაგრაფი</p>
<ul>
  <li>სიაში პირველი</li>
  <li>სიაში მეორე</li>
  <li>სიაში მესამე</li>
</ul>
<p class="inline">ამ პარაგრაფში რომელიღაც ჩვეულებრივ <span>ინლაინ</span> ელემენტი <span>გადაიქცევა ბლოკად</span> და შესაბამისად თავისთვის დაიკავებს მთლიან სტრიქონს.</p>

დავაკვირდეთ შედეგს:

  • ვინაიდან პარაგრაფის გარე გამოსახვა ვაქციეთ ინლაინად, ისინი სხვა ინლაინ ელემენტების გვერდი-გვერდ დალაგდებიან.
  • სიის ელემენტი ვაქციეთ inline-flex-ად, ანუ მისი გარე გამოსახვის ტიპი გახდა inline, ხოლო შიდა - flex. ამის გამო ის ინლაინ პარაგრაფის გვერდით განთავსდება, ხოლო შიდა გამოსახვა იგივე დარჩება.
  • ინლაინ ელემენტები wraps-ს აკეთებენ, ანუ გადავლენ ახალ სტრიქონზე, თუ ისინი სიგანეში მიმდინარე სტრიქონზე ვეღარ ეტევიან.
  • ინლაინ ელემენტები შიგთავსით კი გაწევენ სხვა ელემენტებს ჰორიზონტალურად და ვერტიკალურად, მაგრამმარჯინებით, პადინგებით ან ბორდერებით ეს მხოლოდ ჰორიზონტალურ სიბრტყეზე მოხდება. ამის გამო ახალ სტრიქონზე გადასული ინლაინ ელემენტები ერთმანეთს ვერტიკალურად კვეთავენ.

სცადეთ ამ ელემენტებისთვის display თვისებების შეცვლა და შეისწავლეთ რა შედეგს გვაძლევს ეს. აქ ნახავთ ნიმუშის კოდს.

რა არის Box Model

CSS-ში ბოქს მოდელი მიესადაგება ბლოკურ ბოქსებს და განსაზღვრავს როგორ ურთიერთქმედებს ერთმანეთთან ამ ბოქსის ნაწილები: margin, border, padding და კონტენტი. ინლაინ ბოქსებზე ბოქს მოდელის წესები შეზღუდულად მუშაობს.

ბოქსის ნაწილები

ბოქსი არც თუ ისე განსხვავდება ხახვისგან, რადგან მასაც გააჩნია ფენები. მივყვეთ შიდა ფენიდან გარე ფენებს:

  • Content box: ყველაზე შიდა შრე, სადაც კონტენტია გამოსახული. მისი ზომების დარეგულირება შეგვიძლია შემდეგი თვისებებით: inline-size და block-size, ან width და height.
  • Padding box: თავისუფალი სივრცე კონტენტის გარშემო. მისი გასტილვა შეგვიძლია padding თვისებით.
  • Border box: გარს ეკვრის კონტენტსა და პადინგს. ჩარჩო, რომელიც შემოფარგლავს ელემენტს. მისი გასტილვა შეგვიძლია border თვისებით.
  • Margin box: გარე ფენა, რომელიც ფუთავს კონტენტს, პადინგსა და ბორდერს. იგი წარმოადგენს თავისუფალ სივრცეს ამ ბოქსსა და სხვა ელემენტებს შორის. მისი გასტილვა შეგვიძლია margin თვისებით.

სტანდარტული ბოქსი

ავიღოთ უბრალო პარაგრაფი, რომელსაც გავუსტილავთ შემდეგ თვისებებს:

  • კონტენტის უკანა ფონს (ბეჟში)
  • პადინგს 4-ვე მხრიდან
  • ბორდერს 4-ვე მხრიდან (ლურჯად)
  • მარჯინს 4-ვე მხრიდან
  • კონტენტის სიგანეს (400 პიქსელი)

კოდის ნიმუში იხილეთ აქ

CSS
p {
  background-color: beige;
  padding: 40px;
  border: 30px solid blue;
  margin: 60px;
  width: 400px;
}

ბრაუზრერის developer tools-ში თუ დავაინსპექტებთ ამ ელემენტს, სტილების ბოლოში შეგვიძლია დავაკვირდეთ მის ბოქს მოდელს.

ელემენტს ზემოთ განხილული ფენები იმ ზომებზე აქვს დაყენებული, რომელზეც მივუთითეთ. გასათვალისწინებელია, რომ ჩვენ width-ით ვარეგულირებთ კონტენტის ბოქსს, ანუ ელემენტის მთლიანი სიგანე არის კონტენტის 400 პიქსელს + 40 + 40 + 30 + 30 (პადინგები და ბორდერი).

ეს არის სტანდარტული ბოქს მოდელი, სადაც აზომვა ხდება კონტენტ ბოქსის მიხედვით. ელემენტებს თანდაყოლილი აქვთ შემდეგი თვისება:

CSS
box-sizing: content-box;

ალტერნატიული ბოქს მოდელი

თუმცა არსებობს ალტერნატიული მოდელიც. ამ მოდელის მიხედვით, სიგანე ასახავს უშუალოდ ხილვადი ელემენტის სიგანეს. ანუ ელემენტის კონტენტის, პადინგისა და ჩარჩოების ჩათვლით. შესაბამისად, ელემენტის კონტენტის სიგანე გამოდის მის width ატრიბუტს მინუს border ატრიბუტი და მინუს padding ატრიბუტი.

ელემენტზე ალტერნატიული ბოქს მოდელის გამოსაყებებლად უდა შევცვალოთ box-sizing border-box-ზე.

CSS
p {
  /* ... სხვა სტილები ... */
  box-sizing: border-box;
}

ახლა თუ დავაკვირდებით პარაგრაფის ბოქს მოდელს ინსპექტორით, ვნახავთ, რომ მთლიანი კონტენტის სიგანე რეგულირდება ისე, რომ მთლიანი ელემენტი გამოვიდეს ჩვენ მიერ მითითებული ზომის.

დეველოპერთა უმეტესობა ვიყენებთ border-box-ს ამიტომ ხშირად მთავარი სტილების ფაილებში წააწყდებით შემდეგ სტრიქონებს:

CSS
* {
  box-sizing: border-box;
}

ეს სტილი ყველა ელემენტს (* სელექტორია, რომელიც ნიშნავს "ყველაფერს") მიანიჭებს ალტერნატიული ბოქსის მოდელს.

Margin, padding & border

ზედა ნიმუშებში გაკვრით უკვე შევეხეთ მარჯინებს, პადინგებსა და ბორდერებს. ახლა დროა მათ ცოტა მეტი ყურადღება დავუთმოთ. ამ ქვეთავის კოდის ნიმუში შეგიძლიათ ნახოთ აქ.

Margin

მარჯინი (იგივე "დაშორება") არის უჩინარი სივრცე ელემენტის ბოქსის გარშემო. მარჯინებს შეგვიძლია მივცეთ დადებითი და უარყოფითი მნიშვნელობებიც. უარყოფითი მარჯინების დაყენებამ შეიძლება გამოიწვიოს ელემენტების გადაკვეთა. მიუხედავად იმისა, სტანდარტულ თუ ალტერნატიულ ბოქს მოდელს ვიყენებთ, მარჯინი ყოველთვის იმის მერე ემატება ბოქსს, რაც ბოქსის ხილვადი ზომები გამოითვლება. ანუ მარჯინი ბოქსის სიგანის ნაწილი არ არის.

ჩვენ შეგვიძლია ბოქსის კონკრეტული მხარეების მარჯინები ვმართოთ:

CSS
.box {
  margin-top: -40px; /* ზედა */
  margin-right: 30px; /* მარჯვენა */
  margin-bottom: 40px; /* ქვედა */
  margin-left: 60px; /* მარცხენა */
}

ასევე შესაძლებელია მოკლედ მხოლოდ margin ატრიბუტის გამოყენება:

CSS
.box {
  margin: -40px 30px 40px 60px;
}

ეს იგივე შედეგს მოგვცემს, რასაც წინა ნიმუში. აქ მიწოდებულ მნიშვნელობებს თანიმდევრობა გააჩნია: იწყება ზედა მხრიდან და საათის ისრის მიხედვით მიყვება.

თუ ჰორიზონტალური და ვერტიკალური დაშორებები ერთგვაროვანია, უფრო შემოკლებული ვარიანტიც არსებობს:

CSS
.box {
  margin: 30px 60px;
}

ეს გულისხმობს, რომ ზედა და ქვედა მარჯინები იქნება 30px, ხოლო მარცხენა და მარჯვენა - 60px.

და ბოლოს, თუ ყველა მხრიდან დაშორება ერთია, ჩვენ შეგვიძლია მხოლოდ ერთი მინშვნელობა მივაწოდოთ margin: 30px.

გასათვალისწინებელია, რომ მარჯინებს ახასიათებთ ე.წ "Margin collapsing". როცა ელემენტების მარჯინები ერთმანეთს ესაზღვრება, შემდეგი ეფექტი გვაქვს:

  • ორი დადებითი მარჯინი გაერთიანდება და გახდება ერთი მარჯინი. მისი ზომა იქნება ყველაზე დიდი ინდივიდუალური მარჯინის ტოლი.
  • ორი უარყოფითი მარჯინი დაკოლაპსდება და მათგან ყველაზე მცირე იქნება გამოყენებული.
  • თუ ერთ-ერთი მარჯინია უარყოფითი, მისი მნიშვნელობა გამოაკლდება მთლიან მარჯინს.

შევქმნათ ორი პარაგრაფი:

HTML
<div class="margin-collapse">
  <p class="one">I am paragraph one.</p>
  <p class="two">I am paragraph two.</p>
</div>

და მივანიჭოთ მათ მარჯინები:

CSS
.one {
  margin-bottom: 50px;
}

.two {
  margin-top: 30px;
}

შედეგს თუ დავაკვირდებით, ვნახავთ, რომ ამ ორ პარაგრაფს შორის მარჯინი არის არა მათი მარჯინების ჯამი, არამედ 50px, რადგან ისინი ერთმანეთში "ჩაიშალნენ".

ჰორიზონტალურ მარჯინებს გააჩნია განასკუთრებული მნიშვნელობა auto, რომელიც ბლოკულ ელემენტებს მარჯინზე მაქსიმალურ მნიშვნელობას მისცემს და მას მშობელი ელემენტის ზომების მიხედვით დაარეგულირებს. ამ ეფექტის მისაღებად აუცილებელია, რომ ელემენტს შედარებით მცირე სიგანე ჰქონდეს.

ზედა მაგალითში განხილულ ელემენტს, რომელსაც container კლასი აქვს მივცეთ მარჯინი:

CSS
.container {
  border: 10px solid blue;
  width: 500px;
  height: 350px;

  margin-left: auto;
}

ასე ლემენტი ყოველთვის მარჯვენა მხარეს იქნება და თან ადაპტირდება ფანჯრის ზომების (და შესაბამისად მშOბელი ელემენტის ზომების) ცვლილებასთან.

თუ ელემენტს ორივე მხრიდან (ჰორიზონტალურად) მივცემთ ავტომატურ მარჯინებს, მაშინ ისინი ორივე მაქსიმალურად გაიზრდებიან და საბოლოოდ თანაბრად გაინაწილებენ სივრცეს. ელემენტი მოექცევა ზუსტად ცენტრში.

CSS
.container {
  /* ... სხვა სტილები ... */
  margin-left: auto;
  margin-right: auto;
}

ან უფრო მოკლედ:

CSS
.container {
  margin: auto;
}

ვერტიკალურად ავტომატური მარჯინები არ მუშაობს, თუმცა შეგვიძლია ჰორიზონტალურად გავხადოთ ავტომატური, ხოლო ვერტიკალურად რაიმე კონკრეტული მნიშვნელობა გავუწეროთ:

CSS
.container {
  margin: 50px auto;
}

Border

ბორდერი (იგივე "საზღვარი") გამოსახულია მარჯინსა და პადინგს შორის. მისი გასტილვა ყველაზე მოკლედ და მარტივად შეგვიძლია border თვისებით, სადაც მივუთითებთ ბორდერის სისქეს (border-width), ბორდერის სტილს (border-style) და ბორდერის ფერს (border-color):

CSS
.bordered {
  border: 4px solid #000;
}

არ დაგავიწყდეთ რაიმე ელემენტისთვის შემდეგ ამ კლასის მინიჭება:

HTML
<div class="border-example">
  <p class="bordered">I have a border!</p>
</div>

ასე ჩვენ ერთგვაროვან ჩარჩოს ვაძლევთ ელემენტს ყველა მხრიდან, თუმცა შეგვიძლია ინდივიდუალური მხარეები გავსტილოთ იმავე პრინციპით:

CSS
.bordered {
  border-top: 4px solid #000;
  border-right: 10px dotted #4ace4a;
  border-bottom: 20px dashed blue;
  border-left: 26px groove purple;
}

ასევე შესაძლებელია თითოეულ მხარეს ინდივიდუალურად მივცეთ სიგანე, სტილი თუ ფერი, მაგალითად: border-top-width, border-right-style, border-bottom-color და ა.შ.

Padding

პადინგი (ითარგმნება, როგორც "დარბილება" ან "სატენი მასალა") არის თავისუფალი სივრცე ბოქსის საზღვრებსა და კონტენტს შორის. თუ ელემენტს ამანათის ყუთად წარმოვიდგენთ, მაშინ ეს დამცავი (სატენი) რბილი მასალაა რომელიც ამანათის შიგთავსსა და ყუთს შორის არის, რათა შიგთავსი არ დაზიანდეს.

თითოეული მხარის პადინგის ზომების დასაყენებლად გამოიყენება შემდეგი თვისებები:

  • padding-top
  • padding-right
  • padding-bottom
  • padding-left

თუმცა მისი შემოკლებული ვარიანტიც არსებობს, რომელიც ზუსტად ისე მუშაობს, როგორც margin:

CSS
.example {
  /* padding-top-იდან საათის ისრის მიხედვით */
  padding: 10px 20px 30px 40px;

  /* 10px ვერტიკალურად, 20px ჰორიზონტალურად */
  padding: 10px 20px;

  /* ყველა მხრიდან 12px */
  padding: 12px;
}

შეჯამება

ამ თავში ჩვენ განვიხილეთ Box Model, ანუ ელემენტების, როგორც "ყუთების" გააზრებისა და გასტილვის მოდელი. ელემენტებს გააჩნიათ display თვისება, რომელიც განსაზღვრავს, როგორ გამოისახება ელემენტები. არსებობს შიდა და გარე გამოსახვის ტიპები, რომელთაგანაც გამოვყავით ინლაინ და ბლოკური ბოქსები. ბოქსს გააჩნია შრეები, რომლის ბირთვშიცაა კონტენტი და მას მოყვება პადინგი, შემდეგ ბორდერი და ბოლოს მარჯინი. ბოქს მოდელი სტანდარტულად content-box ის მიხედვით არეგულირებს სიგანეს, ანუ width ატრიბუტი გულისხმობს კონტენტის სიგანეს და მთლიანი ელემენტის სიგანეს ემატება პადინგის და ბორდერის ზომები. არსებობს ალტერნატიული და ძალზედ პოპულარული ბოქს მოდელიც - border-box, რომელიც კონტენტის ზომებს არეგულირებს, რათა მასზე მითითებული width ატრიბუტი გამოვიდეს ელემენტის კონტენტის, პადინგისა და ბორდერის ზომების გაერთიანებით. ბოლოს განვიხილეთ ბოქსის თითოეული შრე და მათი გამოყენების ვარიანტები.

გამოყენებული ლიტერატურა