티스토리 오디세이 스킨 스크롤 시 사이드바를 고정시키는 방법

워드프레스 정보를 제공하는 블로그 Avada 2025. 10. 23. 15:28 • 댓글:

이 티스토리 블로그에는 티스토리의 최신 공식 스킨인 오디세이(Odyssey) 스킨이 적용되어 있습니다. 스크롤 시 사이드바가 고정되지 않아서 자바스크립트를 사용하여 사이드바를 고정시켜 붙박이 사이드바로 만들어 보았습니다. 2년 전에도 JS를 사용하여 사이드바를 고정시켰지만 자연스럽게 고정되지 않아서 코드를 제거했다가, 최근 개선된 코드를 사용하여 이전보다 스무드하게 고정되도록 했습니다.

티스토리 오디세이 스킨: 스크롤 시 사이드바를 고정시키는 방법

티스토리 규제가 강화되면서 팝업 배너를 표시해도 제재를 받을 수 있고, 일부 사용자에 의하면 자동 목차를 표시해도 정지 조치를 내린다고 합니다. 그래서 이 블로그에서는 자동 목차를 제거하고 가능하면 순정 상태로 이용하려고 노력하고 있습니다.😄

사이드바의 경우 스크롤 시 고정하더라도 아직은 규제를 하지 않는 것으로 보입니다. 사이드바를 고정시킨 티스토리 블로그가 간혹 보여서 이 블로그에서도 스크롤 시 사이드바가 고정되도록 코드를 추가했습니다. (다만, 특정 요소가 콘텐츠를 가리도록 고정되는 경우에는 제재를 하는 것으로 보이므로, 요소를 고정할 때에는 주의가 필요합니다.)

스크롤 시 사이드바가 상단에 고정되도록 했습니다.

푸터 영역까지 스크롤하면 푸터 영역 위에서 사이드바 영역이 멈추도록 했습니다.

이 블로그와 같이 오디세이 스킨에서 사이드바 영역을 고정하고 싶은 경우 아래 코드로 테스트해 보시기 바랍니다.

자바스크립트 코드:

<script>
// =========================
// PC(≥1061px)에서만: gutter 유지 + 푸터 위에서 멈춤
// =========================
(function () {
	const TOP_OFFSET = 15;			// 상단 여백(px)
	const GUTTER = 0;				// area-main ↔ area-aside 간격(px)
	const ASIDE_MIN_WIDTH = 300;	// 안전 폭
	let main, areaMain, aside, placeholder, mql, footerEl;
	let startTop = 0;				// aside 고정 시작 지점(문서 Y)
	let footerTopY = Infinity;		// 푸터 상단(문서 Y)
	let ticking = false;
	let inited = false;
	function $(sel, root = document) { return root.querySelector(sel); }
	function createPlaceholder() {
		if (placeholder) return;
		placeholder = document.createElement('div');
		placeholder.className = 'area-aside-placeholder';
		aside.insertAdjacentElement('afterend', placeholder);
	}
	function measure() {
		const wasFixed = aside.classList.contains('is-fixed');
		if (wasFixed) unfix(); // why: 정확한 좌표 측정
		const rect = aside.getBoundingClientRect();
		startTop = window.scrollY + rect.top;
		// 푸터 상단 문서 Y
		if (footerEl) {
			const fRect = footerEl.getBoundingClientRect();
			footerTopY = window.scrollY + fRect.top;
		} else {
			footerTopY = Infinity;
		}
		if (wasFixed) onScroll(); // 상태 복원
	}
	function computeFixedLeft() {
		// why: 가운데 정렬 상황에서 gutter 유지
		if (main && areaMain) {
			const mainRect = main.getBoundingClientRect();
			const left = Math.round(mainRect.left + areaMain.offsetWidth + GUTTER);
			return left;
		}
		// 폴백
		return Math.round(aside.getBoundingClientRect().left);
	}
	function fix() {
		if (aside.classList.contains('is-fixed')) return;
		createPlaceholder();
		placeholder.style.height = `${aside.offsetHeight}px`;
		const left = computeFixedLeft();
		const width = Math.max(ASIDE_MIN_WIDTH, aside.offsetWidth);
		aside.classList.add('is-fixed', 'area-aside--using-placeholder');
		aside.style.top = `${TOP_OFFSET}px`;  // ← 수정: top 명시적 설정
		aside.style.left = `${left}px`;
		aside.style.width = `${width}px`;
		aside.style.transform = '';
	}
	function unfix() {
		if (!aside.classList.contains('is-fixed')) return;
		aside.classList.remove('is-fixed', 'area-aside--using-placeholder');
		aside.style.top = '';  // ← 수정: top 초기화
		aside.style.left = '';
		aside.style.width = '';
		aside.style.transform = '';
		if (placeholder) placeholder.style.height = '0px';
	}
	function clampToFooter() {
		// 고정 상태에서만 실행
		if (!aside.classList.contains('is-fixed')) return;
		const asideBottom = window.scrollY + TOP_OFFSET + aside.offsetHeight;
		const overflow = asideBottom - footerTopY;
		if (overflow > 0) {
			aside.style.transform = `translateY(${-overflow}px)`; // why: 푸터와 겹치지 않도록 위로 보정
		} else {
			aside.style.transform = '';
		}
	}
	function evaluate() {
		if (!mql.matches) return unfix();
		const shouldFix = window.scrollY + TOP_OFFSET >= startTop;
		if (shouldFix) {
			fix();
			clampToFooter();
		} else {
			unfix();
		}
	}
	function onScroll() {
		if (!inited) return;
		if (ticking) return;
		ticking = true;
		requestAnimationFrame(() => {
			evaluate();
			ticking = false;
		});
	}
	function onResize() {
		if (!inited) return;
		// 폭 변화 대응: 고정 중이면 즉시 left/width 갱신
		if (aside.classList.contains('is-fixed')) {
			aside.style.top = `${TOP_OFFSET}px`;  // ← 수정: resize 시에도 top 유지
			aside.style.left = `${computeFixedLeft()}px`;
			aside.style.width = `${Math.max(ASIDE_MIN_WIDTH, aside.offsetWidth)}px`;
		}
		measure();
		evaluate();
	}
	function init() {
		main = $('.wrap-right .main');
		areaMain = $('.area-main');
		aside = $('.area-aside');
		footerEl = $('#footer'); // ← 푸터 기준점
		if (!aside || !main) return;
		mql = window.matchMedia('(min-width: 1061px)');
		measure();
		evaluate();
		window.addEventListener('scroll', onScroll, { passive: true });
		window.addEventListener('resize', onResize);
		if (mql.addEventListener) mql.addEventListener('change', onResize);
		else mql.addListener(onResize);
		inited = true;
	}
	// 지연 초기화
	window.addEventListener('load', function () {
		setTimeout(init, 300);
	});
})();
</script>

CSS 코드:

/* =========================
 * PC 레이아웃 + sticky-fix 스타일
 * ========================= */
@media screen and (min-width: 1061px) {
  .wrap-right .main {
    width: 1200px;
    margin: 0 auto;           /* 가운데 정렬 */
    display: flex;
    gap: 0px;                /* 요구: area-main ↔ area-aside gutter 80px */
    justify-content: flex-start; /* gap을 쓰므로 space-between 불필요 */
    align-items: flex-start;
  }

  .area-main {
    flex: 0 0 640px;
    max-width: 640px;
  }

  .area-aside {
    flex: 0 0 300px;
    width: 300px;             /* 고정 폭 */
    align-self: flex-start;   /* 세로 늘어짐 방지 */
  }

  .area-aside.is-fixed {
    position: fixed;
    top: 5px;                 /* 상단 5px 여백 */
    z-index: 10;
  }

  /* 고정 중 레이아웃 보존용 placeholder */
  .area-aside-placeholder {
    display: none;
  }
  .area-aside--using-placeholder + .area-aside-placeholder {
    display: block;
  }
}

PC 해상도에서만 작동하도록 했습니다. 

티스토리는 티스토리 자체 광고 도입 이후에 애드센스의 앵커 광고와 모바일 전면 광고를 금지함에 따라 애드센스 광고 수익이 급감하는 사용자들이 많아졌습니다. 이로 인해 워드프레스나 블로그스팟 등으로 이동하는 사용자들이 증가하고 있습니다.

 

티스토리에서 워드프레스로 이사하기 (티스토리 백업 이용)

티스토리는 카카오 데이터센터 화재 이후 데이터 백업 기능이 추가되었습니다. 최근 티스토리에서 6월부터 티스토리 자체 광고 신설에 대한 공고를 올렸습니다. [안내] 6월부터 티스토리 자체

avada.tistory.com

참고

https://avada.tistory.com/3779

 

티스토리 소제목 꾸미기

티스토리는 HTML/CSS/JS 사용이 가능하기 때문에 소제목(H2, H3, H4, H5 태그)을 꾸밀 수 있습니다. 스킨 편집의 CSS 탭에서 기존 CSS 스타일을 수정하거나 새롭게 추가가 가능합니다. 저는 CSS 탭 하단에 C

avada.tistory.com

https://avada.tistory.com/3046

 

해외웹호스팅: 클라우드웨이즈 vs. 블루호스트 vs. 카페24 비교 (Cloudways vs. Bluehost vs. Cafe24)

저는 오랫동안 블루호스트(Bluehost)를 이용해 왔으며 2021년부터는 클라우드웨이즈(Cloudways) 웹호스팅 서비스도 함께 이용하고 있습니다. 현재 일부 중요하지 않는 블로그는 Bluehost에서 호스팅되고

avada.tistory.com