Впорядковуємо класи Bootstrap
Bootstrap — чудовий фреймворк. Передусім, його перевага у швидкості створення інтерфейсу сайтів. Для мене як програміста він ідеально підходить для адмінок. Мало хто з замовників погодиться виділити кошти на професійний дизайн не тільки для основного сайту, а ще й для панелі керування. До того ж, Bootstrap дуже допомагає мені створювати нові сайти. Коли дизайну для нового сайту ще немає, а споглядання «голих» елементів HTML пригнічує, Bootstrap допомагає вирішити цілий ряд проблем.
По-перше, він гарний. Його, на відміну від власного дизайну, зімпровізованого під час створення сайту, не соромно показати людям. По-друге, розробка з допомогою Bootstrap типових й невибагливих сайтів значною мірою економить час та дозволяє зосереджуватись саме на програмуванні.
Фейкові класи
На жаль, найбільша перевага Bootstrap, швидкість розроблення, автоматично породжує недолік — складність підтримки. Ця проблема виникає через використання класів для зміни лише однієї-двох властивостей стилю. Я називаю ці класи модним зараз словом «фейкові». Цю проблему легше показати на прикладі, що базується на фрагменті коду, який я взяв зі сторінки зі зразками на офіційному сайті Bootstrap.
<div class="jumbotron p-4 p-md-5 text-white rounded bg-dark"> <div class="col-md-6 px-0"> <h1 class="display-4 font-italic">Title of a longer featured blog post</h1> <p class="lead my-3">Multiple lines of text that form the lede, informing new readers quickly and efficiently about what’s most interesting in this post’s contents.</p> <p class="lead mb-0"> <a href="#" class="text-white font-weight-bold">Continue reading...</a> </p> </div> </div>
Єдиний «справжній» клас в цьому прикладі — це jumbotron
, всі решта — «фейкові». Для того, щоб краще зрозуміти, про що йдеться, я приблизно «перекладу» попередній приклад на більш зрозумілу для всіх мову стилів.
<div class="jumbotron" style="padding: 3rem; color: #fff; border-radius: .25rem; background-color: #343a40;"> <div style="flex: 0 0 50%; max-width: 50%; padding-left: 0; padding-right: 0;"> <h1 style="font-size: 3.5rem; font-style: italic;">Title of a longer featured blog post</h1> <p style="font-size: 1.25rem; font-weight: 300; margin-top: 1rem; margin-bottom: 1rem;">Multiple lines of text that form the lede, informing new readers quickly and efficiently about what’s most interesting in this post’s contents.</p> <p style="font-size: 1.25rem; font-weight: 300; margin-bottom: 0;"> <a href="#" style="color: #fff; font-weight: 700;">Continue reading...</a> </p> </div> </div>
Зрозуміло, що верстати шаблон для сайту буде суттєво швидше, якщо стилі документа писати не в окремий css-файл, а відразу в елементи документа. Та ще й використовуючи зручні скорочення на кшталт mt-1
замість довгого margin-top: 0.25rem;
. Але чому ніхто не подумав про те, наскільки складно його потім буде підтримувати? Це особливо прикро, коли при створенні сайту намагаєшся максимально точно дотримуватись
Наведу ще декілька прикладів з фрагментами коду зі html-сторінок офіційного сайту Bootstrap, в яких часто використовуються «фейкові» класи.
<!-- https://getbootstrap.com/docs/4.3/examples/pricing/ --> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">...</div> <!-- https://getbootstrap.com/docs/4.3/examples/product/ --> <div class="bg-dark mr-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center text-white overflow-hidden">...</div> <!-- https://getbootstrap.com/docs/4.3/examples/blog/ --> <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">...</div> <!-- https://getbootstrap.com/docs/4.3/examples/dashboard/ --> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">...</div> <!-- https://getbootstrap.com/docs/4.3/examples/offcanvas/ --> <div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded shadow-sm">...</div>
Цей випадок нагадав мені ще студентський підхід ЗЗЗ — «Завчив, Здав, Забув». Під’єднав фреймворк, швидко зверстав, здав замовнику та й забув про нього. А страждає з ним нехай хтось інший.
Я пропоную відволіктись на деякий час від Bootstrap та завітати на сторінку специфікації HTML5. А якщо бути точнішим — в розділ 1.10.1. Presentational markup. І якщо Google Перекладач не дуже сильно помилився, то зміст передостаннього параграфа цього розділу виглядає приблизно так:
Єдині функції презентаційної розмітки, що залишилися в HTML, є атрибут style
та елемент <style>
.
Використання атрибута style
не рекомендується у виробничих середовищах, але він може бути корисним для швидкого прототипування (де його правила пізніше можуть бути переміщені безпосередньо в окремі таблиці стилів) і для надання конкретних стилів у незвичайних випадках, коли реалізація окремою таблицею стилів буде недоцільною.
Аналогічно, елемент <style>
може бути корисним тільки для стилів, специфічних для певної сторінки або в поєднанні з ними, але зовнішня таблиця стилів буде більш доцільною, коли стилі застосовуються до декількох сторінок.
А тепер повернімось до нашого коду та подивимось, як він мав би виглядати, якщо б його створювали згідно з рекомендаціями.
<div class="jumbotron"> <div class="jumbotron-container"> <h1 class="jumbotron-title">Title of a longer featured blog post</h1> <p class="jumbotron-description">Multiple lines of text that form the lede, informing new readers quickly and efficiently about what’s most interesting in this post’s contents.</p> <p class="jumbotron-link"> <a href="#">Continue reading...</a> </p> </div> </div>
За такої умови, всі стилі мали б визначатись за допомогою зовнішньої таблиці стилів так, як це радять в специфікації HTML5.
.jumbotron {padding: 3rem; color: #fff; border-radius: .25rem; background-color: #343a40;} .jumbotron-container {flex: 0 0 50%; max-width: 50%; padding-left: 0; padding-right: 0;} .jumbotron-title {font-size: 3.5rem; font-style: italic;} .jumbotron-description {font-size: 1.25rem; font-weight: 300; margin-top: 1rem; margin-bottom: 1rem;} .jumbotron-link {font-size: 1.25rem; font-weight: 300; margin-bottom: 0;} .jumbotron-link a {color: #fff; font-weight: 700;}
Але не поспішайте радіти: такий спрощений підхід може створити вам багато додаткових проблем. Річ у тім, що більшість правил, винесених нами в окрему таблицю стилів, пов’язані з багатьма іншими елементами дизайну. А коли ми їх продублювали, то порушили цей зв’язок з фреймворком. І якщо в майбутньому, з тих чи інших причин, якась властивість в самому фреймворку зміниться, то її додатково буде необхідно змінювати всюди в файлі стилів.
Ця проблема подібна до проблеми «copy-paste» значного шматка коду в програмуванні. І якщо дизайнери-верстальники, яким необхідно швидко здати проект, ще можуть дозволити собі особливо не перейматись цим питанням, то для програмістів, які будуть довгий час цей проект підтримувати та розвивати, таке рішення є абсолютно неприйнятним.
Наслідування класів
Але нам поталанило: мало того, що Bootstrap розповсюджується з відкритим початковим кодом, так ще й в четвертій версії він реалізований за допомогою метамови SCSS. А такий підхід дає розробникам багато додаткових можливостей для більш гнучкого його використання. Декілька з цих можливостей ми якраз і використаємо для розв’язання проблеми з «фейковими» класами.
Я переконаний, що вносити зміни в файли фреймворку — не найвдаліше рішення. Краще імпортувати стилі Bootstrap у свій власний додатковий файл, а вже в ньому можна робити що завгодно: додавати власні нові правила чи перевантажувати наявні. Пізніше ми без проблем зможемо оновлювати оригінальні файли фреймворку на новіші, не забуваючи заново перетранслювати scss-файл.
Отож, створимо файл з назвою, наприклад, bootstrap-extend.scss
та з одним-єдиним записом @import "bootstrap-4.3.1/scss/bootstrap";
. У разі потреби шлях до scss-файлів фреймворку потрібно замінити на той, за яким він знаходиться конкретно у вашому проекті. Після трансляції цього файлу у вас має з’явитись файл bootstrap-extend.css
, який необхідно прописати у свій html-файл. Теоретично, нова таблиця стилів має бути повністю аналогічна до такого ж готового файлу з фреймворку. Конкретно в мене, в мінімізованому вигляді, він виявився ще й на 10 КБ легший, в порівнянні з аналогічним оригінальним.
Якщо ви на своєму проекті використовуєте не всі складові Bootstrap, тоді вам необхідно прописувати для імпорту не загальний файл, як в моєму прикладі, а кожну необхідну частину фреймворку окремо. Подивитись повний перелік його складових частин можна в самому файлі, який я вказав в прикладі вище при імпорті.
А тепер найцікавіше — доповнимо фреймворк своїми правилами для стилів за допомогою метамови SCSS в новоствореному файлі, не руйнуючи водночас зв’язок з самим фреймворком. Для початку додамо такий код:
@each $name, $width in $container-max-widths { .mw-#{$name} {max-width: #{$width};} }
Розв’язання проблеми цей код абсолютно не стосується, але я переконаний, що його дуже бракує в самому фреймворку. Завдяки цим декільком рядкам ви зможете обмежувати максимальну ширину елементів за допомогою прописування класів такого виду mw-sm
або mw-md
. Наприклад, якщо у вас буде таблиця з
А тепер додамо саме той код, який дозволить використовувати в HTML прийнятні класи.
.jumbotron {@extend .p-4, .p-md-5, .text-white, .rounded, .bg-dark; .jumbotron-container {@extend .col-md-6, .px-0; .jumbotron-title {@extend .display-4, .font-italic;} .jumbotron-description {@extend .lead, .my-3;} .jumbotron-link {@extend .lead, .mb-0; a {@extend .text-white, .font-weight-bold;} } } }
За допомогою правила @extend
метамови SCSS, ми використали множинне наслідування для створення необхідних стилів на основі наявних правил фреймворку. Оскільки «фейкові» класи змінюють, зазвичай, одну-дві властивості стилю, то у нас відсутні проблеми з суперечностями, характерними для цього типу наслідування. Водночас ми зберегли необхідний зв’язок з фреймворком, а сама html-сторінка повністю відповідає рекомендаціям специфікації сучасного стандарту HTML5.
Не менш вагомою додатковою перевагою такого підходу до використання стилів фреймворку є те, що ваш проект жорстко до нього не прив’язаний. Та коли настане час змінити дизайн на новий, достатньо буде замінити таблицю стилів без нудної та кропіткої заміни стилів в самому документі HTML.
Висновки
У мене складається враження, що люди, женучись за швидким результатом, забувають про зворотній бік медалі. Чим швидше ви намагаєтесь створити проект, тим складніше буде його розвивати та підтримувати. Як наслідок, роботодавцям доводиться підвищувати зарплати на вакансії, щоб хоч якось додатково вмотивувати потенційних працівників долучитись до проекту, який хтось створив дуже швидко та дешево.
Звичайно, трапляються замовлення на «сайти-одноденки», про які ви точно знаєте, що вони матимуть короткий «лайфтайм» та витрачати на них багато часу просто недоцільно. Але, зазвичай, такі поодинокі випадки не притаманні професійному середовищу.