728x90
오늘은 Sidebar를 만들어보겠습니다.
css파일에서의 중요한 부분은 3곳입니다.
1. .sidbar {} : 사이드 바의 기본 스타일 설정
2. .show-sidebar{} : 사이드바 숨김
3. @media screen and (min-width: 676px) {} : 반응형 사이드바
js파일에서 중요한 부분은 2개입니다.
1. sidebar.classList.toggle("className") : sidebar 요소의 클래스 목록에 접근하여 지정된 클래스가 있으면 제거하고, 없으면 추가합니다
2. sidebar.classList.remove("className") : sidebar 요소의 클래스 목록에 접근하여 지정된 클래스를 제거합니다.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sidebar</title>
<!-- font-awesome -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
/>
<!-- styles -->
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<button class="sidebar-toggle">
<i class="fas fa-bars"></i>
</button>
<aside class="sidebar">
<div class="sidebar-header">
<img src="logo.svg" class="logo" alt="" />
<button class="close-btn"><i class="fas fa-times"></i></button>
</div>
<!-- links -->
<ul class="links">
<li>
<a href="index.html">home</a>
</li>
<li>
<a href="about.html">about</a>
</li>
<li>
<a href="projects.html">projects</a>
</li>
<li>
<a href="contact.html">contact</a>
</li>
</ul>
<!-- social media -->
<ul class="social-icons">
<li>
<a href="https://www.twitter.com">
<i class="fab fa-facebook"></i>
</a>
</li>
<li>
<a href="https://www.twitter.com">
<i class="fab fa-twitter"></i>
</a>
</li>
<li>
<a href="https://www.twitter.com">
<i class="fab fa-behance"></i>
</a>
</li>
<li>
<a href="https://www.twitter.com">
<i class="fab fa-linkedin"></i>
</a>
</li>
<li>
<a href="https://www.twitter.com">
<i class="fab fa-sketch"></i>
</a>
</li>
</ul>
</aside>
<!-- javascript -->
<script src="app.js"></script>
</body>
</html>
app.js
// ".sidebar-toggle" 클래스를 가진 요소를 찾아 toggleBtn 변수에 할당합니다.
const toggleBtn = document.querySelector(".sidebar-toggle");
// ".close-btn" 클래스를 가진 요소를 찾아 closeBtn 변수에 할당합니다.
const closeBtn = document.querySelector(".close-btn");
// ".sidebar" 클래스를 가진 요소를 찾아 sidebar 변수에 할당합니다.
const sidebar = document.querySelector(".sidebar");
// 토글 버튼에 클릭 이벤트 리스너를 추가합니다.
toggleBtn.addEventListener("click", function () {
// 클릭 시, sidebar 요소의 클래스 리스트에 "show-sidebar" 클래스를 토글합니다.
// 즉, "show-sidebar" 클래스가 있으면 제거하고, 없으면 추가합니다.
sidebar.classList.toggle("show-sidebar");
});
// 닫기 버튼에 클릭 이벤트 리스너를 추가합니다.
closeBtn.addEventListener("click", function () {
// 클릭 시, sidebar 요소의 클래스 리스트에서 "show-sidebar" 클래스를 제거합니다.
sidebar.classList.remove("show-sidebar");
});
styles.css
/*
===============
Fonts
===============
*/
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");
/*
===============
Variables
===============
*/
:root {
/* dark shades of primary color*/
--clr-primary-1: hsl(205, 86%, 17%);
--clr-primary-2: hsl(205, 77%, 27%);
--clr-primary-3: hsl(205, 72%, 37%);
--clr-primary-4: hsl(205, 63%, 48%);
/* primary/main color */
--clr-primary-5: hsl(205, 78%, 60%);
/* lighter shades of primary color */
--clr-primary-6: hsl(205, 89%, 70%);
--clr-primary-7: hsl(205, 90%, 76%);
--clr-primary-8: hsl(205, 86%, 81%);
--clr-primary-9: hsl(205, 90%, 88%);
--clr-primary-10: hsl(205, 100%, 96%);
/* darkest grey - used for headings */
--clr-grey-1: hsl(209, 61%, 16%);
--clr-grey-2: hsl(211, 39%, 23%);
--clr-grey-3: hsl(209, 34%, 30%);
--clr-grey-4: hsl(209, 28%, 39%);
/* grey used for paragraphs */
--clr-grey-5: hsl(210, 22%, 49%);
--clr-grey-6: hsl(209, 23%, 60%);
--clr-grey-7: hsl(211, 27%, 70%);
--clr-grey-8: hsl(210, 31%, 80%);
--clr-grey-9: hsl(212, 33%, 89%);
--clr-grey-10: hsl(210, 36%, 96%);
--clr-white: #fff;
--clr-red-dark: hsl(360, 67%, 44%);
--clr-red-light: hsl(360, 71%, 66%);
--clr-green-dark: hsl(125, 67%, 44%);
--clr-green-light: hsl(125, 71%, 66%);
--clr-black: #222;
--ff-primary: "Roboto", sans-serif;
--ff-secondary: "Open Sans", sans-serif;
--transition: all 0.3s linear;
--spacing: 0.1rem;
--radius: 0.25rem;
--light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
--dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
--max-width: 1170px;
--fixed-width: 620px;
}
/*
===============
Global Styles
===============
*/
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--ff-secondary);
background: var(--clr-grey-10);
color: var(--clr-grey-1);
line-height: 1.5;
font-size: 0.875rem;
}
ul {
list-style-type: none;
}
a {
text-decoration: none;
}
h1,
h2,
h3,
h4 {
letter-spacing: var(--spacing);
text-transform: capitalize;
line-height: 1.25;
margin-bottom: 0.75rem;
font-family: var(--ff-primary);
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
font-size: 0.875rem;
}
p {
margin-bottom: 1.25rem;
color: var(--clr-grey-5);
}
@media screen and (min-width: 800px) {
h1 {
font-size: 4rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 1.75rem;
}
h4 {
font-size: 1rem;
}
body {
font-size: 1rem;
}
h1,
h2,
h3,
h4 {
line-height: 1;
}
}
/* global classes */
/* section */
.section {
padding: 5rem 0;
}
.section-center {
width: 90vw;
margin: 0 auto;
max-width: 1170px;
}
@media screen and (min-width: 992px) {
.section-center {
width: 95vw;
}
}
main {
min-height: 100vh;
display: grid;
place-items: center;
}
/*
===============
Sidebar
===============
*/
.sidebar-toggle {
position: fixed;
top: 2rem;
right: 3rem;
font-size: 2rem;
background: transparent;
border-color: transparent;
color: var(--clr-primary-5);
transition: var(--transition);
cursor: pointer;
animation: bounce 2s ease-in-out infinite;
}
.sidebar-toggle:hover {
color: var(--clr-primary-7);
}
@keyframes bounce {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
}
.close-btn {
font-size: 1.75rem;
background: transparent;
border-color: transparent;
color: var(--clr-primary-5);
transition: var(--transition);
cursor: pointer;
color: var(--clr-red-dark);
}
.close-btn:hover {
color: var(--clr-red-light);
transform: rotate(360deg);
}
.logo {
justify-self: center;
height: 40px;
}
.links a {
display: block;
font-size: 1.5rem;
text-transform: capitalize;
padding: 1rem 1.5rem;
color: var(--clr-grey-5);
transition: var(--transition);
}
.links a:hover {
background: var(--clr-primary-8);
color: var(--clr-primary-5);
padding-left: 1.75rem;
}
.social-icons {
justify-self: center;
display: flex;
padding-bottom: 2rem;
}
.social-icons a {
font-size: 1.5rem;
margin: 0 0.5rem;
color: var(--clr-primary-5);
transition: var(--transition);
}
.social-icons a:hover {
color: var(--clr-primary-1);
}
.sidebar {
position: fixed; /* 사이드바를 뷰포트에 고정시키며, 스크롤 시에도 같은 위치에 유지 */
top: 0; /* 뷰포트의 맨 위에서 시작 */
left: 0; /* 뷰포트의 왼쪽에서 시작 */
width: 100%; /* 사이드바의 너비를 뷰포트의 전체 너비로 설정 */
height: 100%; /* 사이드바의 높이를 뷰포트의 전체 높이로 설정 */
background: var(--clr-white); /* 사이드바의 배경색 설정 */
display: grid; /* CSS 그리드 레이아웃 사용 */
grid-template-rows: auto 1fr auto; /* 그리드 행의 크기를 상단과 하단에 자동, 중간에는 나머지 공간을 차지하도록 설정 */
row-gap: 1rem; /* 행 사이의 간격을 1rem으로 설정 */
box-shadow: var(--clr-red-dark); /* 사이드바의 그림자 색상 설정 */
transition: var(--transition); /* 변화(여기서는 위치 변경)에 대한 애니메이션 효과를 부드럽게 전환 */
transform: translate(-100%); /* 사이드바를 왼쪽으로 100% 이동시켜 뷰포트 밖으로 숨김 */
}
.show-sidebar {
transform: translate(0); /* 사이드바를 원래 위치로 이동시켜 화면에 표시 */
}
/* 미디어 쿼리: 스크린에서 뷰포트 너비가 676픽셀 이상일 경우 적용 */
@media screen and (min-width: 676px) {
.sidebar {
width: 400px; /* 사이드바 너비를 400픽셀로 설정 */
}
}
결과
오른쪽 상단의 햄버거 메뉴를 눌러 사이드바 동작을 확인하세요.
'JavaScript' 카테고리의 다른 글
[Javascript] 자바스크립트로 5초 마다 변경되는 배너 만들기 (0) | 2024.04.18 |
---|---|
[Javascript] 마우스 오버 텍스트 색상 변경 (0) | 2024.04.11 |
[Javascript] chart.js 를 사용하여 선 그래프 그리기 (0) | 2024.04.09 |
[JavaScript] CoinGecko API 와 chart api를 사용하여 각 화폐의 현재 USD 가격 표 형태로 비교하기 (0) | 2024.04.06 |
[JavaScript] 마우스 오버 이미지 미리보기 (0) | 2024.04.02 |