0. 오늘의 과제
홈페이지를 기본 틀로 카피해두고, 다른 웹 페이지를 직접 만들어서 React로 연결하고, 백엔드를 구성하는 방향으로 진행할까 한다.
이미지, 폰트 등의 리소스는 원본 웹페이지에서 그대로 가져와서 사용하고, 코드는 원본을 참고하되 홈페이지에서 사용하는 요소를 제외한 불필요한 요소를 걷어내어 최대한 가볍게 만들기로 했다. 또한, 이 과정에서 발견한 기존 홈페이지의 문제점을 직접 고쳐보고 사용자 관점에서 아쉬운 점을 자율적으로 개선해보겠다.
클론 코딩 대상
클론 코딩의 대상으로 삼은 것은 NC Dinos 의 메인 홈페이지. 선정한 이유는 생각보다 많은 요소를 다루고 있고, 독특한 주제라고 생각했기 때문이다. 야구 룰은 자세히 모른지만 야구장에 가는 것은 즐겁다. (먹으러..?)
NC Dinos
www.ncdinos.com
클론 코딩의 프로젝트 깃허브 주소
https://github.com/ncb-yji/clone-ncdinos
GitHub - ncb-yji/clone-ncdinos: Clone of NC Dinos official website
Clone of NC Dinos official website. Contribute to ncb-yji/clone-ncdinos development by creating an account on GitHub.
github.com
1. 클론 코딩으로 웹 페이지 만들기 (프론트엔드 한정)
HTML, Javascript, CSS 만으로 이루어진 프론트엔드 실습이므로, 백엔드는 작성하지 않고 겉모습만 구현한다.
유튜브 등의 외부 사이트를 참고하는 링크만 남겨두고, NC Dinos의 내부 사이트로 이동하는 링크는 전부 막아놨다.
1-1. 소스 코드 참고하기
개발자 모드의 Souces 탭과 Elements 탭을 참고하면서 구성을 해준다. 당연히 그대로 복붙한다고 웹페이지가 제대로 돌아가진 않고 .js나 .css 파일의 수정이 필요하다. 크롬의 '페이지 소스보기 (Ctrl+U)'를 이용해서 정적 코드도 함께 참고했다.

개발자 모드의 Sources 탭에서 원본 .js와 .css 코드를 참고했다. css만 5000줄이 넘어가는데 이는 NC Dinos 내부의 다른 페이지에서 사용하는 코드도 포함되어 있기 때문에 내가 필요한 코드를 확인하기 힘들다. 나는 홈페이지만 구성하는데에 이 코드를 전부 사용할 필요는 없으므로, Coverage 기능을 사용해서 불필요한 코드는 삭제했다. 필요한 코드만 남겨두는 편이 오류를 수정하기에도, 어디에 어떤 코드가 적용되는지 확인하기에도 쉬워서 학습에 도움이 된다. 그리고 다른 페이지도 디자인이나 느낌이 메인 페이지와 비슷할 것이므로, 나중에 다른 페이지를 처음부터 스스로 작성하는데에 가이드라인이 될 것이다.
1-2. 이미지 리소스 이용하기
리소스 등은 원본 페이지에서 참고하고 있는 URL을 그대로 연결해줬다. 가끔 브라우저에서 이미지 URL이 확인되지 않는 경우가 있는데, 백엔드에서 이미지가 넘어오는 경우도 있는 모양이다. 이는 개발자모드의 Network탭을 이용해서 주소를 확인했다.
아마존 S3로 부터 가져오는 이미지들은 외부에서 접근이 되지 않는 경우가 있어서, 이런 이미지들은 로컬에 직접 다운로드 받아서 사용했다.
1-3. 폰트 리소스 이용하기
폰트 또한 비슷한 방식으로 불러오면 되지만 일부 폰트가 제대로 적용되지 않는 경우가 있었다.
개발자모드의 Network 탭에서 확인해보면, CSS 코드에 Import는 되어있지만, 실제로는 불러오지 못하고 있다. 이 경우는 CORS(Cross-Origin Resource Sharing) 정책으로 인해 폰트 로딩이 차단되어 웹폰트 링크를 외부 사이트에서 사용하지 못한다.
이 경우엔 URL로는 접근 가능하니 로컬에 직접 다운로드 받아서 사용해야 한다.

2. 원본 페이지의 버그를 수정 해보기
원본 페이지의 동작을 확인하면서 카피하다보니, NC Dinos 홈페이지에 몇가지 버그가 눈에 띄었다.
1. '다이노스 포토' 란의 슬라이더가 다른 슬라이더의 영향을 받는다.
2. '다이노스 포토' 와 맨 아래 '후원사' 의 버튼이 공통으로 사용되고 있어, '후원사' 란의 동작이 이상하다.
3. 챗봇 버튼이 다른 HTML 요소에 의해 가려지는 경우가 있다.
차례차례 무엇이 문제이고 어떻게 해결할지 분석해보자.
2-1. '다이노스 포토' 란의 슬라이더가 다른 슬라이더의 영향을 받는다.
현상)
- 웹페이지 상단 메인 배너의 슬라이드 'O' 버튼 (pagination)을 클릭해서 이전 혹은 다음 페이지로 넘어가면 다이노스 포토의 슬라이드도 같은 동작을 한다.
- 하지만 그 반대의 경우(다이노스 포토 -> 메인 배너) 엔 문제가 발생하지 않았다.
- 웹페이지 하단의 후원사 슬라이드의 '>' 버튼 (navigation)을 클릭하는 경우에도 동일한 동작을 한다. → 2-2 에서 다룸

원인)
- script.js 에서 두 슬라이드의 pagination 설정의 DOM 요소 선택자가 같기 때문에 영향을 미친다.
- 현재, mainSlider(메인 배너) 와 newsSlider(다이노스 포토)의 pagination 선택자가 '.swiper-pagination'으로 동일하다.

해결 방법) index.html을 참고하여 pagination의 el 속성에 정확한 선택자를 부여한다.

탐구) "하지만 그 반대의 경우(다이노스 포토 -> 메인 배너) 엔 문제가 발생하지 않았다." → 왜?
✅ 핵심 원인:
- .swiper-pagination이 겹치기 때문에, mainSlider()에서 먼저 해당 DOM 요소를 사용해버림
- mainSlider()는 먼저 초기화되며, 문서 전체에서 .swiper-pagination을 먼저 찾아서 news 슬라이더용 pagination을 잘못 잡음
- 이후 newsSlider()가 정상적으로 자기 pagination을 쓴다

✅ 그래서 왜 반대는 영향을 안 주는가?
- newsSlider()가 나중에 초기화되며 자신만의 슬라이더 영역에서 .swiper-pagination을 찾고,
- 이미 mainSlider()는 초기에 잘못된 요소를 잡았더라도, 이후 초기화된 newsSlider()가 DOM에 영향을 주진 않음
- 즉, Swiper 인스턴스 생성 시점의 DOM 요소 선택에 따라 영향이 갈리는 것
2-2. '다이노스 포토' 와 맨 아래 '후원사' 의 버튼이 공통이다.
현상)
- 다이노스 포토의 첫 장에서는 좌측이동버튼(<)이 사라진다. (정상)
- 다이노스 포토의 마지막 장에서는 우측이동버튼(>)이 사라진다. (정상)
- 하단 후원사 슬라이드의 버튼도 다이노스 포토와 동일하게 표시된다. 후원사 슬라이드는 첫장과 마지막이 존재하지 않고 반복되므로 이동 버튼이 사라질 필요는 없다. (아마도 비정상)

원인)
- script.js 에서 두 슬라이드의 navigation 설정의 DOM 요소 선택자가 같기 때문에 영향을 미친다.
- newsSlider(다이노스 포토)와 logoSlider(후원사) 의 navigation 버튼 선택자가 '.ico ico-next', '.ico .ico-prev'로 동일하다.

해결 방법) index.html을 참고하여 navigation의 nextEl, prevEl 속성에 정확한 선택자를 부여한다.

2-3. 화면의 사이즈가 작아지거나, 화면을 확대하는 경우 챗봇 버튼이 다른 HTML 요소에 의해 가려지는 경우가 있다.
현상)

원인) 챗봇 아이콘의 z-index 값이 누락되어 있다.
이미지를 맨 앞으로 보내고 싶다면, 해당 이미지 또는 감싸는 div 등에 높은 z-index 값을 줘야 한다.
참고로 position 속성 없이 z-index만 주면 동작하지 않는다 하니 반드시 position을 relative, absolute, fixed 중 하나로 지정해준다. 이미지가 맨 위로 표시되지 않는 경우, 다른 요소의 z-index가 더 높은 경우일 수도 있다.
해결 방법) 챗봇 아이콘의 z-index를 다른 요소에 비해 높게 지정해준다. (어차피 맨위에 배치할 것이므로 아주 높은 값도 OK)
탐구) Z-Index를 지정해주지 않는다면 기본값은 무엇인가?
z-index를 설정하지 않으면 기본값은 'auto' 다.
- 어떤 요소의 z-index는 부모 요소의 z-index 를 따른다.
- z-index가 명시되지 않은 요소들끼리는 HTML 문서에서 나중에 작성된 요소가 위에 올 수도 있고,position(위치 속성)에 따라 달라질 수 있다.
<div class="box1">Box 1</div>
<div class="box2">Box 2</div>
위처럼 두 박스가 겹쳐 있으면 box2가 위에 표시된다. 왜냐하면 box2가 나중에 정의되었고, 둘 다 z-index: auto이기 때문이다.
- 참고) 사진 슬라이드 기능에 사용된 Swiper란 무엇인지, 각 속성의 의미
✅ Swiper란?
Swiper는 터치 지원이 되는 모바일 친화적인 슬라이더(캐러셀) 라이브러리입니다.
- 다양한 슬라이드 효과, 네비게이션(← →), 페이지네이션(● ○ ○), 자동 재생 등을 지원
- 웹사이트에서 배너, 갤러리, 콘텐츠 캐러셀 구현에 널리 사용됨
- CSS와 JavaScript만으로 구동되며, HTML 구조와 클래스 이름에 따라 다양한 조합 가능
✅ 공통 구조 분석 및 속성 설명
📌 기본 구조 예:
new Swiper('대상 요소 선택자', {
속성: 값,
속성: 값,
...
});
🧾 속성별 상세 설명
| 속성 | 타입 | 의미 |
| loop | true / false | 슬라이드가 끝에 도달하면 처음으로 돌아가 반복 여부 |
| spaceBetween | 숫자(px) | 슬라이드 사이 간격 |
| slidesPerView | 숫자 | 한 화면에 보일 슬라이드 개수 |
| slidesPerGroup | 숫자 | 한 번에 이동할 슬라이드 개수 |
| speed | 숫자(ms) | 슬라이드 전환 속도 |
| effect | "slide" / "fade" 등 | 슬라이드 전환 효과 (예: 부드럽게 사라지고 나타나는 'fade' 효과) |
| navigation | { nextEl, prevEl } | 이전/다음 버튼을 지정하는 객체 |
| pagination | { el, type, clickable } | 페이지네이션 관련 설정 el : 기능이 적용될 DOM 요소 선택자 type : 버튼을 어떤 형태로 표시할지 (bullets, fraction, progressbar, custom) clickable : 페이지네이션 점을 클릭 가능하게 함 |
| autoplay | { delay } | 자동 슬라이드 기능 delay : 시간 간격(ms) |
3. 기타 개선점
사용자 관점에서 아쉬운 점을 개선해보자.
- '다이노스 영상' 란의 타이틀이 사진에 의해 가려지는 경우가 있어 보기 불편하다.
→ 타이틀의 padding 을 조정해서 잘 표시되게 만들었다. - '다이노스 영상' 란의 좌측 메인 영상이 다른 영상들보다 크게 표시되어있는데, 현재 다른 영상들처럼 단순한 링크로 되어있어 의미가 없다. 웹 페이지에서 영상이 바로 재생되면 좋겠다.
→ 링크 대신에 iframe 태그로 youtube 영상을 직접 삽입해서 현재 페이지에서 재생가능하게 만들었다.
개선 전)

개선 후) 타이틀의 위치가 조정되었고, 좌측의 메인 영상은 재생이 가능하다. 우측의 서브 영상들은 기존처럼 링크로 남아있다.

본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 (B-log) 리뷰로 작성 되었습니다.
'학습일지 > K-Digital Traing' 카테고리의 다른 글
| [KDT] AIaaS 마스터클래스 8주차 - 리액트 Hook (1) | 2025.05.14 |
|---|---|
| [KDT] AIaaS 마스터클래스 8주차 - React 학습 (0) | 2025.05.12 |
| [KDT] AIaaS 마스터클래스 6주차 - 테라폼, 깃허브 액션 실습 (5) | 2025.04.28 |
| [KDT] AIaaS 마스터클래스 5주차 - 프라이빗 서비스 인프라 구축 실습 (0) | 2025.04.25 |
| [KDT] AIaaS 마스터클래스 5주차 - 리눅스 ssh 실습 (0) | 2025.04.24 |