Search

21-1 KUCC 새싹 코딩대회

나만의 포트폴리오 퍼블리싱하기

제작 완료된 포트폴리오 사이트 : https://taewoong1378.github.io/my_portfolio.github.io/ 포트폴리오의 세부 코드는 여기 링크에서 확인하실 수 있습니다!

본인 소개

이름 : 강태웅 (00년생 / 22살 / 통계학과 19학번)
매일 아침 5시 ~ 5시 반에 일어나는 얼리버드!
올 1월부터 공부를 시작해 현재 풀스택 공부 중입니다!
산업기능요원으로 IT 회사에 입사하기 위해 열심히 공부 중
사람 만나는거 엄청 좋아합니다 ㅎㅎ
취미 : 운동, 게임, 피아노 등등

목차

1.
해당 테마를 선택한 이유
2.
구체적으로 어떤 웹페이지를 만들 것인가
3.
웹 페이지에 어떤 요소들이 들어가야 하는가
4.
본인이 구현하고자 하는 UI 스케치
5.
개발 진행 플로우 정리
6.
코드 및 로직 소개
7.
트러블슈팅중 기억에 남는 것들 소개(삽질했던 것들 혹은 오류를 해결했던 과정을 소개)
8.
개발하면서 추가적으로 구현해보고 싶었던 기능
9.
후기

1. 해당 테마를 선택한 이유

해커톤 대회를 준비하고 있었는데... 갑작스러운 일정 연기 (코로나 너무 싫어요... )
해커톤 대회를 나가게 되면서 새싹 코딩 대회를 포기했으나 코로나로 갑작스럽게 해커톤 대회가 연기되면서 7월 8일 (목)에 새싹 코딩 대회를 나가야겠다고 생각했습니다. 어차피 이후 회사를 쓰려면 포트폴리오를 만들어야하기도 했고, 최근에 Node.js와 PHP 등 백엔드 위주로 공부하면서 프론트엔드에 대한 지식(휘발성 지식)이 너무 많이 사라졌기 때문에 기억을 상기시키고자 포트폴리오를 테마로 새싹 코딩 대회에 급하게 참여하게 됐습니다. 아침 일찍부터 열심히 만들기 시작했지만 하루만에 완성할만한 양은 아니라 많이 걱정했는데, 다행히 마로 형이 다음날까지 제출해도 괜찮다고 하여 마음 편히 만들기 시작했습니다 (마로 형 감사함다 )
+ 그리고 노션을 항상 써보고 싶다는 생각을 하고는 있었는데 한 번도 써보지 못해 이번 새싹 코딩을 계기로 노션도 써보고 싶어 이렇게 참가하게 됐습니다 ㅎㅎ (노션 너무 신기하고 재밌네요!)

2. 구체적으로 어떤 웹페이지를 만들 것인가

기존에 만들던 포트폴리오를 과감하게 버리고 새롭게 만들기!
한 두 달 정도 전에 section, header 등에 대한 개념조차 모호하던 시절, 마구잡이로 만들었던 포트폴리오 테마가 있는데 당시엔 정말 열심히 만들었지만 지금 와서 보니 정말 난잡하고 이상해서 과감하게 버리고 다시 만들기로 했습니다 (정말 끔찍할 정도로 난잡한 UI...)
최대한 깔끔하게 UI를 구성하려고 했고, animation, hover 등 최대한 배웠던 내용들을 꾹꾹 눌러담은 포트폴리오 사이트를 만들기 위해 노력했습니다.

3. 웹 페이지에 어떤 요소들이 들어가야 하는가

배웠던 내용들을 포트폴리오에 녹아내기 위해 노력했습니다
포트폴리오 사이트이기 때문에 아무래도 글 위주로 들어가야 한다고 생각했습니다. 때문에 쓸모없는 정보나 UI는 최대한 줄이고 가급적 차분한 느낌의 UI를 구성하고자 노력했습니다. 저에 대한 설명을 담은 ABOUT 섹션, 저의 기술 스택에 대한 설명을 담은 SKILL 섹션, 저의 프로젝트에 대한 설명을 담은 PROJECT 섹션 그리고 앞으로의 목표(바램)에 대해 담은 WISH 섹션까지 4가지로 콘텐츠 영역을 구성했으며 푸터에 저의 개인정보 및 github, insta, facebook 주소 등을 담아 저와 쉽게 컨텍할 수 있게끔 하였습니다.

4. 본인이 구현하고자 하는 UI 스케치

PPT를 통해 스케치한 메인페이지 UI
PPT를 통해 스케치한 서브페이지 UI

5. 개발 진행 플로우 정리

먼저 메인페이지의 레이아웃은 크게 4개의 Section 영역, 헤더 영역, 푸터 영역으로 나눴고 이후 헤더 - 푸터 - Section 순으로 메인페이지 제작을 진행했습니다.
먼저, 헤더 영역에는 Portfolio 로고와 서브 페이지의 목차들을 넣었고 목차를 클릭하면 서브페이지로 이동할 수 있도록 설정했습니다.
푸터 영역에는 주소, 이메일, 전화번호와 함께 깃헙, 인스타, 페이스북 링크를 폰트어썸을 이용해 삽입했습니다.
메인페이지의 4개 섹션은 각기 다른 색상의 배경을 이용하여 4개 컬럼으로 구성했습니다. 그리고 ABOUT, SKILL 등 각각의 어휘에 어울리는 사진들을 서로 다른 높이로 삽입해 조금 딱딱해볼 수 있는 구성을 탈피하고자 했습니다.
메인페이지를 전부 제작한 이후에는 각각의 섹션들을 구성하기 시작했습니다. 각각의 세션의 경우, 대부분이 글로 채워졌기 때문에 특별한 것은 없지만, 기술 스택(SKILL) 부분의 경우 한 눈에 각각의 기술 스택에 대해 어느정도의 지식을 갖고 있는지 퍼센테이지로 보여주고자 UI를 구성해봤습니다.
+) 아직 글을 다 작성하지 못한 부분은 lorem으로 채워놨고 차차 채워나갈 생각입니다.

6. 코드 및 로직 소개

6-1 헤더 영역

<header> <strong class="logo_box"><img src="./images/portfolio.png" alt="포트폴리오"></strong> <div class="main_page"> 메인페이지로 돌아가기 </div> <nav> <ul> <li data-rol="menu1"><a href="#none">ABOUT</a></li> <li data-rol="menu2"><a href="#none">SKILL</a></li> <li data-rol="menu3"><a href="#none">PROJECT</a></li> <li data-rol="menu4"><a href="#none">WISH</a></li> </ul> </nav> </header>
HTML
header .logo_box { position: absolute; right: 13px; top: 75px; cursor: pointer; transition: 0.5s; } header .logo_box img { width: 150px; } #wrap header { background: url(./images/menu_bg1.png) repeat-y; z-index: 11; width: 180px; height: 100%; position: fixed; right: 0; top: 0; } #wrap header div { color: rgba(255, 255, 255, 0.815); font-size: 10px; position: absolute; left: 42px; top: 110px; cursor: pointer; } #wrap header nav { width: 100%; height: 100%; } #wrap header nav ul { width: 100%; height: 100%; display: flex; justify-content: center; flex-direction: column; } #wrap header nav ul li { margin-left: 50px; position: relative; } #wrap header nav ul li a { transition: 0.5s; } #wrap header nav ul li:after { content: ""; width: 8px; height: 8px; position: absolute; display: block; border-radius: 50%; background-color: #fff; top: 18px; left: -13px; transition: 0.5s; } #wrap header nav ul li a { line-height: 40px; color: #fff; } #wrap header nav ul li:hover a, #wrap header nav ul li.on a { color:#ed3140; } #wrap header nav ul li:hover:after, #wrap header nav ul li.on:after { background:#ed3140; }
CSS
$(function(){ $("#container").addClass("start"); $("nav li").on("click", function(){ $("#container").css("max-width", "100%") const id=$(this).attr("data-rol"); $("nav li").removeClass("on"); $(this).addClass("on"); $(".content").removeClass("prev this next"); $("#" + id).addClass("this").prevAll().addClass("prev"); $("#" + id).nextAll().addClass("next"); }); // 로고 클릭 시 $(".main_page").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); }); $(".logo_box").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); // $("#container").css("max-width", "1200px"); }); });
JavaScript
header 부분에는 직접 PPT를 이용해 제작한 Portfolio logo를 넣었으며 position: absolute; right: 0; top: 0;을 주어 우측에 배치하였습니다. 또, JQUERY를 이용해 네비게이션의 각 목차를 클릭하면 on 클래스가 추가되면서 클릭한 부분의 색상이 남아있도록 설정했습니다. 더 나아가, 우측 상당의 로고를 클릭하면 JQUERY를 이용해 이후 설명할 콘텐츠 영역의 .content에 추가로 생성된 prev this next 클래스와 네비게이션의 li에 추가된 on 클래스를 제거하여 초기 상태로 돌아가도록 하였습니다.

6-2 푸터 영역

<footer> <address> (10472) 경기도 고양시 덕양구 화중로 219 </address> <p> TEL: 010-9367-1378<br> MAIL: ktw2378@naver.com<br> </p> <a href="https://github.com/Taewoong1378" target="_blank"><i class="fab fa-github"></i></a> <a href="https://www.instagram.com/tae_coding/" target="_blank"><i class="fab fa-instagram"></i></a> <a href="https://www.facebook.com/profile.php?id=100008233455158" target="_blank"><i class="fab fa-facebook-square"></i></a> </footer>
HTML
footer { width: 180px; padding: 0 20px 30px 20px; position: fixed; right: 0; bottom: 0; font-size: 11px; color: #7e7e7e; z-index: 12; text-align: center; } footer address { padding-bottom: 15px; } footer .fab { font-size: 20px; padding-top: 10px; margin: 5px; transition: 0.5s; } footer a:hover .fab { transform: rotateY(360deg); } footer a:nth-of-type(1):hover .fab { color: white; } footer a:nth-of-type(2):hover .fab { color: #e4405f; } footer a:nth-of-type(3):hover .fab { color: #3b5999; }
CSS
footer의 경우에는 우측 하단에 주소, 전화번호, 메일을 넣어 배치하였고, github, instagram, facebook에 링크를 부여한 뒤, 각각의 아이콘에 마우스를 오버할 경우 아이콘들이 360도 회전하면서 색상이 변하도록 설정했습니다.

6-3 콘텐츠 영역

콘텐츠 영역은 다 다루기에는 양이 너무 많아 중요하다고 생각한 일부만 다루도록 하겠습니다.

6-3-1 '페이지 이동 효과 부분'

#container .content.this { width: 100%; left: 0 !important; height: 100%; overflow: hidden; overflow-y: auto; } #container .content.prev { width: 100%; left: -100% !important; } #container .content.next { width: 100%; left: 100% !important; }
CSS
$(function(){ $("#container").addClass("start"); $("nav li").on("click", function(){ $("#container").css("max-width", "100%") const id=$(this).attr("data-rol"); $("nav li").removeClass("on"); $(this).addClass("on"); $(".content").removeClass("prev this next"); $("#" + id).addClass("this").prevAll().addClass("prev"); $("#" + id).nextAll().addClass("next"); }); // 로고 클릭 시 $(".main_page").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); }); $(".logo_box").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); // $("#container").css("max-width", "1200px"); }); });
JavaScript
먼저 페이지 이동 효과의 경우에는 현재 영역을 content .this로, 현재 영역 앞에 위치한 영역을 content .prev로, 현재 영역 뒤에 위치한 영역을 content .next로 설정했습니다. 그리고 JQUERY를 이용해 헤더의 네비게이션의 각 목차를 클릭할 경우 this, prev, next 클래스를 추가하거나 제거하는 속성을 부여하여 페이지를 이동할 수 있게끔 하였습니다.

6-3-2 '사용 기술 스택 부분'

<div class="skill-progress"> <h1>USING STACKS</h1> <div class="item"> <p> <span>HTML/CSS</span> <span>80%</span> </p> <div class="progress"> <div class="progress-level" style="width: 80%"></div> </div> </div> <div class="item"> <p> <span>JAVASCRIPT & REACT</span> <span>90%</span> </p> <div class="progress"> <div class="progress-level" style="width: 90%"></div> </div> </div> <div class="item"> <p> <span>NODE.JS & MYSQL</span> <span>90%</span> </p> <div class="progress"> <div class="progress-level" style="width: 90%"></div> </div> </div> <div class="item"> <p> <span>PHP</span> <span>60%</span> </p> <div class="progress"> <div class="progress-level" style="width: 60%"></div> </div> </div> <div class="item"> <p> <span>JAVA</span> <span>70%</span> </p> <div class="progress"> <div class="progress-level" style="width: 70%"></div> </div> </div> </div>
HTML
.skill-progress { width: 500px; padding: 20px; background-color: #333; color: white; border-radius: 7px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.08); position: relative; margin-bottom: 30px; } .skill-progress h1 { text-align: center; margin-bottom: 40px; font-size: 40px; font-weight: normal; } .skill-progress .item { margin-bottom: 20px; } .skill-progress .item p { overflow: hidden; } .item p span:nth-child(1) { float: left; } .item p span:nth-child(2) { float: right; } .progress { border: 1px solid #6cd4c4; padding: 5px; border-radius: 3px; } .content.this .progress-level { height: 10px; background: linear-gradient(to right, crimson, gold); animation: ani 1s; animation-fill-mode: both; } @keyframes ani { 0% { width: 0; } } .skill-progress .item:nth-of-type(1) .progress-level { animation-delay: 0s; } .skill-progress .item:nth-of-type(2) .progress-level { animation-delay: 0.2s; } .skill-progress .item:nth-of-type(3) .progress-level { animation-delay: 0.4s; } .skill-progress .item:nth-of-type(4) .progress-level { animation-delay: 0.6s; } .skill-progress .item:nth-of-type(5) .progress-level { animation-delay: 0.8 }
CSS
사용 가능한 기술스택 부분의 경우, HTML의 div 태그 내부에서 style = width: 90% 와 같이 주고 CSS에서 animation에 width 값을 0을 줌으로써 내부 bar의 width가 1초 동안 0에서 90%까지 올려가도록 설정하였다. 또, content 영역에 들어가지 않은 메인페이지에서 animation이 작동하면 안되기 때문에 .content에 this 클래스가 붙었을 때 animation을 줌으로써 skill content에 들어갔을 때 애니메이션이 동작하게끔 하였습니다.

7. 트러블슈팅 중 기억에 남았던 부분

아무래도 기본적인 HTML/CSS/JS를 이용했기 때문에 특별히 문제가 됐던 트러블 슈팅은 없었습니다.
$(function(){ $("#container").addClass("start"); $("nav li").on("click", function(){ $("#container").css("max-width", "100%") const id=$(this).attr("data-rol"); $("nav li").removeClass("on"); $(this).addClass("on"); $(".content").removeClass("prev this next"); $("#" + id).addClass("this").prevAll().addClass("prev"); $("#" + id).nextAll().addClass("next"); }); // 로고 클릭 시 $(".main_page").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); }); $(".logo_box").on("click", function(){ $("nav li").removeClass("on"); $(".content").removeClass("prev this next"); // $("#container").css("max-width", "1200px"); }); });
JavaScript
다만, 현재는 JQUERY 라이브러리를 이용해서 JS 코드를 구성했습니다. 저는 JQUERY보다는 Vanilla Javascript의 DOM 혹은 React를 이용해 코드를 짜는 것을 훨씬 좋아하는데 JQUERY의 removeClass와 addClass 그리고 $(this) 3가지를 Vanilla Javascript 코드로 바꾸는 법을 정확히 모르겠어 어쩔수 없이 JQUERY 를 이용했습니다 (한참 구글링하고 classList부터 event.currentTarget까지 여러가지를 이용해봤는데 결국 실패했습니다... ) 시간에 쫓겨 JQUERY로 급하게 코드를 짜긴했지만 이후에 좀 더 공부를 하고 조사를 해서 순수 Javascript로 코드를 바꾸고자 합니다.

8. 개발하면서 추가적으로 구현해보고 싶었던 기능

OKKY에서 봤던 다른 개발자 분의 포트폴리오 사이트인데, 사이트에 들어갈 때부터 간지가 철철 흐르는 것 같습니다. 기능은 아니지만 저도 저렇게 멋있는 사진 한장 찍어서 이후에 더 멋있는 메인 페이지를 만들어보고 싶습니다.
또 위 사진은 제가 HTML/CSS를 공부할 때 마우스가 오버되면 위에 관련된 설명이 나오도록 제작했던 UI입니다. 이번에도 마찬가지로 아래 각 기술스택에 마우스를 오버하면 각각에 대한 설명이 나오도록 제작하려고 했는데, 이유는 아직 잘 모르겠지만 실패하였습니다. 이후 추가적으로 정보를 알아보며 보충해볼 계획입니다.

9. 후기

부족하지만 그래도 하루 만에 완성해낸 나 자신에게 무한한 박수를 쳐주고 싶다!
HTML/CSS를 위주로 공부했던 것이 벌써 2~3달 전인지라 기본적인 것들도 잘 생각이 안나서 이번 포트폴리오 사이트를 제작하면서 구글링을 하는 경우가 빈번했습니다. 2~3달 전에 정말 열심히 해서 HTML/CSS는 어느정도 잘하게 됐다고 생각했었는데 왜 제 머리는 시간이 조금만 지나도 새하얘지는 것일까요... 역시 복습을 자주해주는 것은 필수임을 이번 기회에 다시 한 번 뼈저리게 느낄 수 있었습니다. 그래도 회사에 제출할 포트폴리오를 PPT로 만들지 사이트로 만들지에 대해 고민이 많았는데 이번 기회에 포트폴리오를 만들어보면서 걱정이 한시름 덜어진 느낌입니다. 앞으로 있을 해커톤까지 참여하면서 더욱 많이 성장하는 계기를 얻었으면 좋겠습니다. KUCC 짱
세 줄 요약 :
내 기억력은 왜 이럴까. 앞으로 열심히 복습해야겠다
포트폴리오 고민 해결돼서 너무 기분이 좋다
KUCC 짱!