Box-sizing: переключаем блочную модель
Как известно, в IE6 размеры блока считаются не так как в остальных баузерах и включают в себя не только контентную часть элемента, но и внутренние отступы с границами (см. статью Блочная модель в IE6). Но иногда такой подсчет будет весьма кстати!
Задача
Сделать, чтобы блок растягивался на 50% ширины родителя и при этом имел внутренние отступы padding и границу border.
Решение 1. Стандартное — обертка.
Добавляем дополнительный контейнер-обертку. Задаем ему ширину 50% родителя. Самому блоку задаем внутренние отступы и границы (не задавая ширину). Таким образом внутренний блок займет все доступное пространство обертки без учета внутренних отступов и границ. При изменении размеров внутренних отступов и границ, размер внешнего блока меняться не будет.
Этот блок имеет размеры не зависящие от внутренних отступов
.wrap{ width: 50%; } .element{ padding: 10px; border: 5px; }
Главный недостаток метода — дополнительный контейнер.
Решение 2. Для блока с абсолютным позиционированием.
Для блоков с position: absolute можно использовать прием описанный в статье Два в одном: позиция + размеры. Код будет таким:
Этот блок имеет размеры не зависящие от внутренних отступов
.parent{ position: relative; } .element{ position: absolute; left:0px; right:50%; padding: 10px; border: 5px; } * html .element{ width: expression( parentNode.offsetWidth - 0 + 'px'); }
Преимущество — обошлись без контейнера.
Недостки — способ работает только для блоков спозиционированных абсолютно, используется expression.
Решение 3. Прогрессивное.
Как ты, конечно, догадался, речь идет о CSS3. А точнее, о CSS3 свойстве box-sizing. Это свойство позволяет переключаться между разными блочными моделями.
Это свойство по умолчанию имеет значение content-box и размеры элемента не включают внутренние отступы и границы (такая блочная модель по умолчанию принята во всех современных браузерах кроме IE6). При изменении значения на border-box размеры блока рассчитываются так как в IE6, т.е. содержат в себе внутренние отступы и границы элемента.
Теперь, чтобы добиться требуемого эффекта, для элемента нужно написать всего одну строчку:
.element { box-sizing: border-box; }
Но это только в теории! А на практике эту строчку поймут только Opera 7+ и IE8+. Для других популярных браузеров придется использовать это свойство с вендорными префиксами: -moz-box-sizing для Firefox 1+ и -webkit-box-sizing для Safari 3+ и Chrome.
Итого для нашего блока получим:
.element { width:50%; padding: 10px; border: 5px; -moz-box-sizing: border-box; /*Firefox 1+*/ -webkit-box-sizing: border-box; /*Safari 3+, Chrome 1+*/ box-sizing: border-box; /*Opera 7+, IE8+*/ }
IE6 свойство box-sizing, естественно, не поймет, но в нашем случае это и не нужно! Ведь в режиме Quirks Mode у него размеры элемента по умолчанию включают отcупы и границы.
Для IE7 (и IE6 в режиме Almost Standards Mode) все-таки придется использовать костыль — например, такой expression:
.element { z-index: expression( /* оптимизированный expression, который сработает только при загрузке страницы */ runtimeStyle.zIndex = 1, runtimeStyle.width = parentNode.offsetWidth/2 - 40 + 'px');} }
В боевых условиях expression выносим в отдельный css файл, подключаемый с помощью условных комментариев.
Проверено в:
Выводы
Если тебя не пугает expression для IE7, можно использовать box-sizing для решения подобных задач. Это позволит избавится от лишнего контейнера в HTML файле. Хотя, конечно, для резиновых сайтов использование такого expression вариант неудачный — оптимизированный expression сработает только один раз при загрузке докуманта, а неоптимизированный может порядочно тормозить.
Материалы
- CSS3 и блочная модель — прислал SelenIT
- Box model tweaking