Сегодня будем верстать секцию Hero нашего шаблона, установим фоновое изображение на весь экран и создадим компонент Button. Также проведем небольшой рефакторинг кода, написанного в прошлых уроках. Будет интересно. Погнали!
Полезные ссылки:
Часть 1. Подготовка и настройка проекта
Часть 2. Настройка конфигурации и установка необходимых библиотек
Часть 3. Создание CSS-переменных и верстка блока Header
Часть 4. Верстка секции Hero, создание компонента Button
Часть 5. Верстка секции About
Часть 6. Верстка секции Gallery
Часть 7. Верстка секции WhyUs
Часть 8. Верстка секции Catalogue
Часть 9. Верстка секции Map
Часть 10. Верстка секции Footer
Часть 11. Создание якорных ссылок, рефакторинг
Часть 12. Создание мобильного меню
Часть 13. Анимация секций при скролле
Часть 14. Установка метаданных
Часть 15. Настройка Favicon.ico
Часть 16. Настройка счетчика Яндекс Метрики
Часть 17. Публикуем проект на хостинге
Рефакторинг блока Header
Для начала немного поработаем с уже готовыми компонентами. В нашем блоке Header мы явно указали высоту (h-20), для отображения на мобильных устройствах этого явно недостаточно, поэтому заменим значение на (lg:h-20), тем самым мы укажем, что фиксированная высота будет применяться на разрешениях выше 1024px.
Также поправим ссылки на почту и соцсети, сейчас необходимо кликнуть точно по иконке, чтобы перейти по ссылке. Поменяем местами блоки Link и div, а также добавим анимацию при наведении на получившуюся кнопку.
Итоговый код блока Header
import { IoMdMail } from 'react-icons/io';
import { BiLogoTelegram } from 'react-icons/bi';
import { GiHamburgerMenu } from 'react-icons/gi';
import Link from 'next/link';
export default function Header() {
return (
<header className='flex justify-between lg:h-20 mt-7'>
<div className='flex grow flex-col lg:flex-row lg:justify-between lg:items-center gap-2'>
<Link href='/' className='font-black text-4xl'>
Логотип
</Link>
<div className='flex flex-col lg:flex-row lg:justify-between lg:items-center gap-2 lg:gap-12'>
<nav className='hidden lg:block'>
<ul className='flex gap-12 font-light'>
<li>
<Link href={'#products'}>Наша продукция</Link>
</li>
<li>
<Link href={'#about'}>О нас</Link>
</li>
<li>
<Link href={'#contacts'}>Контакты</Link>
</li>
</ul>
</nav>
<span className='font-black'>+7 999 888 88 88</span>
<div className='flex gap-6 items-start'>
<Link href={'mailto:mail@email.ru'}>
<div className='flex bg-primary hover:brightness-110 rounded-md text-on-primary p-2 transition-all duration-200 ease-in-out'>
<IoMdMail className='flex bg-primary rounded-md text-on-primary' size={18} />
</div>
</Link>
<Link href={'tg://resolve?domain=@someTgAccountName'}>
<div className='flex bg-primary hover:brightness-110 rounded-md text-on-primary p-2 transition-all duration-200 ease-in-out'>
<BiLogoTelegram size={18} />
</div>
</Link>
</div>
</div>
</div>
<div className='block lg:hidden'>
<GiHamburgerMenu size={40} />
</div>
</header>
);
}
Немного семантической разметки page.jsx
Для правильной семантической разметки нашего лендинга обернем все будущие секции в тег <main></main>.
О том, что такое семантическая разметка, будет отдельная статья, поэтому не забудьте подписаться, чтобы не пропустить.
Итоговый код page.jsx
import Hero from './components/sections/Hero';
export default function Home() {
return (
<main>
<Hero />
</main>
);
}
Толщина шрифта layout.jsx
Добавим больше значений насыщенности (толщины) шрифта, для этого в файле layout.jsx добавьте в настройки шрифта значения
weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
Загрузка изображений
Все изображения мы будем хранить в папке app/images. Создайте ее вручную и подготовьте любое понравившееся изображение в формате .jpg, переименуйте его в hero.jpg и перенесите в эту папку.
Компонент Button.jsx
В папке components/elements создайте файл Button.jsx. Мы создадим отдельный компонент для того, чтобы в будущем, когда нам понадобятся кнопки для нашего сайта, мы могли использовать уже готовую структуру и не засорять код. Нам нужен единый дизайн и возможность передать в компонент текст кнопки и ее ссылку (в нашем случае якорную ссылку на секцию).
Итоговый код Button.jsx
export default function Button({ name, href }) {
return (
<a
className='w-max uppercase font-light bg-primary text-on-primary hover:brightness-110 px-5 py-4 rounded-lg transition-all duration-200 ease-in-out'
href={href}
>
<span>{name}</span>
</a>
);
}
Верстка секции Hero.jsx
Высота секции Hero, как на большинстве существующих лендингов, будет равняться высоте окна браузера, задаем это свойством (min-h-screen).
С помощью абсолютного позиционирования мы размещаем наше фоновое изображение и растягиваем его по размеру родительского контейнера.
Также добавляем блок с затемнением нашего фонового изображения. Индексами (z) регулируем позиционирование слоев.
Учитывая то, что наш фон темный, нам необходимо явно указать, что шрифты должны быть светлыми (text-neutral-50).
Итоговый код Hero.jsx
import Header from '../blocks/Header';
import heroImage from '@/app/images/hero.jpg';
import ExportedImage from 'next-image-export-optimizer';
import Button from '../elements/Button';
export default function Hero() {
return (
<section className='flex min-h-screen relative w-full overflow-hidden z-0 text-neutral-50'>
<div className='absolute inset-0'>
<ExportedImage
alt='background image'
src={heroImage.src}
fill
placeholder='blur'
className='object-center object-cover'
/>
</div>
<div className='absolute inset-0 bg-neutral-900 opacity-60 z-10' />
<div className='flex flex-col w-full px-5 mx-auto max-w-screen-xl z-20'>
<Header />
<div className='flex my-auto flex-col lg:text-center lg:items-center w-full mx-auto'>
<h1 className='uppercase text-2xl lg:text-6xl font-black mb-10'>
Строительство комфортных
<br />
загородных домов
</h1>
<span className='text-2xl font-thin mb-10 lg:mb-20'>
Строительство деревянных домов по уникальным проектам
</span>
<Button name={'Перейти в каталог'} href={'#catalogue'} />
</div>
</div>
</section>
);
}
После всех манипуляций с кодом и сохранения вы должны получить такой результат:
На сегодня всё!
В следующей статье мы сверстаем секцию с текстовым блоком и изображением.
Код данного урока доступен в репозитории GitHub по ссылке.
Не забудь подписаться на канал, а также заходи на мой блог blog.in9var.ru, а также можешь посетить мой основной сайт — in9var.ru.