[Git Page Jekyll Blog] - [11] Fixed Topbar 만들기
내 블로그의 Topbar와 같이 화면을 스크롤 해도 항상 그 자리에 고정돼 있는 Topbar를 구현하자. 내 블로그의 Fixed Topbar는 Fixed Topbar 구현 포스트의 방법2 를 바탕으로 제작되었다. 이 포스트에서는 같은 방법을 Minimal-Mistakes 테마에 적용하는 과정을 포스팅 할 것이다.
과정https://innolifes22.github.io/blog/topbar/#과정
과정을 진행하면서 Topbar를 페이지 최상위에 고정 시키고 Fixed Topbar 구현 포스트에서 제기했던 HTML 요소가 가려지는 문제를 해결할 것이다.
1. Topbar 고정https://innolifes22.github.io/blog/topbar/#1-topbar-고정
mmistakes 테마에서 Topbar를 페이지 최상위에 고정시키기위해 아래와 같은 CSS 를 적용한다.
1
2
3
4
5
6
.masthead {
position: fixed;
top: 0;
height: calc(3 * 16px);
width: 100%;
}
코드의 4번째 줄에서 Topbar의 높이 calc(3 * 16px);
는 48px가 된다.
2. 내용 여백 조정https://innolifes22.github.io/blog/topbar/#2-내용-여백-조정
Fixed Topbar로 인해 포스트 내용이 가려지는 것을 방지하기 위해 내용이 약간 아래부터 시작하도록 윗쪽 여백을 넣는다.
1
2
3
body {
padding-top: calc(3 * 16px + 8px);
}
Fixed Topbar의 높이(3*16px=48px
)에 +8px
만큼의 여백을 더 추가하였다.
3. Javascript 작성https://innolifes22.github.io/blog/topbar/#3-javascript-작성
위 두가지 css 설정으로 해결 되지 않는 문제들을 javascript를 이용해서 해결한다.
Fixed Topbar 구현 포스트에서 제기한
문제 상황 2,
3이 여기에 해당한다.
스크롤 목적지를 살짝 위로 설정https://innolifes22.github.io/blog/topbar/#스크롤-목적지를-살짝-위로-설정
먼저 페이지를 스크롤하는 함수를 정의한다.
1
2
3
4
5
6
top_offset = 99;
function scrollToHash(h) {
// 스크롤 위치를 목적지의 y 좌표 보다 top_offset 만큼 위의 좌표로 계산
var yPos = $(h).offset().top - top_offset;
scrollTo({top: yPos, behavior: 'smooth'});
}
자동 스크롤을 하면 기본적으로 브라우저 화면 맨 꼭대기에 스크롤 목적지의 y좌표가 위치하도록 스크롤 된다.
이때 스크롤 목적지의 y좌표에 top_offset
만큼을 빼주면 브라우저 화면 맨 꼭대기에 top_offset
픽셀 만큼
위의 y좌표가 오게된다.
즉, 실제 목적지는 브라우저 화면 꼭대기에서 부터 top_offset
만큼 아래에 있도록 스크롤 된다.
또한 scrollTo()
(스크롤 함수)에 behavior: 'smooth'
옵션을 넣어서 부드러운 스크롤링을 설정했다.
Windows에서 애니메이션 표시https://innolifes22.github.io/blog/topbar/#windows--
참고로 Windows OS에서 부드러운 스크롤링은 Windows에서 애니메이션 표시
옵션을 켜야 정상적으로 동작 한다.
다른 페이지로 부터 이동해 온 다음 특정 위치로 자동 스크롤https://innolifes22.github.io/blog/topbar/#다른-페이지로-부터-이동해-온-다음-특정-위치로-자동-스크롤
다른 페이지에서 링크를 클릭하면 링크의 href
경로로 페이지 이동한다.
이때 href
에 hash
1가 있으면 브라우저는 페이지 이동한 후 해당 hash
의 위치로
화면을 자동 스크롤 한다.
1
2
3
4
5
6
$(function() {
if(location.hash.length > 0) {
var h = decodeURIComponent(location.hash);
scrollToHash(h);
}
});
$(function() { });
로 시작하는 함수는 jquery
에서 지원하는
$( document ).ready(function() { });
함수의 축약형이다. 이 함수는
페이지의 로드가 완료되면 실행 된다는 특징이 있다.
이 함수를 이용해서 위와 같이 코드를 짜면 페이지 로드가 완료되었을 때 현재 URL에 hash
가
포함되어 있는지 확인하고 hash
가 포함돼 있다면 해당 hash
의 y 좌표로 스크롤 한다.
같은 페이지 내에서 다른 위치로 자동 스크롤https://innolifes22.github.io/blog/topbar/#같은-페이지-내에서-다른-위치로-자동-스크롤
링크를 클릭하면 링크의 href
경로로 이동하는데 그 경로가 현재 페이지의 주소와 같은 경우
페이지의 이동 없이 href
에 있는 hash
의 위치로 자동 스크롤 한다.
1
2
3
4
5
6
7
8
9
$('a').click(function (e) {
if($(this)[0].origin == location.origin &&
$(this)[0].pathname == location.pathname) {
e.preventDefault();
var h = $(this).attr('href');
scrollToHash(h);
history.pushState({}, null, h);
}
});
링크의 href
를 이용하므로 <a>
태그에서만 동작한다. 다른 태그에서도 같은 스크롤 기능을 구현
하려면 $('a')
부분을 변경해 주면 된다.
두번째 줄에 있는 조건문의 origin
은 URL의 root 주소를 의미한다.
따라서 이동하려는 목적지와 현재 페이지의 root 주소가 같은지 확인 할 수 있다.
내 블로그의 root 주소는 https://seungwubaek.github.io가 된다.
이어서 세번째 줄의 pathname은 root 주소 이후로 이어지는 주소를 의미한다. 여기까지는 hash
가
포함되지 않는다.
즉, 조건문의 참이 되는 주소는 이동하려는 목적 주소가 현재 페이지와 같은 주소이다.
e.preventDefault();
를 이용해 기본으로 설정되어 있는 자동 스크롤 기능을 해제한다.
그리고 링크가 가진 hash
값을 인자로 하는 스크롤 함수(scrollToHash
)를 실행시킨다.
마지막으로 history.pushState
함수로 href
가 가진 hash
값을 이동한 곳에 맞게 변경해준다.
historyhttps://innolifes22.github.io/blog/topbar/#history
history
라는 객체는 페이지 이동 히스토리를 저장하고 있다. 브라우저의 뒤로/앞으로 가기 기능은
이 객체가 있기 때문에 가능하다. 그래서 위 코드와 같이 history.pushState
를 해주면
history
에 hash
를 포함하는 href
가 저장되고 뒤로/앞으로 가기 기능을 그대로 사용할 수 있다.
Javascript 전체 코드https://innolifes22.github.io/blog/topbar/#javascript-전체-코드
위 코드 조각들을 한번에 쓰면 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$(function() {
top_offset = 99;
function scrollToHash(h) {
var yPos = $(h).offset().top - top_offset;
scrollTo({top: yPos, behavior: 'smooth'});
}
// 외부 페이지로부터 이동해 온 후 다른 위치로 스크롤 할 때
if(location.hash.length > 0) {
var h = decodeURIComponent(location.hash);
scrollToHash(h);
}
// 같은 페이지에서 다른 위치로 스크롤 할 때
$('a').click(function (e) {
if($(this)[0].origin == location.origin &&
$(this)[0].pathname == location.pathname) {
e.preventDefault();
var h = $(this).attr('href');
scrollToHash(h);
history.pushState({}, null, h);
}
});
});
-
hash: href 끝에
#
으로 시작하는 문자열. 요소의 id를 의미. ↩
Share on
Copy URL
Leave a comment