Я впервые обнаружил calc()
функционировать более чем четыре года назад, благодаря CSS3 Нажмите Chart1, И я был абсолютно рад видеть, что основную математических вычислений —сложение, вычитание, умножение и деление —нашел свой путь в CSS .
Много людей думают, препроцессоры полностью покрыть область логики и вычислений, но calc()
Функция может сделать что-то, что не может препроцессора: смешать любой вид units,Препроцессоры можете смешать только единицы с фиксированным соотношением между ними, как и угловых единиц, единиц времени, частоты, частей разрешением и некоторых единиц длины .
1turn
всегда 360deg
100grad
всегда 90deg
И 3.14rad
всегда 180deg
,1s
всегда 1000ms
И 1kHz
всегда 1000Hz
,1in
всегда 2.54cm
или 25.4mm
или 96px
И 1dppx
всегда эквивалентна 96dpi
,Вот почему препроцессоры сможете конвертировать между them2и смешивать их в вычислениях.Тем не менее, препроцессоры не может решить, сколько 1em
или 1%
или 1vmin
или 1ch
в пикселях, так как им не хватает контекста .
Давайте посмотрим на несколько основных примеров:
div {
font-size: calc(3em + 5px);
padding: calc(1vmax + -1vmin);
transform: rotate(calc(1turn - 32deg));
background: hsl(180, calc(2*25%), 65%);
line-height: calc(8/3);
width: calc(23vmin - 2*3rem);
}
В некоторых случаях, мы могли бы использовать переменные в calc()
функция.Это вполне возможно с наиболее популярными препроцессоров .
Во-первых, с Sass3, У нас есть переменная интерполяции, как с любой другой родной функции CSS:
$a: 4em
height: calc(#{$a} + 7px)
@a: 4em;
height: ~"calc(@{a} + 7px)";
a = 4em
height: "calc(%s + 7px)" % a
Мы также можем использовать родной CSS variables6, Но обратите внимание, что это работает только в Firefox 31 на данный момент, потому что нет другой браузер не поддерживает CSS переменных: еще .
--a: 4em;
height: calc(var(--a) + 7px);
Мы должны помнить несколько вещей в виду, чтобы убедиться, что calc()
Функция работает.Во-первых, деление на ноль, очевидно, не будет работать.Имея пространство между именем функции и скобкой не допускается.И плюс и минус операторы должны быть окружены белым пространстве.Это означает, что следующий не действительны:
calc(50% / 0)
calc (1em + 7px)
calc(2rem+2vmin)
calc(2vw-2vh)
Оператор calc()
функция должна работать в качестве значения во всех местах, где числовое значение, с или без заданных единицах, работает.Тем не менее, в то время как основная поддержка является действительно хорошим, мы могли бы запустить в бедув зависимости от whereмы используем его.Давайте посмотрим на несколько примеров, в том числе то, что поддержка у них проблемы (если таковые имеются) и являются ли они, в конечном счете лучшее решение .
Легче понять вычисленные значения Link
Скажем, мы хотим радуги градиент.CSS-за этого действительно simple7:
background: linear-gradient(#f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
Но эти значения HEX не имеет смысла.Использование hsl()
и calc()
, Хотя и более многословен, делает вещи гораздо яснее:
background: linear-gradient(hsl(calc(0*60), 100%, 50%),
hsl(calc(1*60), 100%, 50%),
hsl(calc(2*60), 100%, 50%),
hsl(calc(3*60), 100%, 50%),
hsl(calc(4*60), 100%, 50%),
hsl(calc(5*60), 100%, 50%),
hsl(calc(6*60), 100%, 50%));
К сожалению, с помощью calc()
в hsl()
rgb()
hsla()
или rgba()
не работает в данный момент в Firefox или Internet Explorer8(IE), который означает, что это версия работает только в WebKit browsers9на данный момент.Так, в практике, это, вероятно, еще лучше, чтобы препроцессор обрабатывать все это на данный момент, в том числе вычислений.И лучше всего об использовании препроцессора является то, что позволяет нам генерировать список в loop10:
$n: 6;
$l: ();
@for $i from 0 through $n {
$l: append($l, hsl($i*360/$n, 100%, 50%), comma);
}
background: linear-gradient($l);
Более эффективные стола градиент для гибких элементов Link
Скажем, мы хотим фон с фиксированной 1em
полоса и в верхней и в нижней части.Единственная проблема, что мы не знаем высоту элемента.Одним из решений было бы использовать два gradients11:
background:
linear-gradient(#e53b2c 1em, transparent 1em),
linear-gradient(0deg, #e53b2c 1em, #f9f9f9 1em);
Но мы должны только одним градиент, если мы используем calc()
12:
background:
linear-gradient(#e53b2c 1em, #f9f9f9 1em,
#f9f9f9 calc(100% - 1em),
#e53b2c calc(100% - 1em));
Это должно работать нормально во всех браузерах, которые поддерживают calc()
и градиенты, и потому, что она включает в себя смешивание единиц, это не то, что препроцессоры есть эквивалент.Мы можем, однако, сделать это легче поддерживать по используя variables13:
$s: 1em;
$c: #e53b2c;
$bg: #f9f9f9;
background:
linear-gradient($c $s,
$bg $s,
bg calc(100% - #{$s}),
$c calc(100% - #{$s}));
Примечание: По некоторым причинам, одна из полос, кажется, слегка размытым и уже, чем другой в Chrome и Opera .
Диагональные полосы градиента Link
Скажем, мы хотим элемент с толстым полосой, проходящей по диагонали с обеих сторон его фактическая диагонали.Мы могли бы сделать это используя процентное основе stops14:
background:
linear-gradient(to right bottom,
transparent 42%, #000 0, #000 58%,
transparent 0);
В этом случае, ширина полосы будет зависеть от размеров элемента.Иногда, это именно то, что мы хотим.Например, это, как мы делаем вещи, если мы хотели, чтобы воспроизвести флаг в CSS.Добавление немного зеленого, желтого и синего, чтобы выше дает нам flag15, что любители тонкой шоколад, вероятно, признать —флаг Танзания .
background:
linear-gradient(to right bottom,
#1eb53a 38%, #fcd116 0,
#fcd116 42%, #000 0,
#000 58%, #fcd116 0,
#fcd116 62%, #00a3dd 0);
Но что, если мы хотим, чтобы наша диагональная полоса иметь фиксированную ширину, которая не зависит от размеров элемента?Ну, мы должны использовать calc()
и поставить остановки в 50%
минус половина ширины фиксированной полосой и на 50%
плюс половина ширины фиксированной полосой в.Если мы хотим ширина полоса, чтобы быть 4em
, То мы бы так:
background:
linear-gradient(to right bottom,
transparent calc(50% - 2em),
#000 0,
#000 calc(50% + 2em),
transparent 0);
Вы можете проверить эту live18путем изменения размера окна.Размеры элемента выражены в единицах окна просмотра, и, следовательно, изменить с просмотра, но диагональной полосой всегда остается той же ширины .
Позиционирование Дети известных размеров в середине Link
Вы, вероятно, видели немного trick19абсолютно позиционирования элемента мертвых в середине своего родителя:
position: absolute;
top: 50%;
left: 50%;
margin: -2em -2.5em;
width: 5em;
height: 4em;
С calc()
, Мы можем избавиться от margin
rule20:
position: absolute;
top: calc(50% - 2em);
left: calc(50% - 2.5em);
width: 5em;
height: 4em;
И мы можем сделать это легче поддерживать, используя переменные для ширины и height21:
$w: 5em;
$h: 4em;
position: absolute;
top: calc(50% - #{.5*$h});
left: calc(50% - #{.5*$w});
width: $w;
height: $h;
Обратите внимание, что, в то время как с помощью смещения (top
, left
) для начальной позиционирования является безопасным, если вы планируете анимировать положение элемента после этого, вы должны использовать вместо преобразования.Это потому, что изменение преобразования требует только compositing22, Тогда как изменение смещения также вызывает relayout и перекрасить —Таким образом, ухудшая производительность .
Система координат и сетки с происхождения в середине Link
После обнаружения в четыре значение background-position
23, Я не был слишком заинтересованы в использовании calc()
в положении фоны относительно правой или нижней части элемента.Но calc()
Оказалось, чтобы быть отличным решением для размещения определенной точки фона по отношению к середине элемента .
Пару лет назад, я обнаружил, желающих создать фон, который представляет собой систему координат с сеткой сзади и, происхождение бы мертвым в середине экрана .
Система координат и сетки part26были легко достичь:
background-image:
linear-gradient(#e53b2c .5em, transparent .5em) /* horizontal axis */,
linear-gradient(90deg, #e53b2c .5em, transparent .5em) /* vertical axis */,
linear-gradient(#333 .25em, transparent .25em) /* major horizontal gridline */,
linear-gradient(90deg, #333 .25em, transparent .25em) /* major vertical gridline */,
linear-gradient(#777 .125em, transparent .125em) /* minor horizontal gridline */,
linear-gradient(90deg, #777 .125em, transparent .125em) /* minor vertical gridline */;
background-size:
100vw 100vh, 100vw 100vh,
10em 10em, 10em 10em,
1em 1em, 1em 1em;
Но как мы делаем происхождение фоне мертвым в середине, а не в верхнем левом углу?Во-первых, background-position: 50% 50%
не будет работать, потому что это делает 50% 50%
точка градиента совпадает с 50% 50%
точка элемента, но линии находятся в верхней и в левой части градиентов, соответственно.Решение заключается в использовании calc()
и положение градиентов, так что их верхний левый почти в середине просмотра, просто смещение всверху и слева от оси половину ширины или линии сетки в:
background-position:
0 calc(50vh - .25em), calc(50vw - .25em),
0 calc(50vh - .125em), calc(50vw - .125em),
0 calc(50vh - .0625em), calc(50vw - .0625em);
Опять же, мы можем сделать все это в сопровождении больше с помощью переменных:
Поддержание Aspect Ratio и прикрытии __26 Viewport Dimension |Link
Одна вещь, я всегда хотел при создании HTML слайды было для каждого слайда, чтобы быть коробка определенной фиксированной пропорции, которые всегда покрывает по крайней мере, одно измерение в окне просмотра, и это, конечно, в середине вдоль другой оси.
Давайте начнем, предполагая, что нужное соотношение для слайдов 4: 3, и что я на широкоэкранном дисплее.Это означает, что слайды покрытия видовой вертикально, но все еще есть некоторые места на левом и правом .