Как всегда случайно набрел в просторах Интернет на интересный блог одной девушки-дизайнера с не менее интересным именем Inayaili de León Persson.
Более того, эта девушка португальского происхождения родом из Панамы, но родилась она в СССР! С 2008 года живет в Лондоне и работает ведущим веб-дизайнеров в Canonical. Как все запутано!
Но это было лирическое вступление. Переходим к главному. Мне на глаза уже давно попадались описания функции calc() - на CSSTricks (еще не успел прочитать) и на htmlbook (успел прочитать). Последний источник как-то не впечатлил, из-за сухости изложения материала, наверное.
А вот на сайте девушки с таким необычным именем функция calc() описана кратко, но интересно, с примерами. И хоть написана статья была в далеком 2011 году, мне интересно было ее прочитать для себя (и фактически перевести).
Что такое функция calc()
Функция calc() может быть использована для вычисления различных линейных размеров на странице. Например, с ее помощью можно рассчитывать значение границ, margin, padding, кегля и многое другое.
Вычисление ширины объектов может быть чрезвычайно сложной задачей, особенно если макет сайта резиновый; функция calc() уникальная, потому что она позволяет выполнять расчеты внутри самих таблиц стилей CSS.
Функция calc() умеет работать с простейшими математическими операторами:
- сложением +
- вычитанием -
- умножением *
- делением /
Давайте рассмотрим простейший пример работы функции calc():
div{
width: calc(100% - 20px);
}Очень просто, не правда ли? В одной функции может использоваться не один, а несколько математических операторов:
div{
width: calc(100% - 20px + 2px*2);
}В текущей спецификации говориться, что операции умножения и деления имеют приоритет над операциями сложения и вычитания. Это означает, что в примере выше сначала будет вычислено выражение 2px*2, и только затем два оставшихся - сложение и вычитание. Также обратите внимание, что деление на 0 приведет (и должно привести) к ошибке.
Спецификация по функции calc() еще не завершена, но ее основы уже готовы.
Простой пример calc()
Для того, чтобы показать возможности функции calc(), была создана базовая разметка страницы с помощью этой функции.
Разметка состоит из основного контейнера div id=”main” (расположенного слева), колонки справа div id=”accessory” и подвала, помещенного внизу div id=”footer”.
Ниже приведен код этой разметки:
<div class="wrapper">
<div id="main">
<h1>Far far away ...</h1>
<p>Far far away, behind the word mountains ...</p>
</div>
<div id="accessory">
<ul>
<li><a href="#">Far far away ...</a></li>
<li><a href="#">Separated they live ...</a></li>
<li><a href="#">A small river named ...</a></li>
</ul>
</div>
<div id="footer">Visit the article ...</div>
</div>После применения не требующего объяснений (надо надеяться) простого сброса CSS-стилей (полный код CSS-сброса смотрите в исходном коде примера - Calc Examples), установки базового шрифта и внешнего вида ссылок, стилизуем элемент body:
body {
background: #e8eadd;
color: #3c323a;
padding: 20px;
}После этого я говорю, что основной контейнер div.wrapper должен занимать всю ширину своего контейнера (100%) за вычетом 40 пикселей и располагаться горизонтально, по центру:
.wrapper{
width: 1024px; /* Откат для браузеров, которые не поддерживают функцию calc() */
width: -moz-calc(100% - 40px);
width: calc(100% - 40px);
margin: auto;
}В коде выше была добавлена строка отката для браузеров, которые не поддерживают работу с функцией calc(), а также браузерный префикс -moz- для браузера Firefox 4.
Затем устанавливается ширина, границы, плавание влево и margin для основного блока с контентом div#main:
#main{
border: 8px solid #b8c172;
float: left;
margin: 0 20px 20px 0;
padding: 20px;
width: 704px; /* Откат для браузеров, которые не поддерживают функцию calc() */
width: -moz-calc(75% - 20px*2 - 8px*2);
width: calc(75% - 20px*2 - 8px*2);
}Давайте разберемся с функцией calc() в этом примере кода. Здесь я хочу, чтобы ширина контейнера div#main равнялась 75% (75% от ширины контейнера-родителя, не забывайте об этом!).
Но из этой ширины мне необходимо вычесть padding слева и справа от контейнера - 20px2, а также ширину границы с обоих сторон - 8px2.
Переходим к боковой панели div#accessory и говорим ей, что она должна занимать оставшуюся ширину контейнера-родителя в 25%. Но при этом также должны учитываться ширина границы этого блока, margin-right: 20px и padding. Блок будет “плавать” вправо:
#accessory{
border: 8px solid #b8c172;
float: right;
padding: 10px;
width: 208px; /* Откат для браузеров, которые не поддерживают функцию calc() */
width: -moz-calc(25% - 10px*2 - 8px*2 -20px);
width: calc(25% - 10px*2 - 8px*2 -20px);
}Если более подробно разобрать выражение calc(25% - 10px2 - 8px2 -20px), то увидим, что из первоначальной ширины 25% вычитается padding справа и слева 10px2, ширина правой и левой сторон границы этого блока 8px2, а также правый margin для блока-контейнера div#main.
Блок-подвал footer просто имеет ширину, равную всей ширине блока-родителя. Я думаю, что описывать стили для этого блока излишне.
Если уменьшать размер окна браузера, то при достижении им определенной величины ширина боковой панели div#accessory становиться слишком маленькой, что нарушает дизайн страницы.
Поэтому в код ниже был добавлен простой media query, с помощью которого у блоков div#main и div#accessory убирается плавание влево-вправо и пересчитывается ширина обоих блоков так, чтобы они занимали 100% ширины блока-родителя за минусом ширины границ и соответствующих padding:
@media screen and (max-width: 768px){
#main, #accessory{
float: none;
}
#main{
margin-right: 0;
width: -moz-calc(100% - 20px*2 - 8px*2);
width: calc(100% - 20px*2 - 8px*2);
}
#accessory{
width: -moz-calc(100% - 20px*2 - 8px*2);
width: calc(100% - 20px*2 - 8px*2);
}
}Приведенный выше пример разметки страницы является очень упрощенным. Но есть надежда, что он заинтересует вас и подтолкнет к дальнейшим экспериментам с замечательной функцией calc().
Поддержка браузерами
Функция calc() поддерживается браузером IE9 и Firefox 4 (для которого необходимо указать браузерный префикс -moz-calc()). Я понимаю, однако, что применение этой функции в устаревших браузерах к таким вещам, как анимация, может быть большой проблемой. Но в тоже время, анимация не является жизненно важной необходимостью сайта.
Это не означает, что вы не должны пробовать эту функцию на практике. Ведь разработчики браузеров Firefox и IE предприняли усилия для того, чтобы внести поддержку данной функции в свои браузеры. Доля этих браузеров на мировом рынке самая большая, поэтому, я полагаю, что остальные производители браузеров не останутся долго в стороне.
В своих примерах я предпочла использовать откат в виде абсолютной величины (ширина блока) для браузеров, которые не поддерживают данную функцию.
Дальше переводить не стал, ибо идет сплошная “вода” в виде заключения и всяческих пожеланий, не относящаяся к делу.