14 ноября, 2008

CSS3 и блочная модель

Это так мило и забавно, и связано со старыми добрыми временами, когда нужно было верстать под IE5.

Блочная модель (box model)

Думаю все, кто начинал верстать, столкнулись с тем, что модель вычисления ширины блока вместе со всякими padding и border не очень логична.

box mdoelсиний блок 200px на 200px — контент. А padding и border, как видно, добавлены «извне».
Такова модель w3c.
Скриншот сделан в Firebug.
Еще можно посмотреть иллюстрацию

Да, есть много разных интересных пояснений и метафор, вроде бы делающих это логичным. Мол, задавая ширину, мы имеем ввиду содержимое и т. д. Но давайте смотреть правде в глаза, каждый кто начинал верстать считал это странным. Хотя бы потому что это странно.

Нет, ну правда: вы задаете колонке ширину 100 пикселей, и небольшую границу в 2 пикселя.
И, вуаля, ширина уже 104 пикселя!
Почему? Если я сказал, чтобы она была 100? =)
Для тех кто не в курсе: если это сделать в ИЕ5, то ширина блока останется 100 пикселей.

Если продавщица хочет больше пространства в коробке, она просто кладет туда меньше товара. А не увеличивает коробку волшебной палочкой. Так работает этот мир.

Вдобавок, все дизайнеры при отрисовке макетов думают майкрософтовской моделью, она интуитивна. А мы потом это верстаем.

Общепринятое пояснение: width — это не ширина «блока», а ширина его «содержимого». Что само по себе красиво в своей алогичной противоречивости. Надеюсь я применил достаточно букв, чтобы все поняли, что мне модель w3c не нравится.

Не то чтобы я винил кого-то, просто так сложилась история стандарта, просто в w3c на тот момент было слишком много технарей. Может быть разработчики броузеров даже сэкономили на этом пару строк кода. И, наверное, кому-то тогда так было проще.
Накипело, не упустил повод высказаться. ;)
Но, забавно не это.

В чем забава?

Забава в том, что на данный момент все современные броузеры (включая IE8 Beta) поддерживают свойство box-sizing. Его смысл: переключать блочную модель от W3C-шной к traditional (или от microsoft). Я сделал специальный пример, где хорошо видно, как лишь с помощью CSS в Safari, IE8, Firefox, Konqueror, Chrome и Opera можно сымитировать старую добрую блочную модель от IE5. Это правда круто, и могло бы сэкономить сотни тысяч дивов-оберток в наших верстках.

И… начинают появляться посты с обсуждением новой модели. Удивительно, неужели и правда можно задавать границу в 2 пикселя, а ширина блока по прежнему будет 100! Ура! CSS3 принесла нам еще одно полезное свойство!
Блочная модель 10-летней давности возвращается!

В конце

Я уже года три не вспоминал о блочной модели, я её просто запомнил. Но всплеск интереса к «новой» удобной блочной модели меня сильно позабавил.
Это не критика W3C, все равно я буду играть по их правилам, скорее просто любопытные наблюдения за тем как всё возвращается на круги своя. =)

P.S.: я называл модел «блочной», но это вольный перевод, её еще называют коробочной, боксовой, и чаще всего css box model.

И, вот просто интересно, кому-то кажется стандартная блочная модель логичной? Правда очень любопытны обоснования.

Мысли, Общие

Комментарии(41) к “CSS3 и блочная модель”

1. 14 ноября | Dimox

Я не застал те времена, когда верстали под IE 5-й версии, поэтому сразу привык к модели w3с. По твоим примерам прекрасно видно, что логичнее было бы так, как было раньше, в IE5. Как ты уже отметил, на практике действительно очень часто приходится прибегать к дополнительным контейнерам, когда необходимы border и padding. Поэтому также считаю модель с использование box-sizing более удобной и правильной. Жаль, что применять ее повсеместно получится еще не скоро (вот бы неожиданно исчезли IE6 и IE7 :).

2. 14 ноября | Арнольд

О! Ооо! Это очень хорошая новость.

Нет, ну правда: вы задаете колонке ширину 100 пикселей, и небольшую границу в 2 пикселя.
И, вуаля, ширина уже 102 пикселя!
Почему? Если я сказал, чтобы она была 100? =)

Подписываюсь под каждым словом. Меня это тоже одно время очень возмущало… Сейчас я уже смирился с этим, но так хотелось вернутся к “интуитивной майкрософтской модели”… Возможно, именно она — единственный (или, по крайней мере, один из немного) плюс IE.

Кстати, если не ошибаюсь, в IE 6 тоже действует такая модель… Или я путаю…

3. 14 ноября | Тормоз

Да, блочная модель от microsoft удобнее, но… не возникнет ли ещё большая путаница? Одни браузеры будут поддерживать w3c, другие ms, третьи и то и другое. Всё же лучше придерживаться одного стандарта, пусть он и не идеален.
А мечту с блоком 100% ширины и отступами вполне можно осуществить и стандартно. Просто отступы тоже должны быть в процентах. Хотя, конечно, это не всегда устраивает.

4. 14 ноября | Тормоз

Ударения что-то не понимает форма комментариев. Там было “бОльшая путаница”.

5. 14 ноября | empty

видимо мне одному существующая модель кажется вполне логичной… :)
*задумался о логичности своей логики*

6. 14 ноября | pepelsbey

Существующая блочная модель от W3C — это порождение программистского сознания, что-то вроде нумерации с нуля. Раз сказано «ширина», значит это «ширина», безо всяких обобщений и группировок с другими свойствами.

Т.е. с точки зрения формального описания блока — это наиболее правильно.

А вот если говорить об удобстве, о практике, о дальнейшем развитии… То да — блочная модель border-box кажется гораздо удобнее. Именно удобнее в применении, но не логичнее для формального описания.

Поэтому вполне очевидно, что люди, которые придумывали CSS на коленке, не могли знать и предусмотреть всего.

В общем, ждём кончины IE6–7 и резво начинаем жить хорошо, и не только из-за box-sizing…

7. 14 ноября | akella

@Тормоз: Думаю путаницы не будет. Ведь все броузеры сейчас уже поддерживают модел W3C, просто с помощью этого CSS свойства мы сможем переключать её на модель IE5 в нужных нам местах.
Про 100% - да! Но эти дизйнеры вечно делают блоки с процентной шириной и пиксельными отступами =) Как сговорились.

@empty: Напротив! Буду рад услышать пояснения, я уважаю все мнения, но правда, не очень понимаю логику)

@Арнольд: ХТМЛ таги работают ;) так что можно писать как мы привыкли.
В ИЕ6 тоже есть такая модель, но только в Quirks Mode

8. 14 ноября | Максим Покровский

Когда я впервые увидел такое разногласие в IE6 (Quirks Mode) и FF, меня это тоже неприятно поразило. Не логично ведь.

9. 14 ноября | Андрей Лось

Padding и border пожалуй, действительно стоит запихнуть внутрь. Но margin-то при любых раскладах должен быть за пределами блока?

10. 14 ноября | Денис Чистяков

Спасибо за как всегда полезный и очень актуальный пост.
Вот буквально вчера для текстарии все это прописывал, что бы от изменения размера бордера при фокусировке (аля Сафари) «полезное» пространство не «прыгало».
Уже не актуальный: -ms-box-sizing: border-box; — уберу.
Но, вот я только так понял, что опера (по крайней мере Opera 9.52, в которой я смотрел) все равно пересчитывает неверно (
Может для нее есть какое-нить спец -o–свойство, никто случайно не подскажет?

11. 14 ноября | akella

Свойство нужно все же использовать пока с осторожностью - ИЕ6-7 его не поддерживает =(
А для оперы должно работать обычное box-sizing. Мм, странно что не сработало, и можно даже попробовать префикс. Может свойство появилось только в 9.6?

12. 14 ноября | cr_

как-то недавно тоже сталкивался с необходимостью изменения блочной модели. но для этого, как говорилось, надо ие6 перевести в Quirks Mode, что может породить большие проблемы в дальнейшем. только остаётся молиться чтобы он таки канул в лету :)

а почему, кстати, -ms-box-sizing:border-box не актуален?

13. 14 ноября | Исаак Тынгылчав

В статье существенная неточность. Нормальную бокс-модель поддерживал не только ie5 но и все остальные разработчики, включая Оперу и покойного Нетсекейпа. Чем руководствовались разработчики w3c, упорно настаивая на своей версии, вразрез со сложившейся практикой совершенно непонятно. Ну никак. Почему мнение разработчиков не учитывалось тоже непонятно.
В ссылках которые вы дали эта информация приведена.

14. 14 ноября | akella

@cr IE8 начиная со второй беты поддерживает обычный box-sizng, без префикса

@Исаак спасибо за уточнение. Но я и не говорил что ее поддерживал только ИЕ. Просто одним из лидеров стандартов в те времена был именно он (как ни странно это звучит), и модель эта была предложена разработчиками ИЕ. И именно они продолжали поддерживать модель даже когда все остальные перешли на новую.

А еще, оказывается многие и правда считают модель W3C удобной =). Просто, как сказал pepelsbey, это больше программисткий подход.

15. 14 ноября | Vii

1) как мне кажется w3-модель более логична в “критичных” случаях: берем блок width:5px; + padding:10px; и, что тогда должно получится в ms-модели (контент длинной -5px)?

2) еще, что-то мне подсказывает, что у модели от w3 есть определенное родство с отступами в таблицах (cellpadding): в данном случае padding’ом абсолютно логично делать отступы от рамок, приплюсовывая размеры колонок.

*на правах IMHO >)

16. 15 ноября | Тормоз

Akella, именно поэтому я убеждён, что дизайнер обязательно должен иметь хотя бы базовые знания о вёрстке :) А ещё лучше когда дизайнер и верстальщик в одном лице, и дизайн создаётся в исконно правильном понимании (конструирование), а не так, как у нас в рунете принято (сомнительные красивости).

17. 15 ноября | Тормоз

Андрей Лось, так margin и так за пределами блока.

Vii, точняк! Спасибо за очень правильное и меткое объяснение. Об этом мы и не подумали. А если вообще сделать width: 20px; padding: 30px? Браузеру ничего не останется, как запихнуть контент в третье измерение :)

18. 15 ноября | Михаил

@Тормоз, если мы скрестим дизайнера и верстальщика, то либо получим унылое буэ, либо всё будет делаться крайне долго. Я не говорю, что такой симбиоз не возможен в принципе, но в промышленных масштабах реализуется крайне сложно. Всё-таки Форд не просто так придумал конвейер.

Введение box-sizing, с одной стороны, позволит гибче подходить к вёрстке. Думаю, что не один я сталкивался с проблемой вставки поля ввода с ненулевыми отступами и бордюром шириной в 100% родителя. MS-модель здесь бы очень помогла. С другой стороны, мы получим некоторый геморрой для начинающих и при поддержке чужих проектов. Но самое главное — наверняка какой-нибудь вендор будет игнорировать бордер, или ещё что-нибудь смешное придумает.

19. 15 ноября | akella

наверняка какой-нибудь вендор будет игнорировать бордер, или ещё что-нибудь смешное придумает.

Они уже облажались! Они его все поддерживают! =) (я скрестил пальцы и постучал по дереву)

Мне кажется скрестить очень трудно, и это наверняка утопия, но вот наделить парой базовых знаний, вроде блочной модели, и того как эта таинственная верстка устроена в целом — было бы просто великолепно =)
Хотя при этом я всегда думаю, что если бы дизайнеры знали ограничения, они бы возможно не давали воли своим смелым идеям. А мы, верстальщики не штурмовали сложные проблемы для того чтобы их сверстать. Нам-то конечно легче, но возможно мир лишился бы нескольких клевых дизайнов.
Но, я все равно за их легкую образованность. ;)

20. 15 ноября | Михаил

Лёгкий общеобразовательный курс очень полезен, это правда. Ну хотя бы дать прочесть правила от Ольги Алексашенко (презентация с РИТ-2008 куда-то продолбалась, оказывается).

21. 15 ноября | mihdan

Спасибо за -ms-box-sizing: border-box; Не знал )))

22. 16 ноября | Денис Чистяков

@akella
К сожалению box-sizing:border-box не помог.
Сейчас прописаны следующие свойства:

#comment_form #message {
border:1px solid #999;
height: 120px;
padding: 2px;
width: 100%;

-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-khtml-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#comment_form #message.focus {
border: 2px solid #73a6ff;
}

Соотвественно на onfocus() добавляется класс focus.
Скриншоты: без фокуса, с фокусом, приближенное сравнение.

P.S. Маленький оффтопик, было бы удобно, если бы где нибудь рядом с формой комментирования был перечислен список допустимых HTML тегов, а то вставляешь и надеешься, что вставится, а ведь отредактировать уже нельзя ;)

23. 16 ноября | akella

HTML весь разрешен =)

Выходит на инпуты не распространяется (. Возможно нужно им добавить display:block? По умолчанию то они инлайновые…

24. 16 ноября | Jman

красиво… но пока не умер ИЕ6 остаётся только любоваться

25. 17 ноября | Денис Чистяков

@akella
Да, нет я потом понял в чем проблема )
Точнее — проблемы нет, это просто я заработался наверно, оно отобразилось так как и должно было, т.е. ширина текстарии посчиталась вместе с шириной ее бордера.
Это было сделано, что бы вся форма и подложка не прыгали, а они и не прыгают. Пространство внутри текстарии во всех браузерах уменьшается, просто в опере из-за неактивной полосы прокрутки это стало более заметно, кстати никто не подскажет как ее убрать?

26. 17 ноября | akella

Я сам не пробовал, но возможно поиграться со свойством overflow поможет (hidden, auto..)

27. 17 ноября | Денис Чистяков

Первое, что попробовал — не помогло (
Наверное это особенность оперы.

28. 18 ноября | cssing :: Архив :: Håkon Wium Lie, CSS и educamp

[…] Блочную модель придумал Håkon и Bert Bos. Сказал что вопрос спорный, и что теперь же у всех есть box-sizing, расслабьтесь. Его приверженность к той модели поясняется, вобщем, очень легко. Он технический человек, он уже много лет проверяет почту через emacs. Он shell-guy, про маки сказал, что это не совсем его стиль, да и дорогие они. […]

29. 18 ноября | SelenIT

у модели от w3 есть определенное родство с отступами в таблицах (cellpadding)

По-моему, cellpadding-и ведут себя вполне по традиционной (MS-овской) модели — за исключением случаев, когда они не вмещаются в заданную ширину (проверка: http://silverflame.at.tut.by/cellpadding.html). И вообще весь табличный подход строится на том, что width контейнера задает общую ширину всего, а содержимое уже вынуждено “как-нибудь подстроиться”. По-моему, табличные примеры — как раз аргумент за “старую” боксовую модель…

30. 18 ноября | Денис Чистяков

Маленький оффтопик:
в рассылке новых комментариев на электропочту html-теги записываются через сущности < и >, и получается соответственно, что то типа:

у модели от w3 есть определенное родство с отступами в таблицах (cellpadding)

31. 18 ноября | Денис Чистяков

Блин, тут отрендерилось хорошо.
Вот так приходит: <blockquote>у модели от w3 есть определенное родство с отступами в таблицах (cellpadding)</blockquote>
Хотя возможно это гмейловские выкрутасы )

32. 18 ноября | SelenIT

Вдогонку: я, кажется, понял, какую аналогию cellpadding-а и “стандартной” боксовой модели имел в виду Vii. К ширине, заданной для ячейки, отступы действительно плюсуются всегда.
Но, на мой взгляд, между табличной и CSS-ной моделью есть психологическая разница. В первой мы задаем ширину для элемента (ячейки), а отступы — формально — через свойство контейнера (таблицы)! Т.е. по сути имеем аналог “обертки”. Ну а когда ширина и отступы — свойства одного и того же элемента (таблицы), она ужимает свободное место внутри (пока оно есть) при неизменной ширине, не нарушая интуитивной аналогии с “коробкой продавщицы”.
Пресловутая же CSS-модель (aka box-sizing:content-box) ее-таки нарушает…

33. 17 декабря | Андрей Усачёв

Распечатываю… на стенку в самое видное место!!!

34. 1 января | AMBA

>старую добрую блочную модель от IE5

Помоему в ие6 и ие7 прекрасно работает та же боксовая модель при
!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”
А цссная работает при
!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
Таким образом используя первый доктайп и что-то типа
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Можно добиться как мне кажется именно того что посути и предпологалось. Нет времени на тесты, поправьте если не прав.

У меня есть знакомый дизайнер котороый сам неплохо верстает и разбирается в особенностях браузеров и и.п. получше некоторых верстальщиков. Так что это нормально и производству нисколько не вредит, наоборот он свой дизайн сам сверстает гораздо быстрее, и поправит всё что не сростается тоже..

Дивы тут тоже вырезаются.

35. 1 января | AMBA

Что-то на главной пишет что к этой статье 33 комента когда их 34 и все на месте, какой-то выборочный глюк?

36. 2 января | akella

Такие дизайнеры как правило редкость, о том и разговор.
Да, блочная модель будет вроде бы такая же, но вместе с тем мы получаем и букет кривостей движка quirksmode, например невозможность задавать отступы для инлайн элементов, и не поддержка CSS2. Потому решение не очень хорошее.
Да и вообще это не то чтобы проблема, скорее философский вопрос, который мне захотелось поднять. Решится она сама собой когда умрет ИЕ7

Дивы не вырезаются, а просто отображаются, у меня разрешен HTML в комментариях. Комментарий был на модерации потому не сразу посчитался в кол-ве…

37. 2 января | AMBA

Да, к идеалу можно только стремится. Я не очень жалую дивную вёрстку, поэтому мне эти недостатки не очень мешали. Вопрос может и философский, но задалбывает сидеть с калькулятором высчитывать какой-же ширины получится в итоге страница с десятком падингов :)

38. 14 января | Нові можливості дизайну з CSS3 | Blogoreader – українська блоґосфера - блоґи, новини, статті, персони

[…] CSS3 и блочная модель […]

39. 16 января | webvector

Можно спорить о том, что логичнее, а что нет, но с практической точки зрения
MS-модель даст более чистый код. Плюс ко всему MS-модель более понятна
для большинства. А плюсы w3-модели спорная логичность и меньшее кол-во подсчетов на калькуляторе. И что для вас важнее?

40. 21 января | AMBA

to webvector, а почему меньшее количество подсчётов на колькуляторе? Наоборот помоему. В первом случае я знаю что мне нужна ширина 100, я прописал и не парюсь сколько это будет без падингов и бордеров, а вот во втором… Я вот сейчас делаю проект, в котором по ширине больше 12-ти объектов для сложения, не поверишь сколько я времени убил на подсчёты и пересчёты пока свёл это всё в правильно работающий шаблон.
Единственная радость что меньше надо парится о кроссбраузерности.

41. 8 апреля | Anej

И зачем это надо? проще было добавить такие функции как border inside ( внутри в центре снаружи ) … зачем эти старые модели ( а вот смягчение углов в цсс3 порадовало )

Оставить комментарий

Комментировать

Обязательные поля