<
  • Главная
Статьи

Навігаційне меню з використанням Flexbox

  1. Трохи flex і box Всі ми давно вже знаємо, що як тільки наш улюблений браузер Internet Explorer 9...
  2. угоди
  3. розмітка
  4. скелет
  5. Стилізація основних елементів
  6. Список пунктів меню
  7. перемикач стану
  8. Логотип
  9. Коригування поведінки елементів
  10. Прокрутка списку
  11. демонстрація
  12. висновки

Трохи flex і box

Всі ми давно вже знаємо, що як тільки наш улюблений браузер Internet Explorer 9 вийде з чергового кола болісної підтримки - Flexbox нарешті займе свою нішу.

Мабуть, я не буду розповідати вам про те, який чудовий це інструмент в умілих руках і як прекрасно з ним працювати. Я просто залишу пару посилань нижче. Причому читати їх найкраще в тому порядку, в якому я їх залишив.

Практика і короткі відомості:

теорія:

Довідники:

PS: Вміст деяких посилань російською мовою. Важливо розуміти, що дані про підтримку браузерами застаріли. Детальніше про це нижче.

підтримка браузерами

Так, в IE10 підтримується старий синтаксис, але для Autoprefixer це не проблема.

угоди

Для того, щоб ми з вимі були на одній хвилі, я нагадаю про те, які угоди і інструменти я використовую:

розмітка

Ах, як хотілося б просто скопіювати код з проекту, але немає - я використовую HTML-препроцесор Jade, синтаксис якого заснований на ідентаціі і може бути не зрозумілий читачеві. А ще highlight.js не має підтримку його синтаксису. Доведеться копіювати вже скомпільовану версію.

<! - Компонент навігаційного меню -> <div class = "navbar-component"> <! - Клас `area` - це простий контейнер (про це пізніше) -> <div class =" navbar area "> < ! - Логотип -> <a href="#" class="brand"> Brand </a> <! - Список посилань -> <nav role = "navigation" id = "navigation" class = "list "> <a href="#" class="item -link"> Home </a> <a href="#" class="item -link"> Articles </a> <a href =" # "class = "item -link"> Projects </a> <a href="#" class="item -link"> Resources </a> <a href="#" class="item -link"> About me < / a> <span class = "item"> <i class = "fa fa-search"> </ i> </ span> </ nav> <! - Кнопка для мобільних -> <button data-collapse data -target = "# navigation" class = "toggle"> <! - Тут буде іконка гамбургера -> <span class = "icon"> </ span> </ button> </ div> </ div>

скелет

Отже, насамперед потрібно визначити найпростіші стилі, які все тягають з проекту в проект. Для економії місця я записав їх в компактному 'режимі'.

// Scaffolding *, *: before, *: after {box-sizing: border-box; } Body {background-color: # f5f5f5; color: # 333; font-size: 14px; font-family: Verdana, Arial, sans-serif; line-height: 20px; } A {text-decoration: none; transition: all 0.3s linear 0s; }

Тепер настав час звернути увагу на клас area, який я вказав і зазначив в розмітці вище. Справа в тому, що я не вказую кожен раз розмір контейнера - для цього у мене є цей клас. Його властивості мають такий вигляд:

// Сітка .area {// Оголошуємо цей блок flex-контейнером display: flex; // центруючи margin-right: auto; margin-left: auto; // Встановлюємо головну вісь і багаторядкова контейнера flex-flow: row wrap; // рядок багатостроковий // Розташування елементів щодо поперечної осі на рядку align-items: stretch; // розтягуються // Медіавираженія для типових розмірів екранів @media (min-width: 768px) {width: 750px; } @Media (min-width: 992px) {width: 970px; } @Media (min-width: 1200px) {width: 1140px; }}

На цьому з підготовкою фундаменту ми закінчимо. Тепер визначимо візуальні стилі для розроблюваного нами компонента навігаційного меню. Головний селектор компонента буде мати такий вигляд:

// Component .navbar-component {background-color: @ navbar-background; // 1 box-shadow: 0 2px 5px rgba (0, 0, 0, 0.16), 0 2px 10px rgba (0, 0, 0, 0.12); // 2 // натякає сітці, що &> .navbar {// Вирівнювання щодо головної осі justify-content: space-between; // рівномірний}}

зауваження

1. Зрозуміло, що всі змінні ініціалізовані раніше, просто я не вказую це в статті, бо сенсу в цьому немає.

2. Тіні генерує бібліотека material shadows , Яку можна встановити, використовуючи менеджер пакетів Bower: bower i --save-dev material-shadows.

Давайте відвернемося від рядків суворого коду і подивимося на те, що робить властивість justify-content. Це зображення показує те, що було:

Це зображення показує те, що було:

А тепер подивіться на те, що стало:

А тепер подивіться на те, що стало:

Непогано, так? Якби ми не використали Flexbox, довелося б додавати властивість float, як мінімум селекторам brand, toggle, list і item. Причому не просто додавати властивості, а стежити за тим, щоб вони нормально відображалися в різних умовах.

Стилізація основних елементів

Приступимо до базової (візуальної) стилізації основних елементів нашого компонента.

Список пунктів меню

Спочатку необхідно визначити базові стилі для пунктів меню:

// Component .navbar {// List of items &> .list {display: flex; flex-flow: row nowrap; align-items: center; } &> .List> .item {display: block; // Можливість елемента стискатися flex-shrink: 0; // заборонено // Вирівнювання та відступи height: @ navbar-height; line-height: @ navbar-height; padding-left: round ((@ navbar-height - 20) / 2); padding-right: round ((@ navbar-height - 20) / 2); text-transform: uppercase; color: @ navbar-item-color; font-size: @ navbar-item-font-size; } &> .List> .item.-link {line-height: (@ navbar-height + @ navbar-item-border-width); color: @ navbar-item-color; border-bottom: @ navbar-item-border-width solid @ navbar-item-border; & .- active, &: hover, &: focus {color: @ navbar-item-active-color; border-bottom-color: @ navbar-item-active-border; }}}

Слід трохи пояснити цю простирадло коду перед тим, як йти далі до інших елементів нашого компонента.

По-перше, ми вказуємо селектору list стати flex-контейнером, у якого головна вісь є горизонтальною і однорядковою, а також елементи розташовуються по центру поперечної осі.

По-друге, пункти меню можуть бути не тільки посиланнями, а й, скажімо, елементом <span>, який включає в себе іконки та інші витівки. Для цього ми окремо визначаємо ключові властивості пункту меню (вирівнювання, відступи, трансформацію тексту і його колір). До речі, тут вирівнювання елемента здійснюється за допомогою властивості line-height, так як у елемента, якщо він посилання, може бути нижня рамка, а у звичайних елементів її немає. Тобто нижню рамку ми враховуємо тільки у посилань.

По-третє, на всякий випадок вказуємо пункту меню розмір шрифту, так як іноді щось може піти не так.

перемикач стану

Для зручності приховуємо список пунктів меню, змінивши значення його властивості dispaly на none.

Тепер можна зайнятися цією кнопкою. Рутинно переобумовленої всі стилі кнопки для того, щоб позбавити її стандартного для всіх браузерів виду:

// Component .navbar {// Toggle button &> .toggle {border: 0; background-color: transparent; display: inline-block; outline: none; border: 0; background-color: transparent; background-image: none; vertical-align: middle; text-align: center; white-space: nowrap; cursor: pointer; touch-action: manipulation; user-select: none; // Нагадаю, що 20 - це значення line-height у body padding: round ((@ navbar-height - 20) / 2); } // List of items &> .list {...}}

Займемося іконкою гамбургера.

Я людина ледачий і кожен раз, коли робиться щось тривіальне і рутинне - у мене відразу ж виникає думка винести це в модуль, щоб позбутися від копіювання стилів з проекту в проект. У нашому випадку модулем може бути less-файл, який містить якісь домішки. Так народилася невелика бібліотека hamburger-icon , Яка просто генерує іконку гамбургера і дозволяє її анімувати.

Кмітливий читач здогадався, що залишається тільки підключити цю бібліотеку до проекту і викликати пару домішок. Так ми і зробимо:

// Component .navbar {// Toggle button &> .toggle {...} &> .toggle> .icon {// В силу особливої ​​препроцесора Less, визначаємо настройки бібліотеки .hamburger-settings (24px, 3px, 5px, @ navbar-item-color, @ timing-function: linear); // Генеруємо іконку .hamburger-generator (); } // Визначаємо активний стан для гамбургера &> .toggle.-active> .icon {.hamburger-animation (); } // List of items &> .list {...}}

В силу того, що підключити зовнішній ресурс для Less на Codepen не вийде, там буде знаходитися вручну перенесена версія іконки. І, на жаль, для повноти картини я повинен буду вставити її сюди з коментарями:

&> .Toggle> .icon {position: relative; margin-top: 8px; margin-bottom: 8px; // Створюємо три палки &, &: before, &: after {display: block; width: 24px; height: 3px; transition: background-color 0.3s linear, transform 0.3s linear; background-color: # 555555; } // Абсолютно позиціонуємо палиці і розсовуємо їх по вертикалі &: before, &: after {position: absolute; content: ""; } &: Before {top: -8px; } &: After {top: 8px; }} &> .Toggle.-active> .icon {// Приховуємо середню палицю background-color: transparent; // Повертаємо верхню і нижню палиці &: before {transform: translateY (8px) rotate (45deg); } &: After {transform: translateY (-8px) rotate (-45deg); }}

Дуже добре, тепер можна прибрати з очей геть цю кнопку і зайнятися логотипом. Поки що просто змінимо значення властивості display у селектора toggle на none. До цього ми ще повернемося.

Логотип

У цій частині статті все просто. Потрібно лише розуміти, що логотип може бути картинкою або ж, у бюджетній версії, - текстом.

Відразу обмовлюся, що варіант з картинкою розглядатися не буде, так як там потрібно всього лише вказати зображення в background-image і скорегувати значення властивості margin за своїми розмірами.

Зараз ми трохи облагородимо наш текст, а з картинками я пропоную повозитися при необхідності:

// Component .navbar {// Brand &> .brand {display: block; font-size: 16px; color: # 777; margin: round ((@ navbar-height - 20) / 2); } // Toggle button &> .toggle {...} // List of items &> .list {...}}

На цьому базова стилізація закінчується.

Коригування поведінки елементів

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

  • Логотип повинен відображатися завжди.
  • Кнопка перемикання стану списку пунктів меню повинна бути видна тільки на пристроях з невеликим екраном.
  • Список пунктів меню повинен ховатися на маленьких пристроях і завжди відображатися на великих.

Тут нам стане в нагоді принцип спочатку мобільні (Mobile First).

Виходячи зі списку вище - логотип ми не чіпаємо. Він відображався, відображається і буде відображатися завжди.

На черзі кнопка перемикання стану меню. Спочатку вона повинна відображатися, а починаючи з якогось значення ширини екрану - ховатися. Такий принцип спочатку мобільні. Сказано зроблено:

// Component .navbar {// Brand &> .brand {...} // Toggle button &> .toggle {... @media (min-width: @ navbar-collapse-breakpoint) {display: none; }} // List of items &> .list {...}}

А ось зараз ми спочатку приховуємо список пунктів меню і відображаємо його тільки тоді, коли ширина екрану буде більше необхідною.

// Component .navbar {// Brand &> .brand {...} // Toggle button &> .toggle {...} // List of items &> .list {... display: none; @media (min-width: @ navbar-collapse-breakpoint) {display: flex; } & .- on {display: flex; }}}

Клас -on визначає відкритий стан списку пунктів меню в тому випадку, якщо користувач натиснув на створену нами кнопку. До речі, ось лістинг JavaScript-коду, який відображає і приховує меню при кліці:

(Function () {// Визначення викликає елемента var getTriggerElement = function (el) {// Отримуємо атрибут `data-collapse` var isCollapse = el.getAttribute ( 'data-collapse'); // Якщо атрибут існує, то if ( isCollapse! == null) {// Повертаємо елемент на якому здійснено клік return el;} else {// Інакше намагаємося знайти атрибут у його батька var isParentCollapse = el.parentNode.getAttribute ( 'data-collapse'); // Повертаємо батьківський елемент або undefined return (isParentCollapse! == null)? el.parentNode: undefined;}}; // Оброблювач кліка var collapseClickHandler = function (event) {// Визначення викликає елемента var triggerEl = getTriggerElement (event.target); // якщо у елемента і його батька немає атрибута if (tri ggerEl === undefined) {// Скасовуємо дію return false;} else {event.preventDefault ();} // Отримуємо цільової елемент var targetEl = document.querySelector (triggerEl.getAttribute ( 'data-target')); // якщо цільовий елемент існує if (targetEl) {// маніпулюючи класами triggerEl.classList.toggle ( '- active'); targetEl.classList.toggle ( '- on'); }}; // делегуючи подія document.addEventListener ( 'click', collapseClickHandler, false); }) (Document, window);

Залишилося ще трохи.

Прокрутка списку

Як правило, пунктів меню буває порівняно велика кількість. І, як наслідок, на екрані мобільного телефону вмістити їх не вийде. Для вирішення цієї проблеми, як правило, використовується вертикальне розташування елементів списку, але не в цій статті. Це занадто просто і вже буденно. Насправді ж, я недавно ходив на сайт однієї фруктової компанії і побачив їх класне меню. Ідея полягає в тому, щоб всі пункти розташовувалися горизонтально і їх можна було прокручувати, як слайди.

Трохи подумавши, можна прийти до наступним сценарієм в коді:

Насамперед, необхідно заборонити перенесення рядків:

// List of items .navbar {&> .list {... white-space: nowrap; }}

Далі потрібно створити медіавираженіе, стилі всередині якого будуть діяти тільки до зазначеної точки:

// List of items .navbar {&> .list {... @media (max-width: @ navbar-collapse-breakpoint) {position: fixed; // 1 top: @ navbar-height; // 1 left: 0; // 1 width: 100%; overflow-y: hidden; overflow-x: auto; border-top: 1px solid @ navbar-border; background-color: @ navbar-background; // 1}}}

Трохи докладніше про це медіавираженіі:

  • Властивість position: fixed дозволяє абсолютно позиціонувати наше меню, щоб не «відсувати» блоки нижче нього.
  • Властивість overflow-y: hidden приховує все зайве зовні, а властивість overflow-x: auto дозволяє браузеру при бажанні відображати повзунок скролла.
  • Так як у нас абсолютне позиціонування, то необхідно вказати колір фону цього блоку.

зауваження

1. Якщо вас не бентежить те, що нижчестоящі блоки можуть зрушуватися вниз, то все помічені властивості можна прибрати.

демонстрація

Отже, якщо ви все таки долісталі або навіть дочитали до цього моменту, то ось вам гифка, що демонструє працездатність того, що ми тут накодо:

Зрозуміло, робочий приклад можна подивитися і покликати на CodePen .

Сподіваюсь вам сподобалось.

висновки

Це круто! Дійсно, Flexbox - це те, чого раніше не вистачало для простого і логічного управління блоками макета. Хочете змінити орієнтацію блоку щодо осі Y або X? - всього одна властивість і все готово. Хочете максимально рівномірно розподіляти блоки за доступною ширині? - знову одна властивість і все готово.

Так, Flexbox хороший, але має одне дуже вагоме обставина на користь того, щоб від нього тимчасово відмовитися - підтримка браузерами. Вірніше сказати, підтримка одного браузера, який до цих пір люблять замовники. Якщо ж ваші замовники не живуть в світі «минулому», то Flexbox, мабуть, хороша допомога верстальщику.

Зате в додатках, написаних на NW.js його можна використовувати скільки душі завгодно.

GetAttribute ( 'data-collapse'); // Повертаємо батьківський елемент або undefined return (isParentCollapse! == null)?
Хочете змінити орієнтацію блоку щодо осі Y або X?
Хочете максимально рівномірно розподіляти блоки за доступною ширині?


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью