- PVSM.RU - https://www.pvsm.ru -

Математика разметки с помощью CSS: разбираемся с calc

За последние годы верстка в интернете развилась из фиксированных дизайнов к адаптивным. Причем, в стилях могут использоваться сразу несколько видов единиц измерений (проценты, em или px). Дизайнерам и разработчикам следует понимать, как это работает [1]. Но было бы удобно оперировать (складыва/вычитать) единицами разной размерности в одном и том же выражении.

Для этого отлично подходит calc [2]. При ее всей мощности, то, как ее можно применять, лучше продемонстрировать на примерах.

image

Vertical Flush Margins

Например, возьмем шикарную фотографию водопада [3] от Stian Klo. Это изображение сдвинуто с отступом в 2rem вправо. Теперь его сделаем адаптивным, установив ширину в 50% от ширины родительского элемента:

<img src="" alt style="width:50%; margin-right: 2rem; float: left;"> <p>Det er et velkjent faktum...

Нам нужно, чтобы вертикальный зазор увеличивался, визуально подчеркивая изображение негативным пространством [4] под ним. Проблема в том, что адаптивность абзацев означает, что они будут “ползать” под картинкой по мере сужения (link) [5]:

image

Есть много способов решить эту проблему, и одним из самых простых будет так, чтобы:

у абзацев рядом с картинкой был левый отступ 50% плюс 2rem.

Используя calc, это будет (link) [6]:

img ~ p { margin-left: calc(50% + 2rem); }

image

calc же позволяет комбинировать разные системы измерения, делая отсуп фиксированным, а картинку — адаптивной.

Full-Width Elements In Padded Containers

Рассмотрим следующий пример — полноширинный элемент (например, картинка) над контентом с внутренним отступом (padding):

<article>
<header>
<img src="" alt>
</header>
<p>Det er et velkjent faktum at lesere distraheres av lesbart innhold på en side når man ser på dens layout...
</article>

CSS:

* { box-sizing: border-box; }
body { background: #000; font-family: Edelsans, sans-serif; line-height: 1.5; }
article { width: 80%; margin: 0 auto; background: #fff; padding: 0 2rem; color: #000; }
article header img { width: 100%; height: auto; }

Проблема заключается в том, что padding элемента также смещает контент внутрь (link) [7]:

image

Это можно исправить путем вычисления ширины с помощью calc:

article header { width: calc(100% + 4rem); margin-left: -2rem; }

4rem, добавленные к ширине , создают -2rem-padding с левой и правой стороны для (link) [8]:

image

Операции

calc поддерживает основные арифметические операции (сложение (+), вычитание (-), умножение ( * ) и деление (/)). Важно помнить о том, что необходимо обрамлять операнды сложения и вычитания пробелами с двух сторон, а между calc и открывающей скобкой ничего не должно быть. Так что в такой форме это будет работать:

width: calc(20% - 1rem);

А это нет:

width: calc(20%-1rem);

И это также:

width: calc (20% - 1rem);

Тому есть простое объяснение: какое-либо число со знаком минус перед ним будет трактоваться, как отрицательное значение.

Возможности и ограничения

Все современные браузеры поддерживают calc для длины в CSS. Теоретически, calc может быть применим в любом месте, где встречаются операции с числами, что дает несколько интересных применений:

.box { background: rgba(255, 0, 0, calc(.3 * 2)); }

image

Или так:

.box { transform: rotate(calc(45deg - 2.31rad)); }

image

Но у всех браузеров есть подводные камни:

  • Chrome и Opera поддерживают все виды использования calc, но до Chrome 38 / Opera 25 вычисления углов не работают
  • На данный момент (ноябрь-декабрь 2014) Firefox поддерживает только вычисления длины и относительные величины (в процентах)
  • Safari / Mobile Safari: calc работает с 3D-трансформациями и вычислениями цветов, но что странно, это не прокатывает с двухмерными трансформациями
  • Android 4.4 поддерживает исключительно операции сложения и вычитания, в более ранних версиях calc не работает вообще. Chrome 38 на Android предлагает полноценную поддержку, как обычный десктопный браузер
  • Internet Explorer 9+ (десктоп/мобильный) достаточно хорошо поддерживает вычисления длины. К сожалению, IE9 падает, если calc используется в CSS-свойстве background-position

К счастью, бОльшая часть браузеров не требуют использовать vendor-префиксы.

Выражаю огромную благодарность Ana Tudor [9] за проведение этих исследований; больше информации о поддержке calc браузерами вы можете найти на caniuse.com [10]

calc так же может быть применяться для вычисления color stops в градиентах.

Заключение

Математически операции всегда были одним из преимуществ препроцессоров, как SASS. Сегодня они еще на шаг впереди, но функции, как calc, сокращают разрыв.

Автор: hodik

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/html/75966

Ссылки в тексте:

[1] работает: http://demosthenes.info/blog/775/Which-CSS-Measurements-To-Use-When

[2] calc: https://developer.mozilla.org/en-US/docs/Web/CSS/calc

[3] фотографию водопада: https://500px.com/photo/58814940/she-flows-ii-by-stian-klo?from=user

[4] негативным пространством: https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%B3%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%82%D0%B2%D0%BE

[5] (link): http://hodik.bitbucket.org/css-calc/vertical-flush-margins-1.html

[6] (link): http://hodik.bitbucket.org/css-calc/vertical-flush-margins-2.html

[7] (link): http://hodik.bitbucket.org/css-calc/full-width-elements-in-padded-containers-1.html

[8] (link): http://hodik.bitbucket.org/css-calc/full-width-elements-in-padded-containers-2.html

[9] Ana Tudor: http://codepen.io/thebabydino

[10] caniuse.com: http://caniuse.com/#search=calc

[11] Источник: http://habrahabr.ru/post/243821/