Замечательная функция calc()

Reading time ~8 minutes

Как всегда случайно набрел в просторах Интернет на интересный блог одной девушки-дизайнера с не менее интересным именем Inayaili de León Persson.

Более того, эта девушка португальского происхождения родом из Панамы, но родилась она в СССР! С 2008 года живет в Лондоне и работает ведущим веб-дизайнеров в Canonical. Как все запутано!

Но это было лирическое вступление. Переходим к главному. Мне на глаза уже давно попадались описания функции

1
calc()
- на CSSTricks (еще не успел прочитать) и на htmlbook (успел прочитать). Последний источник как-то не впечатлил, из-за сухости изложения материала, наверное.

А вот на сайте девушки с таким необычным именем функция

1
calc()
описана кратко, но интересно, с примерами. И хоть написана статья была в далеком 2011 году, мне интересно было ее прочитать для себя (и фактически перевести).

Что такое функция calc()

Функция

1
calc()
может быть использована для вычисления различных линейных размеров на странице. Например, с ее помощью можно рассчитывать значение границ,
1
margin
,
1
padding
, кегля и многое другое.

Вычисление ширины объектов может быть чрезвычайно сложной задачей, особенно если макет сайта резиновый; функция

1
calc()
уникальная, потому что она позволяет выполнять расчеты внутри самих таблиц стилей CSS.

Функция

1
calc()
умеет работать с простейшими математическими операторами:

  • сложением
    1
    
    +
    
  • вычитанием
    1
    
    -
    
  • умножением
    1
    
    *
    
  • делением
    1
    
    /
    

Давайте рассмотрим простейший пример работы функции

1
calc()
:

div{
    width: calc(100% - 20px);
  }

Очень просто, не правда ли? В одной функции может использоваться не один, а несколько математических операторов:

div{
  width: calc(100% - 20px + 2px*2);
}

В текущей спецификации говориться, что операции умножения и деления имеют приоритет над операциями сложения и вычитания. Это означает, что в примере выше сначала будет вычислено выражение

1
2px*2
, и только затем два оставшихся - сложение и вычитание. Также обратите внимание, что деление на 0 приведет (и должно привести) к ошибке.

Спецификация по функции

1
calc()
еще не завершена, но ее основы уже готовы.

Простой пример calc()

Для того, чтобы показать возможности функции

1
calc()
, была создана базовая разметка страницы с помощью этой функции.

Разметка состоит из основного контейнера

1
div id="main"
(расположенного слева), колонки справа
1
div id="accessory"
и подвала, помещенного внизу
1
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), установки базового шрифта и внешнего вида ссылок, стилизуем элемент

1
body
:

body {
  background: #e8eadd;
  color: #3c323a;
  padding: 20px;
}

После этого я говорю, что основной контейнер

1
div.wrapper
должен занимать всю ширину своего контейнера (100%) за вычетом 40 пикселей и располагаться горизонтально, по центру:

.wrapper{
  width: 1024px; /* Откат для браузеров, которые не поддерживают функцию calc() */
  width: -moz-calc(100% - 40px);
  width: calc(100% - 40px);
  margin: auto;
}

В коде выше была добавлена строка отката для браузеров, которые не поддерживают работу с функцией

1
calc()
, а также браузерный префикс
1
-moz-
для браузера Firefox 4.

Затем устанавливается ширина, границы, плавание влево и

1
margin
для основного блока с контентом
1
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);
}

Давайте разберемся с функцией

1
calc()
в этом примере кода. Здесь я хочу, чтобы ширина контейнера
1
div#main
равнялась 75% (75% от ширины контейнера-родителя, не забывайте об этом!).

Но из этой ширины мне необходимо вычесть

1
padding
слева и справа от контейнера -
1
20px*2
, а также ширину границы с обоих сторон -
1
8px*2
.

Переходим к боковой панели

1
div#accessory
и говорим ей, что она должна занимать оставшуюся ширину контейнера-родителя в 25%. Но при этом также должны учитываться ширина границы этого блока,
1
margin-right: 20px
и
1
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);
}

Если более подробно разобрать выражение

1
calc(25% - 10px*2 - 8px*2 -20px)
, то увидим, что из первоначальной ширины 25% вычитается padding справа и слева
1
10px*2
, ширина правой и левой сторон границы этого блока
1
8px*2
, а также правый
1
margin
для блока-контейнера
1
div#main
.

Блок-подвал

1
footer
просто имеет ширину, равную всей ширине блока-родителя. Я думаю, что описывать стили для этого блока излишне.

Если уменьшать размер окна браузера, то при достижении им определенной величины ширина боковой панели

1
div#accessory
становиться слишком маленькой, что нарушает дизайн страницы.

Поэтому в код ниже был добавлен простой

1
media query
, с помощью которого у блоков
1
div#main
и
1
div#accessory
убирается плавание влево-вправо и пересчитывается ширина обоих блоков так, чтобы они занимали 100% ширины блока-родителя за минусом ширины границ и соответствующих
1
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);
  }
}

Приведенный выше пример разметки страницы является очень упрощенным. Но есть надежда, что он заинтересует вас и подтолкнет к дальнейшим экспериментам с замечательной функцией

1
calc()
.

Поддержка браузерами

Функция

1
calc()
поддерживается браузером IE9 и Firefox 4 (для которого необходимо указать браузерный префикс
1
-moz-calc()
). Я понимаю, однако, что применение этой функции в устаревших браузерах к таким вещам, как анимация, может быть большой проблемой. Но в тоже время, анимация не является жизненно важной необходимостью сайта.

Это не означает, что вы не должны пробовать эту функцию на практике. Ведь разработчики браузеров Firefox и IE предприняли усилия для того, чтобы внести поддержку данной функции в свои браузеры. Доля этих браузеров на мировом рынке самая большая, поэтому, я полагаю, что остальные производители браузеров не останутся долго в стороне.

В своих примерах я предпочла использовать откат в виде абсолютной величины (ширина блока) для браузеров, которые не поддерживают данную функцию.

Дальше переводить не стал, ибо идет сплошная “вода” в виде заключения и всяческих пожеланий, не относящаяся к делу.


Ошибка с версией Node.js

Довольно часто в своей практике сталкиваюсь с такой ошибкой, когда запускаю локально сторонний проект:```bash$ npm run start> dom-moving-...… Continue reading

Mangling Angular

Published on February 15, 2024

Constructor parameter without access modifier

Published on February 04, 2024