아래와 같이 글의 헤딩(heading)으로 만든 목차는 글의 구조를 파악하는 데에 도움을 주고, 프로그레스는 글의 전개를 이해하는 데에 도움을 준다.
나아가 스크롤의 위치에 따라 헤딩을 하이라이팅 한다면, 보다 몰입할 수 있는 웹사이트 이용 환경을 구축할 수 있을 것이다.
본 글은 스크롤을 내릴 때 헤딩이 슬라이딩으로 나타나고 헤딩을 화면 상단에 고정하는 방법에 대한 내용이다.
추가로 글 제목 및 메뉴를 화면 상단에 고정하는 것을 고려해서 적용할 것을 추천한다.
1] 헤딩 스타일 적용
먼저 헤딩의 스타일을 적용해 보겠다.
1-1] CSS 작업
아래 코드를 CSS에 삽입한다.
.tt_article_useless_p_margin h2 {
font-family: S-CoreDream-9Black; /* 폰트 종류 */
text-align: left; /* 텍스트 왼쪽 정렬 */
border-radius: 5px; /* 박스 테두리 */
background-color: #0A174E; /* 배경 색상 */
color: #F5D042; /* 폰트 색상 */
padding: 6px 15px 6px 15px; /* 박스 여백 */
margin-bottom: 15px; /* 박스 아래 간격 */
word-break: break-all; /* 텍스트 자동 줄바꿈 */
z-index: 100; /* Z축 */
}
.tt_article_useless_p_margin h3 {
font-family: S-CoreDream-8Heavy;
text-align: left;
background-color: #fff;
color: #000;
border-left: 10px solid #555;
border-bottom: 1px solid #555;
padding: 3px 0px 5px 10px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
}
.tt_article_useless_p_margin h4 {
font-family: S-CoreDream-7ExtraBold;
text-align: left;
background-color: #fff;
color: #000;
border-left: 5px solid #888;
border-bottom: 1px solid #888;
padding: 3px 0px 5px 10px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
}
1-2] 작업 결과
아래와 같이 h2, h3, h4의 스타일 적용됐다. 세부 수치는 기호에 맞게 수정하기 바란다.
2] sticky 코드로 고정
스크롤을 내릴 때 헤딩을 화면 상단에 고정하는 가장 쉬운 방법은 sticky 코드를 사용하는 것이다.
2-1] CSS 작업
아래 코드를 CSS에 삽입한다.
.tt_article_useless_p_margin h2 {
position: sticky;
top: 0px;
}
2-2] 작업 결과
아래와 같이 스크롤을 내릴 때 헤딩이 화면 상단에 고정된다.
그런데 이 방법의 단점은 모든 헤딩이 고정되기 때문에 (헤딩끼리 밀어내는 것이 아니기 때문에) 헤딩이 길 경우 아래와 같은 문제가 발생한다.
3] 헤딩끼리 밀어내며 고정
헤딩끼리 밀어내기 하면서 고정하고 방법도 있다.
3-1] HTML 작업
아래 코드를 HTML의 </body> 위에 삽입한다.
<!-- 본문 헤딩 상단 고정 시작 -->
<script>
var stickyHeaders = (function() {
var $stickies;
var load = function(stickies, target) {
if (typeof stickies === "object" && stickies instanceof jQuery && stickies.length > 0) {
$stickies = stickies.each(function() {
var $thisSticky = $(this);
$thisSticky
.data('originalPosition', $thisSticky.offset().top)
.data('originalHeight', $thisSticky.outerHeight());
});
target.off("scroll.stickies").on("scroll.stickies", function(event) {
_whenScrolling(event);
});
}
};
var _whenScrolling = function(event) {
var $scrollTop = $(event.currentTarget).scrollTop();
$stickies.each(function(i) {
var $thisSticky = $(this),
$stickyPosition = $thisSticky.data('originalPosition'),
$newPosition,
$nextSticky;
if ($stickyPosition <= $scrollTop) {
$newPosition = Math.max(0, $scrollTop - $stickyPosition);
$nextSticky = $stickies.eq(i + 1);
if ($nextSticky.length > 0) {
$newPosition = Math.min($newPosition, ($nextSticky.data('originalPosition') - $stickyPosition) - $thisSticky.data('originalHeight'));
}
}
else {
$newPosition = 0;
}
$thisSticky.css('transform', 'translateY(' + $newPosition + 'px)');
});
};
return {
load: load
};
})();
$(function() {
stickyHeaders.load($(".tt_article_useless_p_margin h2"), $(window));
});
</script>
<!-- 본문 헤딩 상단 고정 끝 -->
</body>
3-2] CSS 작업
sticky 코드는 제거하고 아래 코드를 CSS에 추가 삽입한다.
.tt_article_useless_p_margin h2 {
position: relative;
}
3-3] 작업 결과
아래와 같이 스크롤을 내릴 때 헤딩끼리 밀어내기 하면서 화면 상단에 고정된다.
4] width 100%로 고정
헤딩을 본문 영역이 아닌 화면 전체 영역으로 고정하는 방법도 있다.
4-1] HTML 작업
아래 코드를 HTML의 </body> 위에 삽입한다.
<!-- 본문 헤딩 상단 고정 시작 -->
<script>
var stickyHeaders = (function() {
var $window = $(window),
$stickies;
var load = function(stickies) {
if (typeof stickies === "object" && stickies instanceof jQuery && stickies.length > 0) {
$stickies = stickies.each(function() {
var $thisSticky = $(this).wrap('<div class="entry-content" />');
$thisSticky
.data('originalPosition', $thisSticky.offset().top)
.data('originalHeight', $thisSticky.outerHeight(true))
.parent()
.height($thisSticky.outerHeight(true));
});
$window.off("scroll.stickies").on("scroll.stickies", function() {
_whenScrolling();
});
}
};
var _whenScrolling = function() {
$stickies.each(function(i) {
var $thisSticky = $(this),
$stickyPosition = $thisSticky.data('originalPosition');
if ($stickyPosition <= $window.scrollTop()) {
var $nextSticky = $stickies.eq(i + 1),
$nextStickyPosition = $nextSticky.data('originalPosition') - $thisSticky.data('originalHeight');
$thisSticky.addClass("fixed");
if ($nextSticky.length > 0 && $thisSticky.offset().top >= $nextStickyPosition) {
$thisSticky.addClass("absolute").css("top", $nextStickyPosition);
}
}
else {
var $prevSticky = $stickies.eq(i - 1);
$thisSticky.removeClass("fixed");
if ($prevSticky.length > 0 && $window.scrollTop() <= $thisSticky.data('originalPosition') - $thisSticky.data('originalHeight')) {
$prevSticky.removeClass("absolute").removeAttr("style");
}
}
});
};
return {
load: load
};
})();
$(function() {
stickyHeaders.load($(".tt_article_useless_p_margin h2"));
<!-- stickyHeaders.load($(".tt_article_useless_p_margin h3")); -->
<!-- stickyHeaders.load($(".tt_article_useless_p_margin h4")); -->
});
</script>
<!-- 본문 헤딩 상단 고정 끝 -->
</body>
4-2] CSS 작업
아래 코드를 CSS에 삽입한다.
.tt_article_useless_p_margin h2 {
position: relative;
font-family: S-CoreDream-9Black;
text-align: left;
border-radius: 5px;
background-color: #0A174E;
color: #F5D042;
padding: 6px 15px 6px 15px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
}
.tt_article_useless_p_margin h3 {
position: relative;
font-family: S-CoreDream-8Heavy;
text-align: left;
background-color: #fff;
color: #000;
border-left: 10px solid #555;
border-bottom: 1px solid #555;
padding: 3px 0px 5px 10px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
}
.tt_article_useless_p_margin h4 {
position: relative;
font-family: S-CoreDream-7ExtraBold;
text-align: left;
background-color: #fff;
color: #000;
border-left: 5px solid #888;
border-bottom: 1px solid #888;
padding: 3px 0px 5px 10px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
}
.tt_article_useless_p_margin h2.fixed {
position: fixed !important;
top: 0px !important;
left: 0px;
right: 0px;
z-index: 9000;
}
.tt_article_useless_p_margin h2.fixed.absolute {
position: absolute;
}
4-3] 작업 결과
아래와 같이 헤딩이 화면 상단에 고정될 때 헤딩이 화면 전체 영역으로 확장된다.
5] h2, h3, h4 모두 고정
헤딩 h2, h3, h4를 모두 고정하는 방법도 있다.
5-1] HTML 작업
'4-1'의 HTML 코드를 아래 코드로 수정한다.
$(function() {
stickyHeaders.load($(".tt_article_useless_p_margin h2, .tt_article_useless_p_margin h3, .tt_article_useless_p_margin h4"));
});
5-2] CSS 작업
아래 코드와 같이 h2 코드는 수정하고 h3, h4 코드를 삽입한다.
.tt_article_useless_p_margin h2.fixed {
position: fixed !important;
top: 0px !important;
left: 0px;
right: 0px;
z-index: 9000;
}
.tt_article_useless_p_margin h2.fixed.absolute {
display: none;
}
.tt_article_useless_p_margin h3.fixed {
position: fixed !important;
top: 0px !important;
left: 0px;
right: 0px;
background
z-index: 9000;
}
.tt_article_useless_p_margin h3.fixed.absolute {
display: none;
}
.tt_article_useless_p_margin h4.fixed {
position: fixed !important;
top: 0px !important;
left: 0px;
right: 0px;
z-index: 9000;
}
.tt_article_useless_p_margin h4.fixed.absolute {
display: none;
}
5-3] 작업 결과
아래와 같이 스크롤을 내릴 때 h2, h3, h4가 모두 화면 상단에 고정된다.
6] 헤딩 슬라이딩 등장
마지막으로 헤딩을 슬라이딩으로 하이라이팅 하는 방법이다.
6-1] HTML 작업
아래 코드를 HTML의 </body> 위에 삽입한다.
<!-- 스크롤 시 본문 헤딩 좌측 슬라이딩 시작 -->
<script>
var $animation_elements = $('.tt_article_useless_p_margin h2');
var $window = $(window);
function check_if_in_view() {
var window_height = $window.height();
var window_top_position = $window.scrollTop();
var window_bottom_position = (window_top_position + window_height);
$.each($animation_elements, function() {
var $element = $(this);
var element_height = $element.outerHeight();
var element_top_position = $element.offset().top;
var element_bottom_position = (element_top_position + element_height);
if ((element_bottom_position >= window_top_position) &&
(element_top_position <= window_bottom_position)) {
$element.addClass('in-view');
}
else {
$element.removeClass('in-view');
}
});
}
$window.on('scroll resize', check_if_in_view);
$window.trigger('scroll');
</script>
<!-- 스크롤 시 본문 헤딩 좌측 슬라이딩 끝 -->
</body>
6-2] CSS 작업
아래 코드와 같이 h2 코드를 수정 및 삽입한다.
.tt_article_useless_p_margin h2 {
font-family: S-CoreDream-9Black;
text-align: left;
border-radius: 5px;
background-color: #0A174E;
color: #F5D042;
padding: 6px 15px 6px 15px;
margin-bottom: 15px;
word-break: break-all;
z-index: 100;
position: sticky;
top: 0px;
opacity: 0;
transition: all 500ms linear;
-moz-transition: all 500ms linear;
-webkit-transition: all 500ms linear;
-o-transition: all 500ms linear;
transform: translate3d(-100px, 0px, 0px);
-moz-transform: translate3d(-100px, 0px, 0px);
-webkit-transform: translate3d(-100px, 0px, 0px);
-o-transform: translate(-100px, 0px);
-ms-transform: translate(-100px, 0px);
}
.tt_article_useless_p_margin h2.in-view {
opacity: 1;
transform: translate3d(0px, 0px, 0px);
-moz-transform: translate3d(0px, 0px, 0px);
-webkit-transform: translate3d(0px, 0px, 0px);
-o-transform: translate(0px, 0px);
-ms-transform: translate(0px, 0px);
}
6-3] 작업 결과
아래와 같이 스크롤을 내릴 때 헤딩이 화면 영역 안으로 들어오면서 슬라이딩으로 등장한다.