스크롤(scroll) 포트폴리오
: 스크롤을 내려가며 볼 수 있는 포트폴리오
사용 언어
- HTML
- CSS
- Javascript
구조
- index.html - 전체 구조
- index.js - 기능 구현
- main.css - 전체 디자인
코드
구현 계획 & 기능 구현
1. 메뉴바 생성
1-2. 상단에 고정 - position: fixed;
1-3. 서브메뉴 위치 설정 - <a> 태그 이용
2. 본문
2-1. 메뉴마다 나누기 - <section> 태그 이용
2-2. 내용 넣기
(1) Home
- 자기소개 (간략)
(2) About
- 깃허브, 벨로그 버튼
(3) Skills
- 가능 언어
- 가능 프로그램
(4) Projectst
- 자바 세미 프로젝트 - 캐러셀 슬라이드
(5) Contact me
- 이메일 주소
- 연락처
3. 스크롤 이벤트
3-1. 스크롤 진행바 넣기
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="main.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap');
</style>
</head>
<body>
<!-- 스크롤 진행바 -->
<div class="progress"></div>
<!-- 상단 메뉴 -->
<nav class="menu">
<ul class="list-group">
<li class="list-item">
<a href="#home">Home</a>
</li>
<li class="list-item">
<a href="#about">About</a>
</li>
<li class="list-item">
<a href="#skills">Skills</a>
</li>
<li class="list-item">
<a href="#projects">Projects</a>
</li>
<li class="list-item">
<a href="#contact">Contact</a>
</li>
</ul>
</nav>
<div id="container">
<!-- 메인 -->
<section id="home" class="section">
<div class="title">
<h2>권<span>보령</span></h2>
<img src="image.jpg" alt="My image" style="width: 270px; height: 300px;">
<h4>끊임없이 성장하는 자</h4>
<p></p>
<p id="a">안녕하세요,<br/>
프론트엔드 개발자 권보령입니다.<br/></P>
<P id="a">끊임없이 배우며 성장하는 것을 좋아합니다.<br/>
스터디를 하며 지식을 나누고
개발 블로그를 운영하며 약 70개의 포스팅을 작성하였습니다.
</p>
<p> 추리 소설과 같은 매력을 가진 코딩에 흥미가 생겼고, <br/>
마크업 언어에 대한 호기심에 혼자 개발을 공부하며
프론트엔드 개발자를 꿈꾸게 되었습니다. <br/>
</p>
<p> 수많은 도전과 경험을 통해 다양한 기술 스택을 쌓아 <br/>
최고의 UX를 제공할 수 있는 프론트엔드 개발자가 되고 싶습니다.
</p>
</div>
</section>
<!-- About -->
<section id="about" class="section" style="background-color: rgb(251, 248, 243);">
<div class="title">
<h2>About <span id="me">me</span></h2>
<!-- 색상을 다르게 주기 위해 <span> 태그 사용 -->
</div>
<h4 style="font-size: 20px; text-align: center;">성실의 미덕</h4>
<p id="a">
그것이 제 무기입니다.<br/>
꾸준히, 조금씩, 길게 떨어지는 물방울이 결국 바위를 부식시키는 것처럼, <br/>
아무리 어렵고 힘든 일이라도 성실한 물방울이 된다면 해내지 못할 일이 없다고 생각합니다.
</p>
<p id="a">
저는 이러한 제 신조에 맞게 곧게 살아가려고 항상 노력하는 사람입니다. <br/>
작은 일도 성실하게, 한번 시작한 일은 끝까지 책임지고 마무리하는 것을 좋아합니다.
</p>
<div class="iconabout">
<a href="https://velog.io/@kwonboryong/posts">
<svg style="width: 90px; height: 90px;" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Velog</title><path d="M3 0C1.338 0 0 1.338 0 3v18c0 1.662 1.338 3 3 3h18c1.662 0 3-1.338 3-3V3c0-1.662-1.338-3-3-3H3Zm6.883 6.25c.63 0 1.005.3 1.125.9l1.463 8.303c.465-.615.846-1.133 1.146-1.553.465-.66.893-1.418 1.283-2.273.405-.855.608-1.62.608-2.295 0-.405-.113-.727-.338-.967-.21-.255-.608-.577-1.193-.967.6-.765 1.35-1.148 2.25-1.148.48 0 .878.143 1.193.428.33.285.494.704.494 1.26 0 .93-.39 2.093-1.17 3.488-.765 1.38-2.241 3.457-4.431 6.232l-2.227.156-1.711-9.628h-2.25V7.24c.6-.195 1.305-.406 2.115-.63.81-.24 1.358-.36 1.643-.36Z"/></svg>
</a>
<a href="https://github.com/kwonboryong">
<svg style="width: 90px; height: 90px;" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
</a>
</div>
</section>
<!-- skills -->
<section id="skills" class="section">
<div class="title">
<h2>Skills</h2>
<h4>가능한 언어</h4>
<p id="a">HTML, CSS, Javascript, Java</p>
<div class="icon">
<img alt="Html" src ="https://img.shields.io/badge/HTML5-E34F26.svg?&style=for-the-badge&logo=HTML5&logoColor=white"/>
<img alt="Css" src ="https://img.shields.io/badge/CSS3-1572B6.svg?&style=for-the-badge&logo=CSS3&logoColor=white"/>
<img alt="JavaScript" src ="https://img.shields.io/badge/JavaScript-F7DF1E.svg?&style=for-the-badge&logo=JavaScript&logoColor=black"/>
<img src="https://img.shields.io/badge/java-3CB371?style=for-the-badge&logo=OpenJDK&logoColor=white">
</div>
<h4 id="untitle">가능한 프로그램</h4>
<p id="a">VS-code, Eclipse, Intelli-J, Oracle</p>
<div>
<svg style="width: 70px; height: 70px" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Visual Studio Code</title><path d="M23.15 2.587L18.21.21a1.494 1.494 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a.999.999 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a.999.999 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.492 1.492 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352zm-5.146 14.861L10.826 12l7.178-5.448v10.896z"/></svg>
<svg style="width: 70px; height: 70px" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Eclipse IDE</title><path d="M11.109.024a15.58 15.58 0 00-.737.023C6.728.361 3.469 2.517 1.579 5.86A12.53 12.53 0 00.021 11.11c-.04.517-.02 1.745.035 2.208.306 2.682 1.353 5.06 3.07 6.965 1.962 2.173 4.586 3.467 7.437 3.663.42.032 1.043.04 1.02.012a2.404 2.404 0 00-.338-.074c-1.674-.33-3.388-1.13-4.777-2.232a12.344 12.344 0 01-2.45-2.636A12.387 12.387 0 011.884 12.5a12.413 12.413 0 01.56-4.274c.785-2.522 2.37-4.726 4.475-6.228A11.073 11.073 0 0111.156.122l.443-.098zm1.474.51C10.646.65 8.807 1.299 7.301 2.4 5.426 3.77 3.995 5.644 3.22 7.746c-.145.397-.282.82-.282.879 0 .012 3.828.024 10.31.024 8.463 0 10.315-.008 10.315-.036 0-.047-.153-.525-.283-.878-.153-.42-.576-1.31-.82-1.722-.4-.683-.91-1.373-1.474-1.992-1.65-1.82-3.593-2.934-5.82-3.334-.785-.141-1.8-.2-2.585-.153zM23.83 9.97c-.02 0-4.792 0-10.609.004l-10.573.008-.011.059c-.036.16-.134 1.081-.134 1.242 0 .028 1.785.032 10.746.032H24v-.075c0-.102-.07-.791-.106-1.054-.02-.16-.04-.216-.063-.216zm-10.573 2.635c-9.37-.004-10.73 0-10.742.035-.02.04.024.557.075.973.02.157.035.298.035.314 0 .027 2.137.035 10.624.035h10.624l.024-.188c.043-.326.102-.97.094-1.067l-.008-.094zm.003 2.718c-8.882 0-10.321.004-10.321.035 0 .02.054.208.12.42a11.122 11.122 0 002.072 3.741c.282.342.945 1.036 1.228 1.287 1.568 1.4 3.247 2.216 5.18 2.53.605.094.886.113 1.75.11.91 0 1.297-.032 2.023-.177 2.11-.416 3.914-1.451 5.53-3.17 1.267-1.348 2.106-2.76 2.628-4.41l.117-.366z"/></svg>
<svg style="width: 70px; height: 70px" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>IntelliJ IDEA</title><path d="M0 0v24h24V0zm3.723 3.111h5v1.834h-1.39v6.277h1.39v1.834h-5v-1.834h1.444V4.945H3.723zm11.055 0H17v6.5c0 .612-.055 1.111-.222 1.556-.167.444-.39.777-.723 1.11-.277.279-.666.557-1.11.668a3.933 3.933 0 0 1-1.445.278c-.778 0-1.444-.167-1.944-.445a4.81 4.81 0 0 1-1.279-1.056l1.39-1.555c.277.334.555.555.833.722.277.167.611.278.945.278.389 0 .721-.111 1-.389.221-.278.333-.667.333-1.278zM2.222 19.5h9V21h-9z"/></svg>
<svg style="width: 70px; height: 70px" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Oracle</title><path d="M16.412 4.412h-8.82a7.588 7.588 0 0 0-.008 15.176h8.828a7.588 7.588 0 0 0 0-15.176zm-.193 12.502H7.786a4.915 4.915 0 0 1 0-9.828h8.433a4.914 4.914 0 1 1 0 9.828z"/></svg>
</div>
</div>
</section>
<!-- projects -->
<section id="projects" class="section">
<div class="title">
<h2>Projects</h2>
<h4>지하철 혼잡도 관리 시스템</h4>
<p style="font-size: 17px; margin-top: -10px;">2024-01-29 ~ 2024-02-08</p>
<p id="a">지하철 혼잡도 제공을 통한 역 혼잡도 관리</p>
<!-- 캐러셀 슬라이드 -->
<div style="overflow: hidden;">
<div class="slide-container">
<div class="slide-box">
<img style="width: 600px; height: 350px;" src="project.png" alt="project">
</div>
<div class="slide-box">
<img style="width: 600px; height: 350px;" src="project2.png" alt="project">
</div>
<div class="slide-box">
<img style="width: 600px; height: 350px;" src="project3.png" alt="project">
</div>
</div>
</div>
<div class="btn-slide">
<button class="slide-1">1</button>
<button class="slide-2">2</button>
<button class="slide-3">3</button>
</div>
<div class="btn-next">
<button class="before">이전</button>
<button class="next">다음</button>
</div>
</div>
</section>
<!-- contact -->
<section id="contact" class="section" style="background-color: rgb(251, 248, 243);">
<div class="title">
<h2>Contact <span id="me">me</span></h2>
<h4>Email</h4>
<p id="a">kwonboryong@naver.com</p>
<h4 id="untitle">Phone</h4>
<p id="a">010-1234-1234</p>
</div>
</section>
</div>
<script src="index.js"></script>
</body>
</html>
index.js
// 스크롤 진행바
window.addEventListener('scroll', function() {
var sHeight = document.querySelector('html').scrollHeight;
var cHeight = document.querySelector('html').clientHeight;
var sTop = document.querySelector('html').scrollTop;
const prg = ((sTop + cHeight) / sHeight) * 100;
// document.querySelector('.progress').style.width = progress + "%";
console.log(prg);
if (prg < 17) {
this.document.querySelector('.progress').style.width = '0%';
} else if (prg < 22) {
this.document.querySelector('.progress').style.width = '20%';
} else if (prg < 40) {
this.document.querySelector('.progress').style.width = '30%';
} else if (prg < 65) {
this.document.querySelector('.progress').style.width = '40%';
} else if (prg < 75) {
this.document.querySelector('.progress').style.width = '60%';
} else if (prg < 80) {
this.document.querySelector('.progress').style.width = '80%';
} else if (prg > 95) {
this.document.querySelector('.progress').style.width = '100%';
}
});
// 캐러셀 슬라이드
// 숫자 버튼
/* 2번 버튼 클릭 시 - 2번 사진 가져오기(1번 사진을 왼쪽으로 밀기) */
document.getElementsByClassName('slide-2')[0].addEventListener('click', function() {
document.querySelector('.slide-container').style.transform = 'translateX(-100vw)'
now = 2;
// ***숫자 버튼에서도 현재 사진 변수(now)를 신경 써야 한다!
});
// 3번 버튼
document.getElementsByClassName('slide-3')[0].addEventListener('click', function() {
document.querySelector('.slide-container').style.transform = 'translateX(-200vw)'
now = 3;
});
// 1번 버튼
document.getElementsByClassName('slide-1')[0].addEventListener('click', function() {
document.querySelector('.slide-container').style.transform = 'translateX(0vw)'
now = 1;
});
// 다음 버튼
var now = 1; // 현재 사진 변수
document.querySelector('.next').addEventListener('click', function() {
if (now == 3) { // 마지막 장에서 '다음'을 누르면 첫 번째 장이 나오도록
document.querySelector('.slide-container').style.transform = 'translateX(0vw)'
now = 1;
} else {
document.querySelector(".slide-container").style.transform = "translateX(-" + now + "00vw)";
now++;
}
});
// 이전 버튼
document.querySelector('.before').addEventListener('click', function() {
if (now == 1) { // 첫 번째 장에서 '이전'을 누르면 마지막 장이 나오도록
document.querySelector('.slide-container').style.transform = 'translateX(-200vw)'
now = 3;
} else {
document.querySelector(".slide-container").style.transform = "translateX(-" + (now - 2) + "00vw)";
now--;
}
});
main.css
body {
margin: 0;
background-color: var(--bodybackground-color);
font-family: "Gowun Dodum", sans-serif;
}
/* a태그 밑줄 없애기 */
a {text-decoration-line: none; color: rgb(187, 26, 5);}
/* 스크롤 진행바 */
.progress {
background-color: red;
padding: 1px;
width: 0%;
position: fixed;
z-index: 10;
transition: all 1s;
margin-top: -85px;
}
/* 상단바*/
.menu {
width: 100%;
display: flex; /* 가로로 정렬 */
justify-content: space-between; /* 박스 간 간격 */
align-items: center; /* 가운데 정렬 */
background-color: antiquewhite;
height: 95px;
margin-top: -86px;
position: fixed; /* 스크롤 고정 */
}
/* 서브메뉴 - 그룹 */
.list-group {
font-size: 18px;
list-style:none; /* 목록 점 없애기 */
display: flex; /* 가로로 정렬 */
margin: 0 auto; /* 가운데 정렬*/
padding-left: 0;
}
/* 서브메뉴 - 개인 */
.list-item {
padding: 8px 70px; /* 메뉴 간 간격 */
cursor: pointer;
}
/* 메뉴 제목 */
.title {
margin-top: 85px;
padding-top: 70px;
padding-bottom: 10px;
width: auto;
font-size: 20px;
text-align: center;
display: grid;
}
/* 섹션 당 한 화면 보여주기 */
.section {
height: 100vw;
}
/* 본문 - 작은 내용 */
#a {
font-size: 20px;
margin-top: -10px;
text-align: center;
}
/* 두 번째 본문 - 제목 */
#untitle {
margin-top: 40px;
}
/* 메뉴 간격 조정 */
#about {
padding-top: 2px;
}
#skills {
padding-top: 2px;
}
#projects {
padding-top: 2px;
}
#contact {
padding-top: 2px;
}
#me {color: rgb(240, 35, 25);}
/* 프로필 사진 */
.title img {
margin: 0 auto;
}
/* 벨로그, 깃허브 아이콘 */
.iconabout {
text-align: center;
margin-top: 60px;
}
/* 캐러셀 슬라이드 */
.slide-container {
width: 300vw;
transition: all 1s;
}
.slide-box {
width: 100vw;
float: left;
}
.slide-box img {
width: 100%;
}
/* 숫자 버튼 */
.btn-slide {
text-align: center;
padding: 40px;
}
.slide-1, .slide-2, .slide-3 {
font-family: "Nanum Myeongjo", serif;
text-align: center;
font-size: 15px;
margin: 0px 5px 0px 10px;
width: 27px;
height: 25px;
border: none;
background-color: rgb(228, 234, 239);
box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);
}
.slide-1:hover, .slide-2:hover, .slide-3:hover {
background-color: aliceblue;
}
/* 다음, 이전 버튼 */
.btn-next {
font-family: "Nanum Myeongjo", serif;
text-align: center;
}
.next, .before {
font-family: "Nanum Myeongjo", serif;
text-align: center;
font-size: 15px;
margin: 0px 5px 0px 10px;
width: 50px;
height: 27px;
border: none;
background-color: rgb(223, 238, 251);
box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);
}
.next:hover, .before:hover {
background-color: aliceblue;
}
잘한 점
- 지금까지 배운 기능들을 잘 녹여서 구현한 것!
- 상단바, 스크롤 진행바, 메뉴 클릭 시 자동 이동, 캐러셀 슬라이드 등 내가 배우고 구현할 수 있는 기능들로 만들어보니 재밌었다!
- css를 내 손으로 구현한 것
- 사실 js로 기능을 구현하는 것보다는 css로 디자인하는게 제일 힘들고 시간이 많이 걸렸다. 더 예쁘게 만드려면 css 사이트나 라이브러리에서 코드를 긁어오는게 맞는데 궁극적으로는 css도 실력을 키워야 하니까... 포기하지 않고 끝까지 내 손으로 구현한게 뿌듯하다.
아쉬운 점
- 원하는 디자인을 다 구현하지 못했다.
css는...아직도 어려운 것 투성이다. 좀 익숙해졌다 싶다가도 낯설고 알다가도 모르겠다.
꾸준히 정진해야겠다.
깃허브
https://github.com/kwonboryong/Toy_Projects/tree/main/Scroll_mySelf
참고
https://vannilla-js-basic-project-10-scroll.netlify.app/
https://parkjh7764.tistory.com/46
https://hianna.tistory.com/474
https://codingbroker.tistory.com/56
https://romanticdeveloper.tistory.com/58