Сьогодні ми з вами займемося створенням анімованої діаграми за допомогою CSS3. Раніше ми робили щось подібне за допомогою Jquery, але пора нарешті позбутися від громіздких плагінів з купою непотрібного функціонала.
Запишемо основні вимоги. Наша діаграма должена бути:
- незалежною від фону
- адаптивної (для будь-якої кількості стовпчиків)
- масштабируемой (як векторні графіки)
- легко настроюється (колір, розміри і пропорції)
Почнемо по порядку.
Стовпець з рухомим внутрішнім блоком.
Наш стовпець повинен бути представлений у вигляді прямокутного паралелепіпеда, що складається з 6 сторін, при цьому внутрішній блок повинен вертикально переміщатися. Також потрібно передбачити можливість приховати цей блок. Для виконання цього завдання нам знадобиться всього п'ять блокових елементів:
- 1 div для задньої частини, що складається з 3-х сторін (задня стінка, підстава та ліва стінка)
- 1 div для передньої частини, що складається з 3-х сторін (передня, верхня і права стінки)
- 1 div для внутрішнього блоку, що складається з 3-х сторін на зразок передньої частини, але з меншим значенням властивості z-index
- 1 контейнер для розташування всіх трьох частин щодо нього та застосування єдиної фонової текстури в правому нижньому кутку
- 1 контейнер з overflow: hidden. щоб заховати внутрішній блок під стовпцем, коли він опускається вниз
Ви можете здивуватися, навіщо нам потрібно два контейнери? Це не так просто зрозуміти, тому я поясню. Нам потрібен як мінімум 1 контейнер на стовпчик (для того щоб щодо нього ми могли розташувати передню, задню і внутрішню стінку). Крім того наш стовпчик повинен бути масштабованим, і тому ми скористаємося процентним співвідношенням для управління заповненням стовпчика. Для цього нам необхідно, щоб висота нашого контейнера дорівнювала висоті однієї зі сторін стовпа.
Далі, у нас повинна бути кнопка, за допомогою якої можна приховати внутрішній блок, тобто наш блок повинен опуститися «нижче стовпчика» і ісчзнуть. Можна застосувати властивість overflow: hidden. але не для цього контейнера, так як його висота менше справжньої висоти стовпчика. Додаємо ще один контейнер поверх нього, і вже до нього можна застосувати overflow: hidden. Ось так і вийшло два контейнери.
Інтер'єр діаграми на CSS3.
Прийшов час попрацювати над інтер'єром для нашої стовпчастий діаграми щоб було все красиво і функціонально. Вимоги до нього досить жсткіе:
- раз у на все в 3D, то знадобляться три площини (задня стінка, низ і ліва стінка)
- не залежати від фону
- не залежати від кількості стовпчиків і їх характеристикам (висота, ширина та ін.)
- осі Х і Y повинні бути зовні з нанесеними на них відповідними мітками
Для цього нам буде потрібно:
- 1 невпорядкований список ul
- 1 елемент всередині кожного елемента списку для ярликів по осі X
- 1 стовпець всередині кожного елемента списку
- 1 елемент списку з неврегульованим списком всередині для ярликів по осі Y
Невпорядкований список, - запитаєте ви? Хіба більш семантичним не є використання списку визначень dl для столбикового графіка? Можливо, але ми не можемо використовувати його, так як нам необхідно обернути кожен стовпчик і його ярлик на осі X одним контейнером для того, щоб спозиционировать їх відносно один одного.
Більш того, ми не можемо використовувати пункт списку замість другого контейнера для стовпчика, так як нам необхідно розташувати ярлики осі X за межами діаграми і, так як ми знаємо, що другий контейнер стовпчика приховує будь-який контент, який більше або виходить за нього, ми використовуємо елементи списку для того, щоб переконатися, що всі елементи позиційовані правильно.
Реалізація
Настав час покінчити з теорією і зайнятися кодуванням. Код для стовпчика з рухається внутрішнім блоком виглядає так:
Давайте ще раз обговоримо призначення кожного блоку:
- .bar-wrapper - приховує .bar-inner. коли той узжает нижче стовпці
- .bar-container - для відносного позиціонування .bar-foreground. .bar-inner і .bar-foreground
- .bar-background - створює 3 боку корпусу: задню, нижню і ліву сторону
- .bar-inner - внутрішній блок нашого стовпчика
- .bar-foreground - створює залишилися 3 боку корпусу: передню, верхню, праву
Для початку, оформимо наші контейнери
Зверніть увагу, що елементу .bar-container задана ширина 12.5em. Це число дорівнює сумі ширини передньої (10em) і ширини правої (2.5em) сторін стовпчика. Ми так само використовуємо кордону для створення трикутної форми за допомогою властивостей border-style. border-width і border-color. Цей трикутник розташуємо в правому нижньому кутку елемента .bar-container для того, щоб бути впевненими в тому, що внутрішня сторона стовпчика «обрізається» при вертикальному переміщенні.
А тепер приступимо до оформлення задньої стінки:
Як бачите, ми переміщаємо корпус на 2.5em вправо-вгору і схиляємо ліву і нижню сторони на 45 градусів. Зверніть також увагу на рядок transform: skew (0deg, -45deg) ;. задавши нахил по іси X рівним 0 градусів, а по осі Y -45 градусів ми нахилили нашу нижню стінку вертикально.
Перейдемо до оформлення передньої стінки.
Тут все те ж саме, що було в стилізації задньої стінки, тільки трансформація в іншому напрямку. Крім того, ми застосували однакові стилі до обох сторін корпусу і внутрішнього блоку, оскільки у них однакові властивості.
Тепер ми з вами займемося стилями для внутрішнього блоку.
Ми налаштували наші стовпчики і тепер можемо зайнятися зовнішнім оформленням:
Як вже говорилося раніше, ми використовуємо невпорядкований список і теги span для розміщення міток по осях X і Y.
Тут складність полягає в тлі. Ми використовуємо лінійний градієнт для заповнення контейнера діаграми і піднімаємо його на 2.5em. Навіщо? Справа в тому, що низ нашого боксу з діаграмою по висоті становить 2.5em, і нахилений на 45 градусів, тому в правому нижньому кутку залишається утворюється порожній простір.
Тепер давайте перейдемо до стилізації нижній частині.
Ми схиляємо її на 45 градусів і трохи зміщуємо вліво на 1/2 висоти (тому що трансформування відбулося відносно осі, що проходить через середину лівого і правого краю нашого нижнього блоку). В результаті цього зсуву нижня частина виявляється впритул пристикованої до лівої стінки. Далі задаємо 100% ширину для того, щоб бути впевненими в тому, що вона заповнює весь відведений під не простір. Тепер займемося лівою стороною:
Після пояснень, даних вище, ви легко зможете розібратися в наведеному коді. У ньому ми нахилили елемент на 45 градусів, і трохи змістили його вниз на 1/2 ширини. Тепер займемося стилізацією наших стовпчиків:
Поясню що тут відбувається. Ми вибудовуємо наші стовпці поруч один з одним за допомогою властивості float. Після цього, ми додаємо відступ справа до останнього стовпчика діаграми. Зроблено це для того, щоб показати правий нижній кут. Спробуйте прибрати цей параметр, і ви відразу побачите, що з цього вийде. І, в ув'язненні, ми стилізуємо наші мітки по осі X.
OK, ми майже закінчили. Тепер залишилося стилізувати маркери по осі Y і можна буде перевести дух:
Як видно з коду, ми призначили ширину осі з маркерами дорівнює 100%. Це необхідно для того, щоб промальовувати лінію через всю діаграму, відобразити точкові лініідля осі Y і розташувати span-елемент таким чином, щоб мітки осі Y були поза діаграми. За допомогою: before та: after ми можемо зробити це досить легко і не засмітити html код.
Отже, ми закінчили стилізацію нашої діаграми, але не вказали такі важливі змінні як розміри, кольори і рівень заповнення стовпців! Справа в тому, що наша діаграма буде настроюється, тому ми вирішили не плутати змінні з іншим кодом, щоб ви могли самостійно їх змінити.
У демо-файлі ви виявите деякі відмінності в коді. Це тому що ми вирішили використовувати радіо-кнопки щоб можна було міняти характеристики столиків без редагування коду. Не соромтеся ознайомитися з вихідним кодом. Але, якщо вам потрібна тільки статіччная діаграма, скористайтеся уривком коду, наведеним вище, і внесіть свої зміни.
Післямова
На завершення, давайте згадаємо CSS-властивості, техніки, з якими ми зіткнулися роблячи нашу діаграму, але які не отримали належного пояснення:
- transform: skew () і rotate () для трансформації наших елементів таким чином, щоб разом вони створювали відчуття тривимірного простору
- псевдо-класи: before та: after потрібні для генерації елементів за допомогою CSS і для простоти розмітки HTML
- псевдо-класи: nth-last-child () і: not потрібні для визначення конкретних пунктів списку і для того, щоб уникнути додавання додаткових класів / id в розмітку
- linear-gradient разом з background-position потрібні для часткового заповнення елемента фоном
- rgba () для напівпрозорого фону
- border: для створення фігур типу трикутника
- unity