Все заценят: как сделать сайт-портфолио на HTML, CSS и JavaScript
Фулстек-разработчик и автор канала Modern Web опубликовал туториал по созданию сайта-портфолио с помощью HTML, CSS и JavaScript. Ссылка на исходный код проекта и видеоинструкция — в материале. Давайте приступим!
Панель навигации
Начнем с создания панели навигации (Navbar) для сайта. Готовый архив с файлами для проекта хранится здесь.
Для создания navbar нужно написать базовый шаблон и связать файлы style.css
и app.js
. Затем выполнить следующий HTML-код:
<!-- navbar --> <nav class="navbar"> <ul class="link-group"> <li class="link active"><a href="#">home</a></li> <li class="link"><a href="#">projects</a></li> <li class="link"><a href="#">about</a></li> <li class="link"><a href="#">contact</a></li> </ul> </nav>
С HTML все, теперь добавим к нему немного CSS.
*{ margin: 0; padding: 0; box-sizing: border-box; } body{ width: 100%; max-width: 1400px; display: block; margin: auto; min-height: 100vh; background: #191919; font-family: sans-serif; } .navbar{ width: 100%; position: fixed; top: 0; left: 0; display: flex; justify-content: center; align-items: center; z-index: 9; background: #1a1a1a; } .link-group{ list-style: none; display: flex; } .link a{ color: #fff; opacity: 0.5; text-decoration: none; text-transform: capitalize; padding: 10px 30px; margin: 0 20px; line-height: 80px; transition: .5s; font-size: 20px; } .link a:hover, .link.active a{ opacity: 1; }
После выполнения этих действий должно получиться следующее:
Навигационная панель готова.
Более обстоятельно вам поможет разобраться с версткой курс от наших партнеров, школы Mate Academy и Hillel. Фронтенд разработчик востребованная и высокооплачиваемая работа, на которую стоит обратить внимание.
Главная страница
Для создания домашней страницы выполните следующий HTML-код после элемента navbar.
<!-- home section --> <section class="home-section active"> <h1 class="hero-heading">hello, i am <br> kunaal</h1> <img src="img/home.png" class="home-img" alt=""> </section>
Добавим CSS.
.home-section{ width: 100%; height: 100vh; padding: 0 150px; display: flex; align-items: center; position: relative; top: 0; opacity: 0; transition: 1s; } .hero-heading{ color: #fff; font-size: 120px; text-transform: capitalize; font-weight: 300; } .home-img{ position: absolute; top: 0; right: 0; height: 100vh; width: 50%; object-fit: cover; opacity: 0.2; }
- Под
.home-section
есть свойстваposition: relative
иtop:0
. Они важны при навигации. - Всем разделам (home, project, about, contact) задаем фиксированное значение (
position: fixed
). Благодаря этому они будут находиться друг над другом. - Для обозначения активного раздела используем класс active со следующими свойствами
position: relative
иopacity: 1
.
Как только закончите с домашней страницей, убедитесь, что изменили ее положение с relative
на fixed
.
.home-section{ /* previous styles */ position: fixed; }
Чтобы упростить навигацию, пропишите все разделы. Обозначаем активные разделы.
.home-section.active, .project-section.active, .about-section.active, .contact-section.active{ position: relative; opacity: 1; z-index: 8; }
Вот что должно получиться.
Страница с проектами
Создаем страницу с проектами. Для этого нужно выполнить следующий HTML-код.
<!-- project section --> <section class="project-section"> <h1 class="project-heading">some of my projects</h1> <div class="project-container"> <div class="project-card"> <img src="img/project-1.png" class="project-img" alt=""> <div class="project-content"> <h1 class="project-title">project 01</h1> <p class="project-info"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Impedit vitae delectus cumque repudiandae aliquam optio accusamus natus nobis! Nam, sunt? </p> <div class="project-btn-grp"> <button class="project-btn github">github repo</button> <button class="project-btn live">see live</button> </div> </div> </div> // +3 more cards </div> </section>
Стилизуем его.
/* project-section */ .project-section{ width: 100%; min-height: 100vh; padding: 150px 100px 100px; position: fixed; top: 0; transition: 1s; opacity: 0; } .project-heading{ font-size: 100px; background: #252525; text-transform: capitalize; text-align: center; margin-bottom: 50px; color: #1a1a1a; background-clip: text; -webkit-background-clip: text; -webkit-text-stroke: 8px transparent; } .project-container{ display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 100px; } .project-card{ height: 400px; position: relative; } .project-img{ width: 100%; height: 100%; position: absolute; top: 0; left: 0; object-fit: cover; transition: .5s; } .project-content{ position: relative; padding: 40px; color: #fff; transition: .5s; opacity: 0; } .project-title{ font-size: 50px; text-transform: capitalize; text-align: center; font-weight: 300; } .project-info{ margin: 40px; font-size: 20px; line-height: 30px; text-align: center; } .project-btn-grp{ display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 20px; } .project-btn{ height: 40px; text-transform: capitalize; font-size: 18px; border: none; background: #000; color: #fff; cursor: pointer; } .project-btn.live{ background: none; border: 2px solid #fff; } .project-card:hover .project-img{ filter: blur(20px); } .project-card:hover .project-content{ opacity: 1; }
В приведенном выше коде в project-section
уже добавлена позиция fixed
, а opacity
установлено в значение 0
. Но для того, чтобы увидеть результат, убедитесь, что добавили класс active в секцию проекта следующим образом.
<section class="project-section active">
Вот что должно получиться.
Навигация
Прежде чем двигаться дальше, нужно создать систему навигации сайта. Для этого пропишите в файле app.jss
следующий код.
const links = document.querySelectorAll('.link'); const sections = document.querySelectorAll('section'); let activeLink = 0; links.forEach((link, i) => { link.addEventListener('click', () => { if(activeLink != i){ links[activeLink].classList.remove('active'); link.classList.add('active'); sections[activeLink].classList.remove('active'); setTimeout(() => { activeLink = i; sections[i].classList.add('active'); }, 1000); } }) })
В приведенном выше коде сначала выделяются все ссылки и разделы. После этого определяется переменная activeLink
, которая будет отслеживать текущий активный раздел или ссылку. После этого используется метод forEach
— для перебора всех ссылок. Внутри него можно получить доступ к отдельной ссылке и ее индексу.
Сначала добавляется событие щелчка на ссылку с помощью addEventListener
. Затем используется простое условие, чтобы убедиться, что пользователь не щелкает по активной ссылке. После этого удаляется активный класс из текущей активной ссылки с помощью classList.remove
и добавляется класс active
в нажатую ссылку с помощью classList.add
. То же самое делается для удаления класса active
из активного раздела.
Чтобы добавить задержку в 1 секунду для выполнения приведенных далее кодов, используется setTimeout
. Внутри таймаута происходит простое добавление активного класса.
С навигацией все.
Страница «О себе»
В этом разделе About будет раздел с навыками, а также шкала опыта.
Чтобы создать страницу «О себе», пропишите этот код после project section
.
<!-- about section --> <section class="about-section"> <div class="about"> <div class="about-img-container"> <img src="img/home.png" class="about-img" alt=""> <button class="download-cv-btn">downlaod cv</button> </div> <p class="about-info">Lorem ipsum.....</p> </div> </section>
Подключим CSS.
/* about-section */ .about-section{ width: 100%; min-height: 100vh; padding: 150px 100px 0; position: fixed; top: 0; opacity: 0; transition: 1s; } .about{ width: 100%; display: grid; grid-template-columns: 30% 65%; grid-gap: 40px; } .about-img-container{ position: relative; } .about-info{ color: #fff; opacity: 0.6; font-size: 20px; line-height: 40px; } .about-img{ width: 100%; height: 100%; object-fit: cover; border-radius: 20px; } .download-cv-btn{ position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); padding: 10px 20px; color: #fff; border: none; font-size: 16px; text-transform: capitalize; cursor: pointer; transition: .5s; background: rgba(0, 0, 0, 0.5); } .download-cv-btn:hover{ background: #000; }
Примечание: убедитесь, что добавили класс active
в раздел «О себе» и удалили его из всех остальных разделов.
Вот что должно получиться.
Теперь создадим раздел навыков. В нем также будут индикаторы навыков. Ранее мы писали о том, почему не нужно рисовать шкалу навыков в резюме, но все же рассмотрим, как ее сделать.
<!-- skills --> <div class="skill-section"> <h1 class="heading">skills</h1> <div class="skills-container"> <div class="skill-card"> <img src="img/html.png" class="skill-img" alt=""> <div class="skill-level">98%</div> <h1 class="skill-name">HTML</h1> <p class="skill-info">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Consequatur, delectus!</p> </div> // +4 more cards </div> </div>
Пропишите вышеописанный код над элементом about-section
и стилизуйте его.
/* skills */ .skill-section{ position: relative; margin: 100px 0; } .heading{ text-align: center; font-size: 60px; color: #fff; text-transform: capitalize; font-weight: 300; margin-bottom: 100px; } .skills-container{ width: 95%; margin: auto; display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 100px; color: #fff; } .skill-card{ position: relative; } .skill-img{ display: block; margin: auto; height: 200px; } .skill-name{ font-size: 30px; font-weight: 300; text-align: center; text-transform: capitalize; margin: 30px 0 20px; } .skill-info{ text-align: center; opacity: 0.5; font-size: 18px; line-height: 30px; } .skill-level{ position: absolute; top: 80px; right: 0; width: 150px; height: 150px; display: flex; justify-content: center; align-items: center; font-size: 22px; border-radius: 50%; border: 10px solid; } .skill-card:nth-child(1) .skill-level{ background: #ff4f4f28; border-color: #ff4f4f; color: #ff4f4f; } .skill-card:nth-child(2) .skill-level{ background: #4fa0ff28; border-color: #4fa0ff; color: #4fa0ff; } .skill-card:nth-child(3) .skill-level{ background: #ffed4f28; border-color: #ffed4f; color: #ffed4f; } .skill-card:nth-child(4) .skill-level{ background: #52ff4f28; border-color: #52ff4f; color: #52ff4f; } .skill-card:nth-child(5) .skill-level{ background: #4fdfff28; border-color: #4fdfff; color: #4fdfff; }
Вот что получится.
Создаем временную шкалу опыта.
<!-- timeline --> <div class="timeline"> <h1 class="heading">education and experience</h1> <div class="card"> <div class="card-body"> <h1 class="card-title">2000-2002</h1> <p class="card-detail">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Architecto sequi recusandae laborum ipsam dignissimos nostrum vitae provident officia, consectetur ab accusantium corrupti exercitationem temporibus repellat non magni cupiditate ea reprehenderit.</p> </div> </div> //+4 more cards </div>
Не забудьте добавить коды в раздел About.
/* timeline */ .timeline{ display: block; width: 80%; margin: 150px auto; } .timeline .heading{ margin-bottom: 150px; } .card{ width: 45%; padding: 30px; border-radius: 10px; color: #fff; display: block; margin: -80px 0; position: relative; background: #f00; } .card:nth-child(even){ margin-left: auto; } .card:nth-child(even):before{ content: ''; position: absolute; left: -15%; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; border: 5px solid #191919; border-radius: 50%; } .card:nth-child(even):after{ content: ''; position: absolute; left: -8.5%; top: 50%; transform: translateY(-50%); width: 7%; height: 2px; background: #fff; z-index: -1; } .card:nth-child(odd):before{ content: ''; position: absolute; right: -13%; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; border: 5px solid #191919; border-radius: 50%; } .card:nth-child(odd):after{ content: ''; position: absolute; right: -8.5%; top: 50%; transform: translateY(-50%); width: 7%; height: 2px; background: #fff; z-index: -1; } .card:nth-child(2), .card:nth-child(2):before{ background: #ff4f4f; } .card:nth-child(3), .card:nth-child(3):before{ background: #ffb84f; } .card:nth-child(4), .card:nth-child(4):before{ background: #3dca5c; } .card:nth-child(5), .card:nth-child(5):before{ background: #565252; } .card:nth-child(6), .card:nth-child(6):before{ background: #4fa0ff; } .card:nth-child(even) .card-body:before{ content: ''; position: absolute; left: -12%; top: 0; width: 0px; height: 100%; border: 1px dashed #fff; z-index: -1; } .card-title{ font-size: 30px; font-weight: 300; margin-bottom: 20px; }
Вот что должно получиться.
Страница с контактной информацией
Чтобы создать раздел «Контакты», пропишите следующий код.
<!-- contact section --> <section class="contact-section"> <form class="contact-form"> <input type="text" name="name" id="name" autocomplete="off" placeholder="name"> <input type="text" name="email" id="email" autocomplete="off" placeholder="email"> <textarea name="msg" id="msg" placeholder="message" autocomplete="off"></textarea> <button type="submit" class="form-submit-btn">contact</button> </form> <!-- map --> <div class="map"> <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d448181.163742937!2d76.81306771991275!3d28.647279935262464!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x390cfd5b347eb62d%3A0x37205b715389640!2sDelhi!5e0!3m2!1sen!2sin!4v1639489002410!5m2!1sen!2sin" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy"></iframe> </div> </section>
В приведенном выше коде iframe
— это ссылка для встраивания карты Google.
.contact-section{ position: absolute; top: 0; opacity: 0; transition: 1s; padding: 100px 150px; height: 100vh; display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 50px; } .contact-form input, .contact-form textarea{ width: 100%; height: 40px; background: rgba(255, 255, 255, 0.2); border: 1px solid #fff; margin-bottom: 30px; border-radius: 5px; text-transform: capitalize; color: #fff; padding: 5px 10px; } ::placeholder{ color: #fff; } #msg{ height: 280px; resize: none; font-family: sans-serif; } .form-submit-btn{ background: #ff4f4f; color: #fff; text-transform: capitalize; padding: 15px 40px; display: block; margin: auto; border: none; border-radius: 10px; cursor: pointer; } .map{ width: 100%; height: 100%; padding: 10px; border: 2px solid #fff; background: rgba(255, 255, 255, 0.2); border-radius: 10px; } .map iframe{ width: 100%; height: 100%; border-radius: 5px; }
Вот что должно получиться.
Вот и все. Сайт-портфолио готов. Видеоинструкцию по созданию проекта найдете ниже. Также автор разместил исходный код, но он доступен только его подписчикам на Patreon.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: