본문 바로가기

티스토리 헤딩(heading) 상단 고정 및 슬라이딩(sliding)

by JINYH 2022. 2. 21.
728x90
반응형

아래와 같이 글의 헤딩(heading)으로 만든 목차는 글의 구조를 파악하는 데에 도움을 주고, 프로그레스는 글의 전개를 이해하는 데에 도움을 준다.

 

00-TOC-progress

 

 

나아가 스크롤의 위치에 따라 헤딩을 하이라이팅 한다면, 보다 몰입할 수 있는 웹사이트 이용 환경을 구축할 수 있을 것이다.

 

본 글은 스크롤을 내릴 때 헤딩이 슬라이딩으로 나타나고 헤딩을 화면 상단에 고정하는 방법에 대한 내용이다.

 

추가로 글 제목 및 메뉴를 화면 상단에 고정하는 것을 고려해서 적용할 것을 추천한다.

 

 

 

 

 


 

 

 

 

 

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의 스타일 적용됐다. 세부 수치는 기호에 맞게 수정하기 바란다.

 

01-헤딩-디자인

 

 

 

 

 

2] sticky 코드로 고정

 

스크롤을 내릴 때 헤딩을 화면 상단에 고정하는 가장 쉬운 방법은 sticky 코드를 사용하는 것이다.

 

 

 

2-1] CSS 작업

아래 코드를 CSS에 삽입한다.

 

.tt_article_useless_p_margin h2 {
	position: sticky;
	top: 0px;
}

 

 

 

2-2] 작업 결과

아래와 같이 스크롤을 내릴 때 헤딩이 화면 상단에 고정된다.

 

02-sticky

 

 

 

그런데 이 방법의 단점은 모든 헤딩이 고정되기 때문에 (헤딩끼리 밀어내는 것이 아니기 때문에) 헤딩이 길 경우 아래와 같은 문제가 발생한다.

 

03-sticky-over

 

 

 

 

 

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] 작업 결과

아래와 같이 스크롤을 내릴 때 헤딩끼리 밀어내기 하면서 화면 상단에 고정된다.

 

04-fixed

 

 

 

 

 

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] 작업 결과

아래와 같이 헤딩이 화면 상단에 고정될 때 헤딩이 화면 전체 영역으로 확장된다.

 

05-fixed-width

 

 

 

 

 

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가 모두 화면 상단에 고정된다.

 

06-fixed-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] 작업 결과

아래와 같이 스크롤을 내릴 때 헤딩이 화면 영역 안으로 들어오면서 슬라이딩으로 등장한다.

 

07-heading-sliding

 

 

 

 

 

728x90
반응형