Багато хто думає, що препроцесори тільки і складаються, що з логіки і обчислень, але функція calc () вміє робити те, чого не може ні один препроцесор в світі: змішувати будь-які одиниці вимірювання. Препроцесори можуть змішувати тільки одиниці вимірювання з фіксованими зв'язками типу кутових одиниць виміру, тимчасових, частотних, одиниць дозволу і деякі одиниці вимірювання довжини.
1turn це завжди 360deg, 100grad - 90deg, а 3.14rad це 180deg. 1s дорівнює 1000ms, 1kHz дорівнює 1000Hz. 1in це 2.54cm або 25.4mm або 96px, а 1dppx завжди дорівнює 96dpi. Саме через таких точних зв'язків препроцесори і можуть в обчисленнях конвертувати одні одиниці в інші і змішувати їх між собою. Однак препроцесор не може обчислити, скільки 1em або 1% або 1vmin або 1ch буде в пікселях, так як відсутній контекст. Розглянемо пару базових прикладів:
У деяких випадках в функції calc () можуть знадобитися змінні. Це можна реалізувати в практично будь-якому препроцесорів. Перший приклад - Sass змінна, працює з будь-якою іншою нативной функцією CSS:
![Починаємо працювати з css calc () (працювати) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-8b45fd66.jpg)
Практичний курс по верстці адаптивного Лендінзі з нуля!
Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів
Можна скористатися і рідними CSS змінними, але вони поки що працюють тільки в Firefox 31+. Решта браузери ще не підтримують CSS змінні.
Щоб функція calc () працювала, як слід, необхідно пам'ятати пару речей. Перше - не можна ділити на нуль, це очевидно. Між словом calc і круглою дужкою не повинно бути пробілів. Оператори, такі як + або -, відокремлюються пробілами з двох сторін. Код нижче неправильний:
Calc () працює як значення в тих місцях, де можна підставити просто значення, не має значення з одиницями вимірювання чи ні. Підтримка у даній функції чудова, але все ж можна зіткнутися з рядом проблем. Все залежить від того, де ми застосовуємо цю функцію. Розглянемо кілька прикладів, серед яких будуть також і проблемні, а також найкращі вирішення цих завдань.
Простий спосіб зрозуміти обчислені значення
Скажімо, ми хочемо зробити градієнт в кольори веселки. В CSS це не важко:
Але HEX значення незрозумілі. За допомогою hsl () і calc () код вище можна переписати в:
На жаль метод calc () всередині однієї з функцій hsl (), rgb (), hsla () або rgba () поки що не працює в Firefox і Internet Explorer. Даний метод працює тільки в WebKit браузерах. На практиці найкраще все це віддати на обчислення препроцесору. А найкрутіше, що в препроцесорів можна формувати список прямо в циклі:
Ефективні фонові градієнти для гнучких елементів
Наприклад, ми хочемо зробити фон, зверху і знизу на якому будуть прямі фіксованого розміру 1em. Проблема в тому, що ми не знаємо точної висоти елемента. В даному випадку можна використовувати два градієнта:
За допомогою функції calc () запис вище можна зробити за допомогою одного градієнта:
Такий запис буде працювати у всіх браузерах з підтримкою calc () і градієнтів. А так як тут використовуються змішані одиниці виміру, то препроцесор не зможе з цим розібратися. Можна ще трохи поліпшити код вище, додамо змінні:
Замітка: У Chrome і Opera одна зі смуг з незрозумілих причин може бути трохи вже інший і злегка розмита.
Діагональні смуги за допомогою градієнта
Наприклад, нам потрібно створити широку діагональну пряму. Це можна зробити за допомогою відсотків.
В даному випадку ширина смуги буде залежати від розміру елемента. Іноді саме це і потрібно. Наприклад, приклад вище відмінно підходить, якщо нам потрібно намалювати прапор. Додамо трохи зеленого, жовтого і блакитного, і ось наш прапор. Любителі шоколаду розпізнають в цьому прапорі прапор Танзанії.
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-43d1f15d.png)
А що, якщо необхідно задати фіксовану ширину смуги, щоб вона не змінювалася в залежності від розміру об'єкта? У функції calc () необхідно задати значення 50% мінус половина від фіксованої ширини смуги і 50% плюс половина ширини смуги. Якщо нам потрібна смуга шириною 4em:
Приклад вище можна протестувати в браузері. пограти з розміром вікна браузера. Розміри прямокутника задані в vmin, тому розмір об'єкта змінюється при зміні розміру вікна браузера. Але діагональна смуга завжди залишається фіксованою ширини.
Позиціонування дочірніх елементів з відомими розмірами в центрі батьківського елемента
Ви, швидше за все, знаєте про трюк з абсолютним позиціонуванням дочірнього елемента в центрі батьківського:
З функцією calc () можна позбутися від margin:
Зробимо код більш гнучким, додамо змінні ширини і висоти:
Зверніть увагу на те, що top і left можна використовувати для позиціонування елемента. Однак якщо вам необхідно анімувати об'єкт, використовуйте трансформації. Так як під час трансформації відбувається рекомпозиції об'єкта, при зміщенні об'єкта він заново промальовується на сторінці - тим самим знижується продуктивність.
Система координат і сіток з початком координат в центрі
Коли я дізнався про чотиризначний значення властивості background-position, мені вже стало нецікаво позиціонувати елемент відносно правої або нижньої сторони батьківського об'єкта за допомогою функції calc (). Але за допомогою цієї функції, виявилося, можна чудово розміщувати в центрі об'єкта одну конкретну точку фону.
Пару років тому мені знадобилося створити фоновий малюнок, який представляє собою систему координат. Завдання було змусити початок координат фонового малюнка завжди бути по центру.
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-9cf810db.png)
Намалювати систему координат з сіткою було легко:
![Починаємо працювати з css calc () (працювати) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-8b45fd66.jpg)
Практичний курс по верстці адаптивного Лендінзі з нуля!
Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів
Але як змусити фоновий малюнок приклеїтися намертво до центру елемента, а не до його верхньому лівому кутку? background-position: 50% 50 не спрацює, тому що точка 50% 50% градієнта буде збігатися з точкою 50% 50% елемента, але лінії розташовані зверху і зліва від градієнта відповідно. Вирішити цю проблему можна за допомогою calc (). Необхідно розташувати градієнт так, щоб його верхній лівий кут був рівно в центрі фігури. Потім зрушити градієнт вгору і вліво на половину ширини і висоти осей відповідно:
І знову змінні зроблять код більш гнучким. Ознайомтеся з прикладом system of coordinates + grid # 2 від Ana Tudor (@thebabydino) з сайту CodePen.
Збереження співвідношення сторін і видимій області екрана
При створенні HTML слайдеров я завжди хотів, щоб кожен слайд був контейнер з фіксованим співвідношенням сторін, щоб слайд завжди містився у видимій області вікна браузера і був завжди посередині.
Скажімо, нам потрібно співвідношення сторін 4: 3, а переглядаємо ми його на широкоформатному екрані. Це означає, що по висоті все буде нормально, а ось по ширині у нас будуть залишатися невеликі зазори зліва і справа.
![Починаємо працювати з css calc () (CSS3 найближчі днів) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-69d0ef02.png)
З співвідношенням сторін менше, ніж 4: 3 у нас з'являються зазори зверху і знизу, а по горизонталі блок поміщається цілком.
![Починаємо працювати з css calc () (працювати) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-0b3e55cd.png)
Блок займає всю ширину видимої області браузера, тобто width: 100vw. По ширині і співвідношенню сторін можна обчислити висоту height, вона буде дорівнює 3/4 * 100vw. І нарешті, відступ зверху буде дорівнює половині висоти вікна браузера мінус половина висоти блоку 100vh / 2 - 3/4 * 100vw / 2.
Можна також спростити код за допомогою змінних висоти і ширини. Нижче приклад на Sass, який можна протестувати. змінюючи розмір вікна браузера:
Ще краще, код вище можна перетворити в миксин, набагато краще, ніж глобальні змінні:
Зверніть увагу, для правильної роботи медіа запитів, змінні $ a і $ b повинні бути integer. Спосіб підтримується у всіх сучасних браузерах. Проте, до недавнього часу WebKit браузери не підтримували застосування vw одиниць у функції calc (). Підтримка з'явилася в Safari 8, Chrome 34 і останньої Opera.
Короткий заголовок слайда в центрі
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі днів) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-e92d1af7.png)
Я не хотів використовувати абсолютне позиціонування і вирішив працювати з властивістю line-height. Слайд з рамкою займає всю висоту вікна браузера, так що мені необхідно було задати властивості line-height значення 100vh мінус подвоєне значення border-width:
Якщо слайд з рамкою займає 100% ширини вікна браузера (і знаходиться вертикально посередині), його висота дорівнює $ b / $ a * 100vw. А значення line-height дорівнюватиме $ b / $ a * 100vw мінус подвоєне значення border-width слайда:
У цьому полягала моя ідея, в теорії вона працює ідеально. Більш того, вона працює в WebKit браузерах і IE. Але в Firefox функція calc () не вирахував значення для властивості line-height (і деяких інших); в цьому випадку calc () не найвдаліший варіант. Існує безліч інших способів вирішення цієї проблеми (flexbox, абсолютне позиціонування і т.д.).
Властивість perspective, заданий для сцени, робить так, що якщо об'єкт розташований ближче до глядача, він більшого розміру і навпаки. Властивість приймає значення довжини, і чим значення менше, тим більше контраст між ближніми і далекими об'єктами.
У нас є проста фігура - куб, наприклад. Куб розташований в центрі сцени. Фігура не сильно схожа на 3D: вона симетрична, і якщо сторони абсолютно непрозорі, то нам видно тільки передня частина фігури.
![Починаємо працювати з css calc () (calc) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-752de26f.png)
Давайте прокрутимо куб на 30 ° по осі У (вертикальна вісь проходить через середину об'єкта) або навколо осі Х. Вже краще, але нам тепер видно тільки дві поверхні.
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-932f355c.png)
perspective-origin 100% 0 задає точку відліку верхній правий кут сцени, а фігура завжди знаходиться в центрі сцени. Через це при зміні розміру сцени, змінюється відстань від точки 50% 50% (позиція куба) до точки 100% 0 (точка спостереження perspective-origin).
Як вихід можна використовувати calc (). Для цього необхідно додати або відняти фіксоване значення від 50%:
Спробуйте самі. змініть розмір вікна браузера. А як щодо вас? Ви вже використовували calc ()? Якщо так, то навіщо?
Редакція: Команда webformyself.
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі днів) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-8b45fd66.jpg)
Практичний курс по верстці адаптивного Лендінзі з нуля!
Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів
Найсвіжіші новини IT і веб-розробки на нашому Telegram-каналі
![Починаємо працювати з css calc () (HTML5 CSS3 найближчі) Починаємо працювати з css calc ()](https://images-on-off.com/images/134/nachinaemrabotatscsscalc-c3843abf.png)