CSS level 1 Спецификация

4    МОДЕЛ НА ФОРМАТИРАНЕ

CSS1 използва прост кутийно-ориентиран модел на форматиране, в който всеки форматиран елемент бива интерпретиран като една или повече правоъгълни кутии. (Елементите, чиято стойност на атрибута 'display' е установена на 'none' не се форматират и следователно няма да бъдат интерпретирани като кутия). Всички кутии имат своя собствена област на съдържание, като по избор могат да бъдат зададени стойности за уплътнение('padding'), рамки('border') и полета('margin').

 _______________________________________
|                                       |
|           поле(прозрачно)('margin')   |
|   _________________________________   |
|  |                                 |  |
|  |        рамка('border')          |  |
|  |   ___________________________   |  |
|  |  |                           |  |  |
|  |  |     уплътнение('padding') |  |  |
|  |  |   _____________________   |  |  |
|  |  |  |                     |  |  |  |
|  |  |  |  съдържание         |  |  |  |
|  |  |  |_____________________|  |  |  |
|  |  |___________________________|  |  |
|  |_________________________________|  |
|_______________________________________|

          |широчина на елемента|
|          широчина на кутията          |

Размера на полето, рамката и уплътнителната област се задават с помощта съответно на свойствата margin(5.5.1-5.5.5), padding(5.5.6-5.5.10), и border(5.5.11-5.5.22). Уплътнителната област използва същия фон като самия елемент(зададен чрез фоновите свойства(5.3.2-5.3.7)).Цвета и стила на рамката се задава чрез свойствата й. Полетата винаги са прозрачни, така че родителския елемент ще се вижда, когато е под тях.

Размера на кутията се определя от сбора на широчината на елемента(например форматиран текст или изображение) и този на на уплътнителната област, рамката и полетата.

От гледна точка на форматиране съществуват два основни типа елементи: блокови и вътрешноредови.

4.1    Блокови елементи

Елементите, стойността на атрибута 'display', на които е установена на 'block' или 'list-item' се наричат блокови елементи. За блокови елементи се считат и плаващите такива(тези, чиято стойност 'float' е различна от 'none).

Следващият пример показва как полетата и уплътнението форматират елемент 'ul' с два дъщерни елемента. За да бъде по-проста скицата няма рамки. Също така, еднобуквените константи в този пример не са валиден CSS1 синтаксис, но са удобен начин да бъдат включени стилови стойности във фигурата.

<STYLE TYPE="text/css">
  UL { 
    background: red; 
    margin: A B C D;      
    padding: E F G H;
  }
  LI { 
    color: white;    
    background: blue;     /* текста е бял на син фон */ 
    margin: a b c d; 
    padding: e f g h;
  }
</STYLE>
..
<UL>
  <LI>1st element of list
  <LI>2nd element of list
</UL>
 _______________________________________________________
|                                                       |
|    A      UL поле('margin')(прозрачно)                |
|    _______________________________________________    |
| D |                                               | B |
|   |    E UL уплътнителна област('padding')(червена|   |
|   |    _______________________________________    |   |
|   | H |                                       | F |   |
|   |   |    a   LI поле('margin')(прозрачно,   |   |   |
|   |   |        така че прозира червения цвят) |   |   |
|   |   |    _______________________________    |   |   |
|   |   | d |                               | b |   |   |
|   |   |   | e LI уплътнение('padding')син)|   |   |   |
|   |   |   |                               |   |   |   |
|   |   |   | h  първи елемент от списъка f |   |   |   |
|   |   |   |                               |   |   |   |
|   |   |   |    g                          |   |   |   |
|   |   |   |_______________________________|   |   |   |
|   |   |                                       |   |   |
|   |   |     max(a, c)                         |   |   | <- забележете, че се търси максималната стойност
|   |   |    _______________________________    |   |   |
|   |   |   |                               |   |   |   |
|   |   | d | e LI уплътнение('padding')син)|   |   |   |
|   |   |   |                               |   |   |   |
|   |   |   | h  втори елемент от списъка f |   |   |   |
|   |   |   |                               |   |   |   |
|   |   |   |    g                          |   |   |   |
|   |   |   |_______________________________|   |   |   |
|   |   |                                       |   |   |
|   |   |   c  LI поле('margin')(прозрачно,     |   |   |
|   |   |      така че прозира червения цвят)   |   |   |
|   |   |_______________________________________|   |   |
|   |                                               |   |
|   |    G                                          |   |
|   |_______________________________________________|   |
|                                                       |
|   C                                                   |
|_______________________________________________________|

Технически, свойствата 'padding' и 'margin' не се наследяват. Но, както примера показва, разположението на елемента е относително с това на предшествениците и подобните му, така че стойностите за уплътнение и поле на тези елементи влияят върху дъщерните им елементи.

Ако в горния пример бяха включени рамки('border') те щяха да се намират между уплътнението и полетата.

Следващата фигура демонстрира малко полезна терминология:

                           --------------- <-- външен горен ръб
                             горно поле
                           ---------------
                             горна рамка
                           ---------------
                            горно уплътнение
                           +-------------+ <-- вътрешен горен ръб
|        |        |        |             |         |         |         |
|--ляво--|--лява--|--ляво--|--съдържание-|--дясно--|--дясна--|--дясно--|
|  поле  |  рамка | уплътн.|             | уплътн. |  рамка  |   поле  |
|        |        |        |             |         |         |         |
                           +-------------+ <-- вътрешен долен ръб
^                          ^             ^                             ^
ляв         ляв вътрешен ръб             десен вътрешен ръб          десен
външен							     външен
ръб                  долно уплътнение			     ръб
                           ---------------
                             долна рамка
                           ---------------
                             долно поле
                           --------------- <-- долен външен ръб

Левият външен ръб е ръба на елемента, ако се взимат в предвид стойностите, зададени на неговото уплътнение, рамка и поле. Левият вътрешен ръб е ръба единствено на съдържанието, което се намира във вътрешността на уплътнението, рамката или полето. Същото се отнася и за дясната част. Горната част е горната част на елемента , като се взимат в предвид стойностите, зададени за уплътнение, рамка и поле; тя е дефинирана единствено за вътрешноредови и плаващи елементи, но не и за не-плаващи блокови елементи. Вътрешния горен ръб е горния ръб на съдържанието, което се намира във вътрешността на уплътнението, рамката или полето, ако има такива. Долният ръбе долния ръб на елемента, извън стойностите за уплътнение, рамка и поле; той е дефиниран за вътрешноредови и плаващи елементи, но не и за блокови елементи. Вътрешният долен ръб е долния ръб на елемента, вътре в стойностите за уплътнение, рамка и поле.

Широчината на елемента е широчината на съдържанието, т.е. разстоянието между левия вътрешен ръб и десния вътрешен ръб. Височината е височината на съдържанието, т.е. разстоянието от вътрешния горен ръб до вътрешния долен ръб.

4.1.1    Вертикално форматиране

Широчината на полето на не-плаващ блоков елемент определя минималното разстояние до ръбовете на околните кутии. Две или повече съседни вертикални полета(т.е. без рамка, уплътнение или съдържание между тях) се сливат, така че да се използва максималната стойност от тях. В повечето случаи, след сливане на вертикални полета резултата е по-приятен за окото и по-близък до това, което дизайнера очаква. В примера по-горе, полетата между двата 'li' елемента се сливат чрез използване на максималната стойност от тази, зададена на 'margin-bottom' атрибута на първия елемент и тази, зададена на 'margin-top' атрибута на втория елемент. Подобно, ако уплътнението между 'ul' елемента и първия 'li' елемент(константата E) е било със стойност 0 , полето на ul елемента и това на първия li елемент щяха да се слеят.

В случай, че са зададени отрицателни полета, абсолютния максимум от отрицателните съседни полета се изважда от максимума на положителните съседни полета. Ако не съществуват положителни полета, абсолютния максимум на отрицателните съседни полета се изважда от 0.

4.1.2    Хоризонтално форматиране

Хоризонталната позиция, както и размера на неплаващ, блоков елемент се определя от седем свойства: 'margin-left', 'border-left', 'padding-left', 'width', 'padding-right', 'border-right' и 'margin-right'. Сумата на тези седем атрибута е винаги равна на широчината('width') на родителския елемент.

По подразбиране, стойността на 'width' свойството е 'auto'. Ако елемента не е заместен такъв, 'width' се изчислява от браузъра, така че сумата на споменатите по-горе седем свойства да бъде равна на широчината на родителския елемент. Ако елемента е заместен елемент, стойността 'auto' на свойството 'width' автоматично се замества от собствената широчина на елемента.

За три от седемте свойства може да бъде зададена автоматична стойност('auto'): 'margin-left', 'width' и 'margin-right'. При заместени елементи стойност 'auto', зададена на широчината('width') може да бъде заместена от присъщата широчина, така че за тях може да има и само две стойности 'auto'.

Свойството 'width' притежава неотрицателна минимална стойност, която се дефинира от браузъра(която може да се различава от елемент на елемент и дори може да зависи от други свойства). Ако стойността на 'width' попадне под тази граница или защото е зададена изрично или защото има стойност 'auto' и правилата по-долу са я направили твърде малка, стойността ще бъде заместена с минималната такава.

Ако на точно един от елементите 'margin-left', 'width' или 'margin-right' е зададена стойност 'auto', браузърът ще присвои на това свойство такава стойност, че сумата на седемте свойства да бъде равна на широчината на родителския елемент.

Ако няма свойство със зададена стойност 'auto', ще се счете, че стойността на 'margin-right' е със стойност 'auto'.

Ако на повече от едноот три свойства е зададена стойност 'auto, и едно от свойствата с такава стойност е 'width', тогава на останалите('margin-left' и/или 'margin-right') ще бъде зададена стойност 0 и на 'width' ще бъде зададена такава стойност, че сумата на седемте свойства да бъде равна на широчината на родителския елемент.

Иначе, ако и 'margin-left' и 'margin-right' са зададени на 'auto' ще имат равни стойности. Това ще разположи елемента централно в неговия родителски такъв.

Ако 'auto' е зададено като стойност на едно от седемте свойства в елемент, който е вътрешноредов или плаващ, това свойства ще бъде третирано, сякаш му е зададена стойност 0.

За разлика от вертикалните полета, хоризонталните не могат да се сливат.

4.1.3    Елементи от списък(List-Item)

Елементите, стойността на атрибута 'display', на които е зададена на 'list-item' биват форматирани като блокови елементи, но се предшестват от маркер за списък. Типа на този маркер се определя от свойството 'list-style'. Маркера се разполага в зависимост от стойността на 'list-style' свойството:

<STYLE TYPE="text/css">
  UL         { list-style: outside }
  UL.compact { list-style: inside }
</STYLE>
  
<UL>
  <LI>first list item comes first
  <LI>second list item comes second
</UL>

<UL CLASS=COMPACT>
  <LI>first list item comes first
  <LI>second list item comes second
</UL>

Горния пример ще бъде форматиран по подобен начин:

* first list item 
  comes first

* second list item
  comes second

  * first list
  item comes first

  * second list
  item comes second

В текст, който се разполага от дясно на ляво, маркерите ще бъдат разположени от дясната страна на кутията.

4.1.4    Плаващи елементи

Чрез свойството 'float' може да бъде декларирано, че един елемент се намира извън нормалния поток на елемeнтите. Тогава той се форматира като блоков елемент. Например, чрез задаване на стойност 'left' за свойството 'float' на изображение, то ще бъде местено наляво, докато не бъде достигнато полето, уплътнението или рамката на друг блоков елемент. Нормалния поток ще обгърне елемента от дясната му страна. Полетата, рамките и уплътненията на самия елемент ще бъдат спазени и полетата няма да се сливат с тези на съседните елементи.

Позиционирането на плаващия елемент е подчинено на следните ограничения(вижте глава 4.1за обяснение на термините):

  1. Левият външен ръб на плаващ вляво елемент(такъв, на чийто атрибут 'float' е зададена стойност 'left') може и да не се намира вляво на левия вътрешен ръб на своя родителски елемент. Същото се отнася и за плаващите вдясно елементи.
  2. Левият външен ръб на плаващ вляво елемент трябва да се намира вдясно на десния външен ръб на всеки по-ранен(в зависимост от момента си на появяване в HTML сорс кода) плаващ вляво елемент или горната част на първия трябва да е по-ниско от долната част на последния. Същото важи и за плаващите вдясно елементи.
  3. Десният външен ръб на плаващия вляво елемент не може да се намира вдясно на левия външен ръб на който и да е плаващ вдясно елемент, който се намира вдясно от него. Същото важи и за плаващите вдясно елементи.
  4. Горният ръб на плаващ елемент не може да се намира по-високо от вътрешния горен ръб на неговия родителски елемент.
  5. Горният ръб на плаващ елемент не може да се намира по-високо от горния ръб на по-рано деклариран плаващ или блоков елемент.
  6. Горният ръб на плаващ елемент не може да се намира по-високо от всяка редова кутия(вижте глава 4.4) със съдържание, която го предшества в HTML сорс кода.
  7. Горният ръб на плаващ елемент трябва да бъде разположен, колкото се може по-високо.
  8. Плаващ вляво елемент трябва да бъде разположен максимално вляво, плаващ вдясно елемент трябва да бъде разположен максимално вдясно. Предпочита се по-високата позиция пред тази, която е по-далеч от лявата/дясната част.
<STYLE TYPE="text/css">
  IMG { float: left }
  BODY, P, IMG { margin: 2em }
</STYLE>

<BODY>
  <P>
    <IMG SRC=img.gif>
    Some sample text that has no other...
</BODY>

Горния пример може да бъде форматиран по подобен на долния начин:

 ________________________________________
|
|          max(BODY поле, P поле)
|          ______________________________
|    |    |       Some sample text
| B  | P  | IMG полета, чиято единствена
| O  |    |    _____    цел е да 
| D  | П  |   |     |   покажат как плаващите
| Y  | о  |   | IMG |   елементи се придвижват
|    | л  |   |     |   откъм страната на 
| п  | е  |   |_____|   родителския елемент
| о  |    |             докато се спазват
| л  |    |             полета, рамки
| е  |    |             и уплътнение. Обърнете внимание
|    |    |на това как съседните вертикални полета 
|    |    |при неплаващите блокови елементи
|    |    |се сливат. 

Забележете как полето на 'p' елемента огражда плаващия 'IMG' елемент.

Съществуват две ситуации, при които плаващите елементи могат да застъпят полето, рамката и уплътнителните области на други елементи:

  • когато плаващия елемент има негативно поле: негативните полета на плаващите елементи се третират, както и при останалите блокови елементи.
  • когато плаващия елемент е по-широк или по-висок от елемента, в който се намира.

4.2    Вътрешноредови елементи

Елементите, които не са форматирани като блокови елементи, се наричат вътрешноредови елементи. Вътрешноредовият елемент може да дели редовото пространство с други елементи. Вземете в предвид следния пример:

<P>Several <EM>emphasized</EM> words <STRONG>appear</STRONG>.</P>

Елементът 'p' обикновено е блоков, докато 'em' и 'strong' са вътрешноредови елементи. Ако елемента 'p' е достатъчно широк, че да бъде форматиран целия елемент на един ред ще има два вътрешноредови елемента на реда:

Several emphasized words appear.

Ако мястото на един ред не е достатъчно вътрешноредовия елемент ще бъде разделен на няколко кутии:

<P>Several <EM>emphasized words</EM> appear here.</P>

Горния пример ще бъде форматиран по подобен начин на този, показан по-долу:

Several emphasized
words appear here.

Ако към вътрешноредовият елемент са прикачени полета, рамки, уплътнение или текстови украшения, те няма да укажат ефект на местата, където елемента е счупен:

         ----------
Several |emphasized
         ----------
-----
words| appear here.
-----

(по-горната фигура е леко деформирана, поради употребата на ASCII графика. Вижте глава 4.4, където има описание на това как да се изчислява височината на редовете.

4.3    Заместени елементи

Заместен елемент е елемент, който е заместен от съдържание, което е посочено от него. Например, в HTML, елемента 'img' е заместен от изображение, което е посочено от 'src' атрибута. Може да се предположи, че заместените елементи вървят ръка за ръка със своите свойствени измерения. Ако стойността на свойството 'width' е установена на 'auto', присъщата широчина се използва като широчина на елемента. Ако е зададена стойност, различна от 'auto' в стиловия лист, тази стойност се използва и размера на заместения елемент се променя в зависимост от стойността(метода на промяна на размера ще зависи от media типа). Свойството 'height' се използва по същия начин.

Заместените елементи могат да бъдат или блокови, или вътрешноредови.

4.4    Височина на редовете

Всички елементи притежават 'line-height' свойство, което по същество, дава общата височина на ред от текста. Добавя се място отгоре и отдолу на текста на реда, така че височината на реда да бъде равна на зададената. Например, ако текста е висок 12pt(12 пункта) и 'line-height' свойството е установено на 14pt(14 пункта), допълнително място от 2 пункта се добавя, а именно 1 пункт над и 1 пункт под реда. Празните елементи влияят на тези изчисления по същия начин, по който влияят и елементите със съдържание.

Разликата между размера на шрифта и 'line-height' стойността се нарича leading. Половината от тази стойност се нарича half-leading. След форматирането, всеки ред ще сформира правоъгълна редова кутия.

Ако един ред с текст съдържа области, в които са зададени различни стойности на свойството 'line-height'(поради това, че има вътрешноредови елементи на реда), то всяка от тези области ще има своя-собствена стойност за half-leading съответно отгоре и отдолу. Височината на редовата кутия се определя от разстоянието на най-високата точка в най-високата област до най-ниската точка на най-ниската област. Забележете, че не е задължително горната част и долната част да отговарят на тези на най-високия елемент, тъй като елементите могат да бъдат позиционирани вертикално чрез свойството 'vertical-align'. За да бъде сформиран параграф, всяка редова кутия се поставя веднага след предишния ред.

Нужно е да се подчертае, че ако има уплътнение, рамка или поле над или под незаместените вътрешноредови елементи, това няма да повлияе на височината на реда. С други думи: ако стойността, зададена на 'line-height' е твърде малка за съответното уплътнение или рамка, ще се получи застъпване с текста на други редове.

Заместените елементи(например изображенията) на реда могат да направят редовата кутия по-голяма, ако горната част на заместения елемент(това включва всички уплътнения, рамки или полета) се намира над най-високата област в текста или ако долната част се намира под най-ниската област от текста.

В най-често срещания случай, когато се използва само една стойност за свойството 'line-height' в един параграф, и няма високи изображения, горната дефиниция ще гарантира, че baseline частите на последователните редове се намират на точно такова разстояние по между си, каквото е зададено със свойството 'line-height'. Това е важно, например, когато колони от текст, който е с различен шрифт трябва да бъдат подравнени в таблица.

Забележете, че това не изключва възможността текст на два съседни реда да се застъпва. За свойството 'line-height' може да се зададе стойност, по-малка от тази на височината на текста, като в този случай leading стойността ще е отрицателна. Полезно е, ако знаете, че текста няма да съдържа символни очертания под baseline частта на редовете(т.нар. descender-и)(например, защото съдържа само главни букви), така че редовете могат да бъдат разположени по-близо един до друг.

4.5    Платно

Платното е част от изобразителната област на браузъра, в която документите се визуализират. Нито един структурен елемент на документа не отговаря на платното, поради което възникват два въпроса при форматирането на документа:

  • от къде трябва да се зададат размерите на платното?
  • как да се визуализира празната област, когато документа не заема цялото платно?

Разумен отговор на първия въпрос е, че първоначалната широчина на платното зависи от размера на прозореца, но CSS1 оставя този въпрос в ръцете на браузъра. Също така е разумно да се очаква браузъра да променя широчината на платното, когато размера на прозореца бъде променен, но това също е извън възможностите на CSS1.

HTML разширенията са образували прецедент при втория въпрос: атрибутите на елемента 'body' задават фона на цялото платно. За да бъдат задоволени очакванията на дизайнерите, CSS1 представя специално правило, с което се намира фона на платното:

Ако стойността 'background' на елемента 'html' е със стойност, различна от 'transparent'(прозрачен фон) тогава тя се използва, в противен случай се използва 'background' стойността на елемента 'body'. Ако съответната стойност е 'transparent' визуализирането не се дефинира.

Това правило позволява следния код:

<HTML STYLE="background: url(http://style.com/marble.png)">
<BODY STYLE="background: red">

В примера горе платното ще бъде покрито с изображението "marble.png". Фонът на елемента 'body'(който може и да не покрива напълно платното) ще бъде червен.

Докато не се появят други средства за адресиране на платното, се препоръчва свойствата на платното да се задават чрез елемента 'body'.

4.6    'BR' елементи

Текущите CSS1 свойства и стойности не могат да опишат описанието на елемента 'br'. В HTML, 'br' елемента служи за деклариране на преминаване на нов ред в думите. Фактически, елемента се замества от символ за нов ред. Бъдещите версии на CSS най-вероятно ще могат да се справят с добавено и заместено съдържание, но CSS1-базираните форматори трябва да третират 'br' елемента по специфичен начин.