В рамках данного урока сделаем шапку сайта состоящую из верхнего меню, блока с логотипом и рекламой, и нижнего меню с формой поиска всплывающей по клику.
Весь этот блок будет выглядеть так:
Чтобы сверстать данный блок возьмем стартовый шаблон bootstrap 5:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<h1>Привет, мир!</h1>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
Верстка Header (шапки)
За основу возьмем готовы пример под названием Double header, вот его html:
<nav class="py-2 bg-body-tertiary border-bottom">
<div class="container d-flex flex-wrap">
<ul class="nav me-auto">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2 active" aria-current="page">Home</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Features</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Pricing</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">FAQs</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">About</a></li>
</ul>
<ul class="nav">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Login</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Sign up</a></li>
</ul>
</div>
</nav>
<header class="py-3 mb-4 border-bottom">
<div class="container d-flex flex-wrap justify-content-center">
<a href="/" class="d-flex align-items-center mb-3 mb-lg-0 me-lg-auto link-body-emphasis text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"/></svg>
<span class="fs-4">Double header</span>
</a>
<form class="col-12 col-lg-auto mb-3 mb-lg-0" role="search">
<input type="search" class="form-control" placeholder="Search..." aria-label="Search">
</form>
</div>
</header>
И компонент Navbar, вот его html:
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Ссылка</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Искать</button>
</form>
</div>
</div>
</nav>
Объединим все это воедино, получаем следующее:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Верстка Bootstrap шапки</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<nav class="py-2 bg-body-tertiary border-bottom">
<div class="container d-flex flex-wrap">
<ul class="nav me-auto">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Об авторе</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Мои услуги</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Портфолио</a></li>
</ul>
<ul class="nav">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Иконка 1</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Иконка 2</a></li>
</ul>
</div>
</nav>
<header class="py-3 mb-4 border-bottom">
<div class="container d-flex flex-wrap justify-content-center">
<a href="/" class="d-flex align-items-center mb-3 mb-lg-0 me-lg-auto link-body-emphasis text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"/></svg>
<span class="fs-4">Double header</span>
</a>
<form class="col-12 col-lg-auto mb-3 mb-lg-0" role="search">
<input type="search" class="form-control" placeholder="Search..." aria-label="Search">
</form>
</div>
</header>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Ссылка</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Искать</button>
</form>
</div>
</div>
</nav>
<h1>Привет, мир!</h1>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
Выглядит это сейчас так:
Почти то, но не то, в общем нужно дорабатывать, пойдем сверху в низ.
С правой стороны у нас иконки соц сетей. Добавить их можно по разному: как картинки, как svg и т.д. Я возьму популярный иконочный шрифт Font Awesome, подключим его в head при помощи CDN:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
И выведем нужные иконки, в результате код данного блока примет следующий вид:
<nav class="py-2 bg-body-tertiary border-bottom">
<div class="container d-flex flex-wrap">
<ul class="nav me-auto">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Об авторе</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Мои услуги</a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2">Портфолио</a></li>
</ul>
<ul class="nav">
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2"><i class="fa-brands fa-vk"></i></a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2"><i class="fa-brands fa-square-odnoklassniki"></i></a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2"><i class="fa-brands fa-square-whatsapp"></i></a></li>
<li class="nav-item"><a href="#" class="nav-link link-body-emphasis px-2"><i class="fa-brands fa-telegram"></i></a></li>
</ul>
</div>
</nav>
Вот его внешний вид:
Теперь правим header: удляем из него svg код иконки бутстрап и надпись Double header, вместо них выводим логотип, а в место формы банер.
<header class="py-3 border-bottom">
<div class="container d-flex flex-wrap justify-content-center">
<a href="/" class="d-flex align-items-center mb-3 mb-lg-0 me-lg-auto link-body-emphasis text-decoration-none">
<img class="img-fluid" src="https://web-revenue.ru/demo/bootstrap-header/images/logo2retina.png" alt="логотип" width="190" height="90">
</a>
<a href="#" class="col-12 col-lg-auto">
<img class="img-fluid" src="https://web-revenue.ru/demo/bootstrap-header/images/static728x90_1.png" alt="банер">
</a>
</div>
</header>
Ну и осталось нижнее меню, оно сейчас во всю ширину, исправим это заменив класс container-fluid
на container
. Удалим блок с логотипом, который имеет класс navbar-brand.
Блок с формой поиска переносим на 1 уровень ниже (перед закрытием container
), чтобы в мобилке данный блок не скрывался под бургер. И переделываем form
: превращаем в div
, вместо остального содержимого выводим иконку лупы обернутую в ссылку с каким нибудь классом.
<div class="d-flex">
<a class="nav-search" href="javascript:;" title="поиск по сайту"><i class="fas fa-search"></i></a>
</div>
После всех этих манипуляций если все сделали правильно должны получить вот такой внешний вид.
Дело осталось за малым — форма поиска, которая появляется после нажатия на соответствующую иконку.
Добавим под иконку поиска вот такую форму:
<form class="search-box" action="#">
<div class="input-group">
<input type="text" class="form-control" placeholder="Поисковой запрос..." name="search" aria-label="Поиск" value="">
<span class="input-group-btn search">
<button class="btn btn-search" type="submit"><i class="fas fa-search"></i></button>
</span>
</div>
</form>
Сразу оформим ее и скроем.
.navbar .container {
position: relative; /*Устанавливаем позицию элемента с классом 'navbar .container' как относительную. Это позволяет позиционировать элементы внутри него относительно его собственного контекста.*/
}
.search-box{
display: none; /* Скрываем данный блок на странице. */
right: 0;
left: auto;
padding: 11px;
background-color: #f8f9fa;
position: absolute; /*Задаем положение элемента как абсолютное, чтобы он мог быть позиционирован относительно ближайшего позиционированного предка.*/
box-shadow: 5px 5px rgba(91,91,91,0.2);
width: 274px;
margin-top: 30px;
z-index: 22;
}
/* Устанавливаем стили для кнопки поиска внутри элемента с классом 'input-group-btn'. Здесь мы задаем цвет фона кнопки как белый, радиус границы как 0 5px 5px 0, и границу как 1px solid #dee2e6. */
.input-group-btn .btn-search {
background-color: #fff;
border-radius: 0 5px 5px 0;
border: 1px solid #dee2e6;
}
@media (max-width: 991px) {
.nav-search {
position: absolute; /*Чтобы его не перекидывало в низ при открытии бургера.*/
left: auto;
right: 15px;
top: 7px;
}
}
И сразу оживим кнопку поиска добавив немного JS:
document.addEventListener('DOMContentLoaded', function() {
var btnSearch = document.querySelector('.btn-search');
btnSearch.addEventListener('click', function(event) {
var hiddenElements = document.querySelectorAll('.search-box');
hiddenElements.forEach(function(element) {
element.classList.toggle('d-block');
});
event.preventDefault();
});
});
document.addEventListener('DOMContentLoaded', function() {
— Эта строка кода добавляет обработчик события ‘DOMContentLoaded’ к объекту document. Это означает, что функция, которую мы передаем в качестве аргумента, будет вызвана, когда HTML-документ будет полностью загружен и проанализирован.var btnSearch = document.querySelector('.btn-search');
— Эта строка кода выбирает первый элемент на странице с классом ‘btn-search’ и сохраняет его в переменной btnSearch.btnSearch.addEventListener('click', function(event) {
— Эта строка кода добавляет обработчик события ‘click’ к элементу, сохраненному в переменной btnSearch. Это означает, что когда пользователь кликает на этот элемент, будет вызвана функция, которую мы передаем в качестве аргумента.var hiddenElements = document.querySelectorAll('.box-none');
— Эта строка кода выбирает все элементы на странице с классом ‘box-none’ и сохраняет их в массиве hiddenElements.hiddenElements.forEach(function(element) {
— Эта строка кода вызывает функцию forEach для массива hiddenElements, что означает, что для каждого элемента в массиве будет вызван указанный лямбда-функционал.element.classList.toggle('d-block');
— Эта строка кода вызывает метод toggle для класса ‘d-block’ у текущего элемента. Метод toggle добавляет или удаляет указанный класс, в зависимости от того, присутствует ли он уже у элемента.event.preventDefault();
— Эта строка кода предотвращает стандартное действие события ‘click’. В данном случае, это предотвращает переход по ссылке, если элемент ‘btn-search’ является ссылкой.
Готово, теперь наша форма оформлена и всплывает по клику на иконку поиска и скрывается при повторном клике.
Весь финальный код можно посмотреть в demo (нажав CTRL + U)