새소식

인기 검색어

개인공부/HTML5&CSS3

PROJECT

  • -

main.js

"use strict"; // Make navbar transparent when it is on the top const navbar = document.querySelector("#navbar"); const navbarHeight = navbar.getBoundingClientRect().height;//현재 nav 엘레먼트의 높이 가져오기 document.addEventListener("scroll", () => {// 사용자가 페이지를 위아래로 스크롤 할 때 if (window.scrollY > navbarHeight) {//현재 스크롤 픽셀을 반환 현재 스크롤 위치가 엘리먼트의 높이를 넘어가면 navbar.classList.add("navbar--dark");//클래스를 추가 } else { navbar.classList.remove("navbar--dark");//클래스를 제거 } }); // Handle scrolling when tapping on the navbar menu const navbarMenu = document.querySelector(".navbar__menu"); navbarMenu.addEventListener("click", (event) => {//사용자가 동일한 요소 위에서 마우스 버튼을 눌렀다 땔 때 const target = event.target;//현재 이벤트를 발생시킨 대상을 얻기 const link = target.dataset.link;//dataset을 통하여 data-link속성값 가져오기 scrollIntoView(link);//element를 기준으로 스크롤을 이동 }); // Handle click on "contact me" button on home const homeContactBtn = document.querySelector(".home__contact"); homeContactBtn.addEventListener("click", () => { scrollIntoView("#contact"); }); // Make home slowly fade to transparent as the window scrolls down const home = document.querySelector(".home__container"); const homeHeight = home.getBoundingClientRect().height; document.addEventListener("scroll", () => { home.style.opacity = 1 - window.scrollY / homeHeight; //home__container영역의 투명도 조절 }); // Change Skill Value Animation const skills = document.querySelector("#skills"); const skill__value = document.querySelectorAll(".skill__value"); const skillsTop = skills.getBoundingClientRect().top;//요소의 시작 좌표 const skillsBottom = skills.getBoundingClientRect().bottom;//끝 좌표 document.addEventListener("scroll", () => { console.log(window.scrollY); if (window.scrollY < skillsTop - 150 || window.scrollY > skillsBottom - 50) { for (var i = 0; i < skill__value.length; i++) { skill__value[i].classList.add("skill_defaultValue"); //스킬 그래프를 다시 제자리로 } } else { for (i = 0; i < skill__value.length; i++) { skill__value[i].classList.remove("skill_defaultValue"); } } //home__container영역의 투명도 조절 }); // Show "arrow up" button when scrolling down const arrowUp = document.querySelector("#arrow-up-btn"); document.addEventListener("scroll", () => { if (window.scrollY > homeHeight / 2) {//스크롤 자표값이 home section height의 절반을 넘어가면 arrowUp.classList.add("visible"); } else { arrowUp.classList.remove("visible"); } }); // Handle click on the "arrow up" button arrowUp.addEventListener("click", () => { scrollIntoView("#home"); }); // Projects const workBtnContainer = document.querySelector(".work__categories");//카테고리 버튼 const projectContainer = document.querySelector(".work__projects");//이미지 부모 div 태그 const projects = document.querySelectorAll(".project");//이미지 a 태그 workBtnContainer.addEventListener("click", (e) => { const filter = e.target.dataset.filter || e.target.parentNode.dataset.filter; //숫자를 표시하는 span태그를 누를시 데이터셋 속성이 존재하지 않기에 부모 요소(카테고리 버튼)의 데이터셋 속성을 가져옴 if (filter == null) { // data 없으면 아무 일도 안일어나도록 //카테고리 버튼과 카운트 span태그를 제외한 공간을 누를시 예외처리를 하기 위해 조건문 삽입 return; } //이벤트를 발생시킨 요소를 나타내는 target 프로퍼티로 해당 요소의 데이토 속성값을 가져온다 // 버튼을 누르면 해당하는 리스트 출력 const active = document.querySelector(".category__btn.selected"); active.classList.remove("selected");//선택된 버튼 css 제거 const target = e.target.nodeName === "BUTTON" ? e.target : e.target.parentNode; //현재 클릭 이벤트 발생시킨 요소가 버튼이아닌 카운트 숫자를 표시하는 span태그 누를시 상위 요소인 버튼 태그를 target에 지정 target.classList.add("selected");//선택된 버튼 css 추가 projectContainer.classList.add("anim-out"); //anim-out => 40%투명도와 y축으로 40px이동 setTimeout(() => { projects.forEach((project) => { if (filter === "*" || filter === project.dataset.type) { // 전체 or data-filter(tab btn) 값이 project data 값과 같으면, project.classList.remove("invisible"); } else { project.classList.add("invisible");//display none } }); projectContainer.classList.remove("anim-out"); }, 300);//0.3초 후 실행 }) ; function scrollIntoView(selector) { const scrollTo = document.querySelector(selector); scrollTo.scrollIntoView({behavior: "smooth"});//smooth => 스크롤 이동 방식 }

port.html

더보기
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My portfolio</title> <!-- <link rel="icon" type="image/png"--> <!-- href="../../Downloads/portfolio-website-main/portfolio-website-main/imgs/seedling-solid.svg"/>--> <!-- <link--> <!-- rel="stylesheet"--> <!-- href="w"--> <!-- integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm"--> <!-- crossorigin="anonymous"--> <!-- />--> <!-- <script src="https://kit.fontawesome.com/36e2eaaec8.js" crossorigin="anonymous"></script>--> <link rel="preconnect" href="https://fonts.googleapis.com"/> <!-- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>--> <link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,600;0,700;1,400&display=swap" rel="stylesheet" /> <link rel="stylesheet" href="css/port.css"/> </head> <body> <!-- Navbar --> <nav id="navbar"> <div class="navbar__logo"> <a href="#">MKC</a> </div> <ul class="navbar__menu"> <li class="navbar__menu__item" data-link="#home">Home</li> <li class="navbar__menu__item" data-link="#about">About</li> <li class="navbar__menu__item" data-link="#skills">Skills</li> <li class="navbar__menu__item" data-link="#work">My work</li> <li class="navbar__menu__item" data-link="#contact">Contact</li> </ul> <!-- Toggle button--> <!-- <button class="navbar__toggle-btn"><i class="fas fa-bars"></i></button>--> </nav> <!-- Home --> <section id="home"> <div class="home__container"> <!-- <img src="img/me.jpg" alt="profile" class="home__avatar"/>--> <h1 class="home__title typing">Hello, <br/>I'm </h1> <h2 class="home__description typing"> MaKiChang </h2> <button class="home__contact">Contact Me</button> </div> </section> <!-- About --> <section id="about" class="section section__container"> <h1>About me</h1> <p>Tech Stack</p> <div> <DIV class="about__majors"> <div class="major"> <div class="major__icon"> <i class="fa-brands fa-html5"></i> </div> <div class="major__title">HTML</div> </div> <div class="major"> <div class="major__icon"> <i class="fa-brands fa-css3-alt"></i> </div> <div class="major__title">CSS</div> </div> <div class="major"> <div class="major__icon"> <i class="fa-brands fa-js"></i> </div> <div class="major__title">JS</div> </div> </DIV> <DIV class="about__majors"> <div class="major"> <div class="major__icon"> <i class="fab fa-react"></i> </div> <div class="major__title">React</div> </div> <div class="major"> <div class="major__icon"> <i class="fab fa-java"></i> </div> <div class="major__title">Java</div> </div> <div class="major"> <div class="major__icon"> <i class="fa-solid fa-database"></i> </div> <div class="major__title">DB</div> </div> </DIV> </div> </section> <!-- Skills --> <section class="section" id="skills"> <div class="section__container"> <h1>Skills</h1> <h2>Skills & Attributes</h2> <p></p> <div class="skillset"> <div class="skillset__left"> <h3 class="skillset__title">Skills</h3> <div class="skill"> <div class="skill_description"> <span>HTML</span> <span>80%</span> </div> <div class="skill__bar"> <div class="skill__value skill_defaultValue" style="width: 80%"></div> </div> </div> <div class="skill"> <div class="skill_description"> <span>CSS</span> <span>70%</span> </div> <div class="skill__bar"> <div class="skill__value skill_defaultValue" style="width: 70%"></div> </div> </div> <div class="skill"> <div class="skill_description"> <span>JS</span> <span>70%</span> </div> <div class="skill__bar"> <div class="skill__value skill_defaultValue" style="width: 70%"></div> </div> </div> <div class="skill"> <div class="skill_description"> <span>React</span> <span>0%</span> </div> <div class="skill__bar"> <div class="skill__value" style="width: 0%"></div> </div> </div> <div class="skill"> <div class="skill_description"> <span>DB</span> <span>70%</span> </div> <div class="skill__bar"> <div class="skill__value" style="width: 70%"></div> </div> </div> <div class="skill"> <div class="skill_description"> <span>JAVA</span> <span>100%</span> </div> <div class="skill__bar"> <div class="skill__value skill_defaultValue" style="width: 100%"></div> </div> </div> </div> <div class="skillset__right"> <div class="tools"> <h3 class="skillset__title">Tools</h3> <ul class="tools_list"> <li><span>Visual Studio</span></li> <li><span>Visual Studio Code</span></li> <li><span>intellij</span></li> <li><span>MySQL</span></li> </ul> </div> <div class="etc"> <h3 class="skillset__title">Etc</h3> <ul class="etx__list"> <li><span>Git</span></li> </ul> </div> </div> </div> </div> </section> <!-- Work --> <section id="work" class="section" style="height: 948px;"> <div class="section__container"> <h1>My work</h1> <h3>Projects</h3> <div class="work__categories"> <button class="category__btn selected" data-filter="*"> ALL<span class="category__count">8</span> </button> <button class="category__btn" data-filter="front-end"> Front-end<span class="category__count">3</span> </button> <button class="category__btn" data-filter="back-end"> Back-end<span class="category__count">3</span> </button> <button class="category__btn" data-filter="mobile"> Mobile<span class="category__count">2</span> </button> </div> <div class="work__projects"> <a href="#" class="project" target="blank" data-type="front-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbRr3a%2FbtrMKs9zlgU%2FmZcVp9HF3rKSHYCLfLJZd1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>HTML and CSS</span> </div> </a> <a href="#" class="project" target="blank" data-type="front-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbRr3a%2FbtrMKs9zlgU%2FmZcVp9HF3rKSHYCLfLJZd1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>HTML and CSS</span> </div> </a> <a href="#" class="project" target="blank" data-type="front-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbRr3a%2FbtrMKs9zlgU%2FmZcVp9HF3rKSHYCLfLJZd1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>HTML and CSS</span> </div> </a> <a href="#" class="project" target="blank" data-type="back-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuB4aw%2FbtrMFFiOtAc%2FS69MzO1kKixsXZdaX7aHW1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>Pet Sitting</h3> <span>JSP</span> </div> </a> <a href="#" class="project" target="blank" data-type="back-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJe33b%2FbtrMIrxm6oh%2FcbLoSdLzsCQ2mXl0wrBVK1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>JSP</span> </div> </a> <a href="#" class="project" target="blank" data-type="back-end"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJe33b%2FbtrMIrxm6oh%2FcbLoSdLzsCQ2mXl0wrBVK1%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>JSP</span> </div> </a> <a href="#" class="project" target="blank" data-type="mobile"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs7afu%2FbtrMIwSTupi%2F7KhTRk6jXq0rlxPz6dAlSk%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>Mobile</span> </div> </a> <a href="#" class="project" target="blank" data-type="mobile"> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs7afu%2FbtrMIwSTupi%2F7KhTRk6jXq0rlxPz6dAlSk%2Fimg.png" alt="" class="project__img"/> <div class="project__description"> <h3>My Portfolio</h3> <span>Mobile</span> </div> </a> </div> </div> </section> <!-- Contact --> <section id="contact" class="section"> <h1 class="contact__title">Let's talk</h1> <h2 class="contact__email">smreo3839@naver.com</h2> <div class="contact__links"> <a href="https://github.com/smreo3839" target="blank"> <i class="fab fa-github"></i> </a> <a href="#" target="blank"> <i class="fab fa-linkedin"></i> </a> </div> <p class="contact__rights">2022 - mkc</p> </section> <!-- arrow-up button --> <button id="arrow-up-btn"> <i class="fas fa-solid fa-arrow-up"></i> </button> <script src="js/main.js" defer></script> <script src="https://kit.fontawesome.com/36e2eaaec8.js" crossorigin="anonymous"></script> </body> </html>

port.css

더보기
/* Global */ :root { /* Color */ --color-white: #ffffff; --color-light-white: #eeeeee; --color-dark-white: #bdbdbd; --color-my-blue: #005666; --color-my-dark-blue: #3e5bc4; --color-dark-grey: #4d4d4d; --color-grey: #616161; --color-light-grey: #7c7979; --color-blue: #008080; --color-yellow: #fff7d1; --color-orange: #feb546; --color-black: #000000; /* Font size */ --font-large: 48px; --font-medium: 28px; --font-regular: 18px; --font-small: 16px; --font-micro: 14px; /* Font weight */ --weight-bold: 700; --weight-semi-bold: 600; --weight-regular: 400; /* Size */ --size-border-radius: 4px; /* Annimation */ --animation-duration: 300ms; --animation-duration-slow: 3000ms; } * { box-sizing: border-box; } body { font-family: "Open Sans", sans-serif; margin: 0; cursor: default; /*마우스 커서 속성*/ } a { text-decoration: none; color: var(--color-white); } ul { padding-left: 0; } li { list-style: none; } button { background-color: transparent; cursor: pointer; border: none; outline: none; padding: 0; } h1 { font-size: var(--font-large); font-weight: var(--weight-bold); color: var(--color-black); margin: 16px 0px; } h2 { font-size: var(--font-medium); font-weight: var(--weight-semi-bold); color: var(--color-black); margin: 8px 0; } h3 { font-size: var(--font-regular); font-weight: var(--weight-regular); color: var(--color-black); margin: 8px 0; } p { font-size: var(--font-regular); font-weight: var(--weight-regular); color: var(--color-black); margin: 4px 0; } /* Navbar */ #navbar { position: fixed; width: 100%; display: flex; justify-content: space-between; align-items: center; /*안의 요소들 중앙 정렬*/ padding: 16px; background-color: transparent; transition: all var(--animation-duration) ease-in-out; z-index: 1; } #navbar.navbar--dark { background-color: var(--color-my-blue); padding: 8px; } .navbar__logo { font-size: var(--font-medium); font-weight: var(--weight-semi-bold); color: white; } .navbar__menu { display: flex; } .navbar__menu__item { padding: 8px 12px; margin: 0 4px; cursor: pointer; color: var(--color-white); transition: all 0.2s ease-in-out; border: 1px solid transparent; border-radius: var(--size-border-radius); } .navbar__menu__item:hover { border: 1px solid white; background-color: var(--color-my-dark-blue); border-radius: var(--size-border-radius); } /* Home */ #home { background: url("../img/bg.png") center/cover no-repeat; padding: 50px; padding-top: 120px; text-align: center; } .home__avatar { /*썸네일*/ width: 250px; height: 250px; border-radius: 50%; border: 2px solid var(--color-light-white); } .home__title, .home__description { color: var(--color-white); } .home__contact { /*contact Me 버튼*/ color: var(--color-white); font-size: var(--font-regular); font-weight: var(--weight-bold); margin: 24px; padding: 8px 12px; border: 2px solid var(--color-white); border-radius: var(--size-border-radius); } .home__contact:hover { background-color: var(--color-orange); } /* Section common */ .section { padding: 100px; text-align: center; margin: auto; } .section__container { max-width: 1200px; margin: auto; } /* About */ .about__majors { display: flex; justify-content: space-between; margin: 80px 0; } .major__icon { width: 170px; height: 170px; font-size: 70px; line-height: 170px; margin: auto; color: var(--color-blue); border: 1px solid var(--color-blue); border-radius: 50%; margin-bottom: 16px; } .major__icon i { transition: all var(--animation-duration) ease; } .major__icon:hover i { color: var(--color-my-blue); transform: rotate(-30deg) scale(1.1); } /* Skill */ #skills { padding-bottom: 250px; background-color: var(--color-yellow); } .skillset { display: flex; background-color: var(--color-light-grey); color: var(--color-light-white); margin: auto; } .skillset__title { color: var(--color-white); } .skillset__left { flex-basis: 60%; background-color: var(--color-dark-grey); padding: 20px 40px; } .skill { margin-bottom: 32px; } .skill__description { display: flex; justify-content: space-between; } .skill__bar { width: 100%; height: 7px; background-color: var(--color-grey); } .skill__value { transition: all var(--animation-duration-slow) ease; height: 7px; background-color: var(--color-orange); } .skill_defaultValue { width: 10% !important; } .skillset__right { flex-basis: 40%; } #css { width: 70%; } .tools { background-color: var(--color-grey); } .tools, .etc { padding: 20px; height: 50%; } /* Work */ .work__categories { margin: 40px; } .category__btn { border: 1px solid var(--color-dark-white); border-radius: var(--size-border-radius); font-size: var(--font-regular); padding: 8px 48px; position: relative; } .category__btn.selected, .category__btn:hover { background-color: var(--color-my-blue); color: var(--color-white); } .category__btn.selected .category__count, .category__btn:hover .category__count {/*선택된 버튼 혹은 마우스가 올려진 버튼*/ opacity: 1; top: 5px; } .category__count { background-color: var(--color-orange); color: var(--color-white); border-radius: 50%; width: 24px; height: 24px; line-height: 24px; display: inline-block; position: absolute; top: -10px; opacity: 0; transition: all var(--animation-duration) ease-in; margin-left: 5px; } .work__projects { display: flex; flex-wrap: wrap; justify-content: center; width: 100%; opacity: 1; transition: all var(--animation-duration) ease-out; } .work__projects.anim-out { opacity: 0.6; transform: scale(0.9) translateY(100px); } .project { position: relative; display: flex; justify-content: center; align-items: center; width: 280px; height: 250px; margin: 2px; border-color: var(--color-white); } .project.invisible { display: none; } .project__img { max-width: 100%; /*max-height: 100%;*/ height: 250px; border: 1px solid lightgray; } .project__description { position: absolute; background-color: black; display: flex; flex-direction: column; justify-content: center; width: 100%; height: 100%; top: 10px; left: 0; opacity: 0; /*transform: translateY(10px);*/ transition: all var(--animation-duration) ease-in; } .project:hover .project__description { opacity: 0.8; /*transform: translateY(0px);*/ top: 0px; transition: all var(--animation-duration) ease-in; } .project__description h3 { color: var(--color-orange); } .projects { display: flex; } /* Contact */ #contact { background-color: var(--color-my-blue); } .contact__title, .contact__email, .contact__rights { color: var(--color-white); } .contact__title { margin: 32px 0; } .contact__links { font-size: var(--font-large); margin: 24px 0; transition: all var(--animation-duration) ease-in; } .contact__links i:hover { transform: scale(1.1); color: var(--color-yellow); } /* arrow-up button */ #arrow-up-btn { position: fixed; bottom: 50px; right: 30px; width: 70px; height: 70px; background-color: var(--color-my-dark-blue); border: 3px solid var(--color-white); color: var(--color-white); border-radius: 50%; font-size: var(--font-medium); transition: all 0.3s ease-in; pointer-events: none; opacity: 0; } #arrow-up-btn.visible { opacity: 1; pointer-events: auto; }

 

프로젝트 진행 중 참고 내용

https://www.daleseo.com/css-width/

 

[CSS] width 속성과 너비 결정 매커니즘

Engineering Blog by Dale Seo

www.daleseo.com

https://studiomeal.com/archives/197   

 

📌 요소들을 수평 나열하기위해 flex 속성을 사용하였습니다.

 

이번에야말로 CSS Flex를 익혀보자

이 튜토리얼은 “차세대 CSS 레이아웃” 시리즈의 첫번째 포스트입니다. 이번에야말로 CSS Flex를 익혀보자 이번에야말로 CSS Grid를 익혀보자 벌써부터 스크롤의 압박이 느껴지고,‘좀 편안하게 누

studiomeal.com

https://developer.mozilla.org/ko/docs/Web/API/Element/getBoundingClientRect

📌 스크롤 이벤트 발생시 브라우저의 y축 좌표값과 특정 요소의 좌표값을 비교하기 위해 getBoundingClientRect()를 사용하였습니다

 

Element.getBoundingClientRect() - Web API | MDN

Element.getBoundingClientRect() 메서드는 엘리먼트의 크기와 뷰포트에 상대적인 위치 정보를 제공하는 DOMRect 객체를 반환합니다.

developer.mozilla.org

https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-HTML-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%85%8Bdata-%EC%86%8D%EC%84%B1

📌 카테고리 버튼에 값을 지정하여 각각의 다른 이벤트를 발생시키기위해 데이터셋 속성을 사용하였습니다

 

[JS] 📚 HTML 데이터셋(data-*) 속성

데이터 속성 HTML5부터는 데이터 속성이라는 개념이 생겼습니다. 데이터 속성은 HTML 요소의 'data-' 로 시작하는 속성입니다. 이러한 데이터 속성은 특정한 데이터를 DOM 요소에 저장해두기 위함이

inpa.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.