
바쁘신 분들은 [ Learning point 🧐 ] 부분을 꼭 읽어주세요!
HTML과 CSS를 이론 공부에서 끝내지 않고 체화하기 위함입니다.
HTML 이론 체화 목표
1. 시멘틱 태그 사용해보기 (header, section, main, footer 등)
2. HTML5 태그 사용해보기 (dialog 태그)
3. 미디어 태그 사용해보기 (video, svg 태그)
4. 다양한 meta 태그 사용해보기
CSS 이론 체화 목표
1. CSS3 flex layout 사용해보기
2. 간단한 transition, animation 사용해보기
3. 다양한 디자인 상황 직면해보기
4. BEM 방법론 도입해보기
5. SCSS와 같은 전처리 도구 도입해보기
- HTML5, CSS3를 메인으로 약간의 JS를 사용하여 웹 사이트를 제작하였습니다. (+ SCSS, parcel)
- Github.io 무료 배포 서비스를 활용하여 프로젝트를 배포하였습니다.
1. 전체적인 HTML 구성의 중요성
전체적인 구조를 생각하지 않고 header면 header대로 menu는 menue대로 지엽적인 부분들만 먼저 구현하려고 시도하면 안된다는 것을 알았다.
전체적인 태그들의 구조를 작성한 후 작업하는 것이 훨씬 효율적이었다.
2. class 이름의 중요성
구조가 복잡해지면서 부모, 자식 관계의 태그를 디자인할 때 클래스 이름이 명확하지 않으면 작업 소요 시간이 오래 걸린다는 것을 몸소 체감했다.
향후 현업을 위해서라도 각 요소의 이름을 명확하고 논리적인 흐름이 있도록 짓는 것은 중요하다.
3. 한 번의 구현 겸험이 여러 번의 이론 공부 내용 정리보다 값지다.
머릿속으로만 알고 있었던 Flex Layout 개념이 이번 Clone Coding을 통해 명확해졌다.
Flex 레이아웃 개념이 어느 정도 체화되면서 작업 후반부로 갈수록 HTML 구조와 CSS Flex Layout을 동시에 고려하면서 Clone Coding을 할 수 있었고, 마무리 단계에서는 HTML 구조와 디자인 방식이 머릿속에 그려지게 되었다. (+ 다른 사이트의 레이아웃을 보는 눈이 생겼다.)
4. 무조건 JS로 기능을 구현하는 것이 답은 아니다.
처음 테슬라 코리아 홈페이지를 보면서 scroll-snap 기능이 해당 웹 사이트의 UX에 가장 큰 영향을 준다고 판단하였고 중요한 부분인 만큼 당연히 JS로 구현해야겠다고 단순하게 생각했다.
하지만 JS를 사용하는 것 보다 CSS의 scroll-snap-type을 활용하는 것이 원하는 기능을 구현할 수 있음은 물론 개발 시간까지 줄일 수 있었다.
실제 코드 리뷰들을 보면 JS로 구현되지 않았다는 점에서 다들 인상깊게 보았다.


5. SCSS, Less 등 전처리 도구의 필요성
프로젝트에 필요한 디자인과 스타일링이 늘어나면서 중복 되는 CSS 코드가 많다고 느끼게 되었고, 이 부분에서 발생하는 작업 시간을 줄이고 싶었고 코드를 재사용하고 싶은 생각이 들었다.
또한 코드 리뷰를 통한 리팩토링 과정에서, 한 부분의 디자인을 변경하더라도 여러 파일의 내용들을 수정해야하는 번거러움도 있었다.
이에 CSS 전처리 도구에 대해서 생각해게 되었고 학습의 필요성을 느끼게 되었다.
CSS 전처리 도구를 사용하면 앞선 문제점들을 해결 할 수 있을 것으로 보인다.
이에 다양한 CSS 전처리 도구 중에서, 가장 오래되어 성숙도가 높고 커뮤니티가 있으며, 하나의 컴파일러로 모두 컴파일 가능한 SCSS로 리팩토링할 계획이다. (리펙토링 완료, 아래 Code Refactoring 목차 확인)
6. "왜 이 코드를 쓰는지" 생각하는 습관을 가지자.

그래서 부랴부랴 video 태그에 직접 src 속성을 정의하는 것과 무슨 차이가 있는지 검색해 보았고 이제서야 내가 쓴 코드를 제대로 이해했다.
구현하는 것에만 초점을 맞추고 코드를 짜는 것이 얼마나 위험한 행동인지 알게 되었다.
앞으로는 내가 선택한 코드가 프로젝트에 정확히 어떤 영향을 주고 있는지 생각하면서 개발해야겠다고 느꼈다.
- 시멘틱 태그를 이용하여 HTML 문서의 가독성을 높였습니다.
- CSS3의 Flex Layout을 활용하여 각 요소들을 효율적으로 배치하였습니다.
- JS 없이 CSS의 scroll-snap-type 속성만으로, 해당 웹 사이트의 UX에 가장 큰 영향을 끼치는 scroll-snap을 구현하였습니다.
- CSS의 Media Query를 활용하여 사용자 뷰 포트에 맞게 Hear 스타일을 다르게 가져갔습니다.
- 메뉴바 동작을 HTML5 dialog 태그와 JS의 showModal(), close()를 사용하여 효율적으로 구현하였습니다.
- JS를 활용해 사용자 스크롤 위치에 따라 header 스타일이 변하도록 하였습니다.
(각 JS 파일에 JS 사용 이유와 소스코드 설명을 주석을 통해 작성해 두었습니다.)+
7. Parcel과 SCSS를 활용하여 기존 CSS 코드를 유지 보수에 유리하도록 가독성있게 정리하였습니다.
/*
header 메뉴바를 열고 닫기 위한 JS 소스코드
(dialog 태그를 여닫는 El.showModal() El.close()가 필요하여 JS를 사용)
*/
// 메뉴바 구현용 dialog 요소 불러오기
const menuDialog = document.querySelector("dialog");
// 메뉴바 여닫는용 button 요소들 불러오기
const menuBtn = document.querySelector(".site-nav-items-menu");
const menuCloseBtn = document.querySelector(".menu-close-btn");
// 메뉴 button을 누르면 메뉴바가 열림
menuBtn.addEventListener("click", () => {
menuDialog.showModal();
});
// X button을 누르면 메뉴바가 닫힘
menuCloseBtn.addEventListener("click", () => {
menuDialog.close();
});
main{
min-width: 100vw;
height: 100vh;
overflow: auto;
scroll-snap-type: y mandatory;
}
.snappin-box {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-position: center;
background-size : cover;
background-repeat : no-repeat;
scroll-snap-align: center;
}
/*
실시간 사용자 스크롤 위치에 맞는 header 글자 색 변경용 JS 소스코드
(실시간 사용자 스크롤 위치가 필요하여 JS를 사용)
*/
// 실시간 사용자 스크롤 위치 감지용 main 요소 불러오기
const main = document.querySelector("main");
// header 로고와 글자 색 변경용 모든 header 요소 불러오기
const headerLogo = document.querySelector(".site-logo-tesla");
const headerText = document.querySelectorAll(".site-nav li span");
// 변경 색상 정의
const BLACK = "#171A20"
const WHITE = "#F9F8F8"
// 실시간 사용자 스크롤의 위치가 첫 페이지에 있다면 header 로고와 글자 색을 WHITE, 아니면 BLACK으로 변경
mainPage.addEventListener("scroll", event => {
if (event.target.scrollTop === 0) {
changeColorToWhite();
} else {
changeColorToBlack();
}
});
// 실시간 사용자 스크롤이 첫 페이지에 있다면 참을 반환
function userScrollInFirstPage(userScroll) {
return userScroll < main.offsetHeight
};
// header 로고와 글자 색을 흰 색으로 변경
function changeColorToWhite(){
headerLogo.style.color = WHITE;
headerText.forEach((span) => {
span.style.color = WHITE;
});
}
// header 로고와 글자 색을 검은 색으로 변경
function changeColorToBlack(){
headerLogo.style.color = BLACK;
headerText.forEach((span) => {
span.style.color = BLACK;
});
}
@media (max-width: 1200px) {
.site-nav-products,
.site-nav-items li:nth-of-type(1),
.site-nav-items li:nth-of-type(2) {
display: none;
}
}
- SCSS Ampersand (상위 선택자 참조)를 활용한 가독성 및 코드 연관성 향상
#menu {
...
}
#menu[open] {
...
}
#menu::backdrop {
...
}
#menu {
...
&[open] {
...
}
&::backdrop {
...
}
}
- SCSS @mixin, @include를 활용한한 코드 재사용, 읽기 쉬운 코드로 refactoring
#menu-btn {
...
}
#menu-close-btn svg {
...
}
#menu-items li a {
...
}
#menu-btn:hover,
#menu-close-btn svg:hover,
#menu-items li a:hover {
border-radius: 3px;
background-color: #b3b9bc4b;
}
@mixin menuBtnHover {
border-radius: 3px;
background-color: #b3b9bc4b;
}
#menu-btn {
...
&:hover {
@include menuBtnHover;
}
}
#menu-close-btn svg {
...
&:hover {
@include menuBtnHover;
}
}
#menu-items {
...
li {
...
}
a {
...
&:hover {
@include menuBtnHover;
}
}
}
- Sass Partials 기능을 활용한 각 기능 모듈화 및 유지 보수 편의성 향상
- 프로젝트 규모가 커지면 파일이 점점 많아지는데, 모든 scss파일을 컴파일하여 각각의 .css 파일로 나눠서 저장한다면 관리나 성능 차원에서 문제가 될 수 있다.
- 파일 이름 앞에
_를 붙여(_header.scss와 같이)@import로 가져오면 컴파일 시 전처리 결과를 한 파일에 모두 넣어줄 수 있다.
@import "variables", "header", "menu", "main-content", "main-text", "main-btn",
Sass-App
# ...
├─css
│ └─main.css # header + variables + menu ... 전처리 결과를 한 파일에 모두 넣어줌
├─scss
│ ├─header.scss
│ ├─menu.scss
│ ├─variables.scss
│ ├─styles.scss
│ └─ ...등등
# ...
<link rel="stylesheet" href="./src/styles/styles.scss" />