오늘은 사전스터디 1주차 과제였던 자기소개 페이지 만들기에 대한 게시글을 써보려 한다. 사실 1~2년동안 먼저 프론트엔드 개발자가 되기 위해서 혼자 나름대로의 공부를 해왔다고 생각했는데, 이번 과제를 통해서 아직 내가 한~참 부족한 모시깽이라는 것을 느꼈다.. 그래도 기존에 내가 사용했었던 코드나 드림코딩 포트폴리오를 만들때 배웠던 코드들은 유용하게 활용할 수 있었다.
대략적인 레이아웃은 이렇게 설정하였다. 사실 여러 개의 페이지를 연결해서 만들까도 생각했지만, 아직은 멀티 페이지 애플리케이션으로 구현을 할 수 밖에 없기 때문에, 속도 저하 등의 효율성이 떨어진다고 생각해서 한 페이지에서 navbar를 통한 버튼으로 이동할 수 있게 레이아웃을 설정하였다. 다만 버튼을 통해 이동한 레이아웃은 한 페이지라는 느낌이 들도록 height 속성을 브라우저에 꽉차게 설정하였다.
1. Header
<header>
<div class="page_logo">
<i class="fas fa-male"></i>
<a href="#">Kyeom's Page</a>
</div>
<nav id="navbar">
<ul class="navbar_menu">
<li class="navbar_menu_item" data-link="#me">About Me</li>
<li class="navbar_menu_item" data-link="#skills">Skills</li>
<li class="navbar_menu_item" data-link="#hobby">Hobby</li>
<li class="navbar_menu_item" data-link="#gallery">Gallery</li>
<li class="navbar_menu_item" data-link="#contact">Contact</li>
</ul>
</nav>
</header>
헤더의 html 태그다.
/* Header */
header {
height: 1300px;
position: relative;
}
header:after {
background-image: url(imgs/header_bg.jpg);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
background-attachment: fixed;
top: 0;
left: 0;
position: absolute;
opacity: 0.5 !important;
z-index: -1;
content: "";
width: 100%;
height: 100%;
}
.page_logo {
display: flex;
font-weight: var(--weight-semi-bold);
justify-content: center;
font-size: 70px;
padding: 300px;
padding-bottom: 200px;
}
.page_logo i {
margin: 20px;
}
.page_logo:hover {
transition: 0.7s;
color: var(--color-white);
}
.navbar_menu {
display: flex;
justify-content: center;
font-size: var(--font-medium);
}
.navbar_menu_item {
padding: 8px 12px;
margin: 0 4px;
cursor: pointer;
border: 1px solid transparent;
border-radius: var(--size-border-radius);
}
.navbar_menu_item:hover {
transition: 0.7s;
border: 1px solid var(--color-white);
background-color: var(--color-black);
color: var(--color-white);
border-radius: var(--size-border-radius);
}
헤더의 CSS 속성이다.
헤더에서 가장 중점적으로 구현하고자 한 기능은 스크롤 시 배경화면 고정과, navbar 버튼 클릭시에 해당 레이아웃으로 이동하는 기능이었다.
스크롤 시 배경화면 고정은, 현재 배달의 민족 홈페이지나 스타벅스 홈페이지에서도 볼 수 있는 기능이라, '와 저건 어떤 엄청난 코드를 사용해서 구현한 복잡한 기능일까?' 하는 두려움과 설렘이 있었다. 그러나, 이를 구현하기에는 생각보다 너무나도 간단한 코드 한줄만이 필요했다.
background-attachment: fixed;
background-attachment 속성을 fixed로 설정하면, 배경을 뷰포트에 대해 고정하기 때문에 스크롤을 해도 배경은 함께 스크롤되지 않고 고정된 상태로 남아있게 된다. 다만 여기서 새로운 문제가 발생하게 되는데, 기존 <header>
태그에 background 속성과 opacity 속성을 적용하면, header 태그 내부에 존재하는 page_logo 와 navbar 요소까지 함께 투명도가 적용되는 것이었다.
이를 해결하기 위해서는, CSS의 가상요소인 ::after
를 통해 <header>
의 자식 의사 요소를 추가하면 된다. 기존 <header>
태그의 자식 의사 요소에 background 요소와 opacity를 설정한 후, z-index
를 통해 해당 요소의 z축을 뒤로 보내면, 배경화면에만 opacity가 적용됨을 확인할 수 있다.
navbar의 버튼을 클릭해서 해당 레이아웃으로 이동하는 기능은 Javascript가 필요했다. 우선 dataset을 활용하기 위해 navbar 메뉴의 HTML 요소에서 dataset attribute를 customize했다.
<nav id="navbar">
<ul class="navbar_menu">
<li class="navbar_menu_item" data-link="#me">About Me</li>
<li class="navbar_menu_item" data-link="#skills">Skills</li>
<li class="navbar_menu_item" data-link="#hobby">Hobby</li>
<li class="navbar_menu_item" data-link="#gallery">Gallery</li>
<li class="navbar_menu_item" data-link="#contact">Contact</li>
</ul>
</nav>
dataset attribute를 customize 하기 위해서는 data-(변수명)
식으로 작성하고 value 값을 주면 된다. 여기서는 dataset에 link라는 변수를 주고 value 값으로 해당 레이아웃들의 id 값을 주었다.
// function about scroll smoothly
function scrollIntoView(e) {
const scrollTo = document.querySelector(e);
scrollTo.scrollIntoView({
behavior: "smooth",
});
}
// 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;
if (link == null) {
return;
}
navbarMenu.classList.remove("open");
scrollIntoView(link);
});
navbar의 js 함수들이다. 우선 버튼을 클릭하면 스크롤되어 해당 레이아웃으로 이동하기 때문에, scrollIntoView 라는 함수를 정의해 해당 element로 Window.scrollTo()
되게 하였다. 여기서 behavior: "smooth" 값을 적용해 조금 더 부드러운 스크롤이 가능하도록 구현하였다.
그리고 navbar_menu
의 class 값을 불러와 addEventListener로 click 이벤트를 등록하였다. 여기서 dataset의 link 변수를 불러오기 위해 target이라는 변수에 event.target
값을, link라는 변수에 target.dataset.link
값을 저장하였다. link 값이 null인 경우에는 return 명령문을, link 값이 유효할 때는 앞서 선언한 scrollIntoView 함수를 통해 link 값에 할당된 레이아웃으로 이동하도록 이벤트 핸들러를 등록하였다.
2. About Me
레이아웃의 시작인 About Me 레이아웃이다. 아무래도 HTML & CSS를 중점적으로 활용하여 만드는 자기소개 페이지이다 보니까 CSS animation 속성들을 많이 활용하고 싶었다. 그래서 조금은 뜬금없지만 내 사진이 빙글빙글 돌게 하는 건 어떨까 싶어 적용해 보았다.
#me img {
display: block;
margin: 30px auto;
width: 400px;
height: 400px;
border-radius: 100% 100% 100% 100%;
}
#me img:hover {
animation: rotation 2s infinite ease;
transition: 3s;
}
@keyframes rotation {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(360deg);
}
}
우선 이미지를 둥글게 하기 위해 width와 height 값을 같게 설정한 후, border-radius 값을 50%로 주었다. 그리고 아무래도 내가 계속 빙글빙글 돌아가는 건 좀 어지러울 거 같아서, 마우스를 올렸을 때, 즉 :hover
상태일 때만 animation을 주기로 했다. animation은 rotation 2s에 무한대로 돌 수 있도록 infinite를 주었다.
그리고 3D로 도는 듯한 느낌을 주고 싶어서, @keyframes
속성을 사용해 Y축 0deg에서 부터 360deg까지 돌도록 설정하였다.
아래의 개인 정보들은 hover시 scale(1.2)와 blue color를 주었다.
#me p:hover {
transform: scale(1.2);
color: var(--color-blue);
transition: 0.5s;
}
(2편에서 계속)
안녕하세요 ! 배운지 한달정도 되어가는 비전공자 입니다
css 와 html 의 기능으로 우선 구성해서 사용하셧던 JSP 기능을 넣으려고 하는데요
메인 페이지는 구성을 했지만 그 다음페이지를 구성을 하려니 조금 헷갈려서요..ㅠ
페이지별 크기 설정은 어떤식으로 하셧을까요?