От автора: CSS3 функция calc() позволяет выполнять математические операции над значениями свойств. Можно, например, не задавать ширину элемента в статических пикселях, а использовать функцию calc(), чтобы указать, что ширина складывается из двух числовых значений.
1 2 3 |
.foo { width: calc(100px + 50px); } |
Почему calc()?
Если вы используете препроцессоры типа SASS, пример сверху вам должен быть знаком.
1 2 3 4 5 6 7 8 9 10 |
.foo { width: 100px + 50px; } // Или с помощью SASS переменных $width-one: 100px; $width-two: 50px; .bar { width: $width-one + $width-two; } |
Функция calc() лучше по двум причинам. Во-первых, можно совмещать разные единицы измерения. Можно комбинировать относительные единицы, такие как проценты и vw, с абсолютными единицами типа пикселей. Например, можно написать выражение, в котором из процентного значения будет вычитаться значение в пикселях.
1 2 3 |
.foo { width: calc(100% - 50px); } |
В примере выше элемент .foo всегда будет на 50px уже 100% ширины его родителя.
Во-вторых, в calc() вычисленное значение является самим выражением, а не конечным значение выражения. При работе с математическими выражениями в CSS препроцессорах значение, передаваемое в браузер, является конечным значением выражения.
1 2 3 4 5 6 7 8 9 |
// Значение, заданное в SCSS .foo { width: 100px + 50px; } // Скомпилированный CSS и вычисленное значение в браузере .foo { width: 150px; } |
А с функцией calc() значение, которое парсится браузером, это само выражение calc().
1 2 3 4 5 6 7 8 9 |
// Значение, заданное в CSS .foo { width: calc(100% - 50px); } // Вычисленное значение в браузере .foo { width: calc(100% - 50px); } |
Это значит, что значения в браузере могут быть более динамичными, они могут адаптироваться под изменения вьюпорта. Можно создать элемент с высотой вьюпорта минус абсолютное значение, и он будет адаптироваться под изменения вьюпорта.
Использование calc()
Функцию calc() можно использовать для сложения, вычитания, умножения и деления числовых значений свойств. Ее можно использовать с типами данных length, frequency, angle, time, number и integer.
Пара примеров:
1 2 3 4 5 6 7 |
.foo { width: calc(50vmax + 3rem); padding: calc(1vw + 1em); transform: rotate( calc(1turn + 28deg) ); background: hsl(100, calc(3 * 20%), 40%); font-size: calc(50vw / 3); } |
Вложенность функций calc()
Функцию calc() можно вкладывать. Однако внутренние функции будут расцениваться, как просто выражения в скобках. Разберем для примера выражение ниже:
1 2 3 |
.foo { width: calc( 100% / calc(100px * 2) ); } |
Вычисленное значение этой функции будет следующим:
1 2 3 |
.foo { width: calc( 100% / (100px * 2) ); } |
Создание фолбека
Функция calc() довольно хорошо поддерживается.
Если браузер не поддерживает значение в виде функции calc(), игнорируется пара свойство-значение. То есть для браузеров без поддержки можно с легкостью задать фолбек в виде статического значения.
1 2 3 4 |
.foo { width: 90%; /* Фолбек для старых браузеров */ width: calc(100% - 50px); } |
Когда можно использовать calc()?
Функция calc() полезна во многих ситуациях.
Пример 1 – центрирование элементов
Функция calc() дает нам еще один способ решения старой-старой проблемы с центрированием элементов по горизонтали и вертикали внутри контейнера. Если нам известны размеры дочерних элементов, обычно можно использовать отрицательные margin’ы для сдвига элементов на половину высоты или ширины, вот так:
1 2 3 4 5 6 7 8 |
// Если размеры .foo составляют 300px в высоту и 300px в ширину .foo { position: absolute top: 50%; left: 50%; marging-top: -150px; margin-left: -150px; } |
С помощью calc() центрировать элемент можно всего лишь с помощью свойств top и left.
1 2 3 4 5 |
.foo { position: absolute top: calc(50% - 150px); left: calc(50% - 150px); } |
Если подключить flexbox, такие методы нам не понадобятся. Однако в случаях, когда нельзя использовать flexbox (например, если элемент нужно абсолютно или фиксировано спозиционировать), этот метод будет очень полезен.
Пример 2 – создание базового размера сетки
С помощью calc() можно создать сетку, подстраивающуюся под вьюпорт в rem единицах. Это можно сделать, установив размер шрифта корневого элемента в виде дроби относительно ширины вьюпорта.
1 2 3 |
html { font-size: calc(100vw / 30); } |
Теперь 1rem будет равен 1/30 ширины вьюпорта. Любой текст на странице будет автоматически изменяться вместе с вьюпортом. На экране всегда будет одно и то же количество текста независимо от размера вьюпорта.
Если нетекстовым элементам на странице задать размеры в rem, они будут вести себя так же. Элемент шириной 1rem всегда будет занимать 1/30 ширины вьюпорта.
Пример 3 – ясность
Функцию calc() можно использовать для упрощения вычислений, чтобы они были более понятными. Например, если группа элементов должна занимать 1/6 от ширины родителя, можно, конечно, написать вот так:
1 2 3 |
.foo { width: 16.666666667%; } |
Но намного понятнее будет, если записать код в такой форме:
1 2 3 |
.foo { width: calc(100% / 6); } |
С calc() можно делать еще очень много чего, например, можно создать систему сеток. Определенно, это одна из полезнейших функций в CSS.
Источник: //bitsofco.de/
Редакция: Команда webformyself.