Починаємо працювати з css calc ()

Багато хто думає, що препроцесори тільки і складаються, що з логіки і обчислень, але функція 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 ()

Практичний курс по верстці адаптивного Лендінзі з нуля!

Навчіться з нуля верстати адаптивні Лендінзі на 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 ()

А що, якщо необхідно задати фіксовану ширину смуги, щоб вона не змінювалася в залежності від розміру об'єкта? У функції calc () необхідно задати значення 50% мінус половина від фіксованої ширини смуги і 50% плюс половина ширини смуги. Якщо нам потрібна смуга шириною 4em:

Приклад вище можна протестувати в браузері. пограти з розміром вікна браузера. Розміри прямокутника задані в vmin, тому розмір об'єкта змінюється при зміні розміру вікна браузера. Але діагональна смуга завжди залишається фіксованою ширини.

Позиціонування дочірніх елементів з відомими розмірами в центрі батьківського елемента

Ви, швидше за все, знаєте про трюк з абсолютним позиціонуванням дочірнього елемента в центрі батьківського:

З функцією calc () можна позбутися від margin:

Зробимо код більш гнучким, додамо змінні ширини і висоти:

Зверніть увагу на те, що top і left можна використовувати для позиціонування елемента. Однак якщо вам необхідно анімувати об'єкт, використовуйте трансформації. Так як під час трансформації відбувається рекомпозиції об'єкта, при зміщенні об'єкта він заново промальовується на сторінці - тим самим знижується продуктивність.

Система координат і сіток з початком координат в центрі

Коли я дізнався про чотиризначний значення властивості background-position, мені вже стало нецікаво позиціонувати елемент відносно правої або нижньої сторони батьківського об'єкта за допомогою функції calc (). Але за допомогою цієї функції, виявилося, можна чудово розміщувати в центрі об'єкта одну конкретну точку фону.

Пару років тому мені знадобилося створити фоновий малюнок, який представляє собою систему координат. Завдання було змусити початок координат фонового малюнка завжди бути по центру.

Починаємо працювати з css calc ()

Намалювати систему координат з сіткою було легко:

Починаємо працювати з css calc ()

Практичний курс по верстці адаптивного Лендінзі з нуля!

Навчіться з нуля верстати адаптивні Лендінзі на 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 ()

З співвідношенням сторін менше, ніж 4: 3 у нас з'являються зазори зверху і знизу, а по горизонталі блок поміщається цілком.

Починаємо працювати з css calc ()

Блок займає всю ширину видимої області браузера, тобто 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 ()

Я не хотів використовувати абсолютне позиціонування і вирішив працювати з властивістю 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 ()

Давайте прокрутимо куб на 30 ° по осі У (вертикальна вісь проходить через середину об'єкта) або навколо осі Х. Вже краще, але нам тепер видно тільки дві поверхні.

Починаємо працювати з css calc ()

perspective-origin 100% 0 задає точку відліку верхній правий кут сцени, а фігура завжди знаходиться в центрі сцени. Через це при зміні розміру сцени, змінюється відстань від точки 50% 50% (позиція куба) до точки 100% 0 (точка спостереження perspective-origin).

Як вихід можна використовувати calc (). Для цього необхідно додати або відняти фіксоване значення від 50%:

Спробуйте самі. змініть розмір вікна браузера. А як щодо вас? Ви вже використовували calc ()? Якщо так, то навіщо?

Редакція: Команда webformyself.

Починаємо працювати з css calc ()

Практичний курс по верстці адаптивного Лендінзі з нуля!

Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів

Найсвіжіші новини IT і веб-розробки на нашому Telegram-каналі

Починаємо працювати з css calc ()

Практика HTML5 та CSS3 з нуля до результату!

Схожі статті