본문 바로가기

IT/Tistory

[스킨 수정] 티스토리 자동 ToC 적용 및 설정 변경

ToC란?

ToC는 Table of Content의 약자로 우리나라 말로 하면 '목차'에 해당하는 단어라고 볼 수 있다.

ToC를 적용하기로 마음먹은 이유

필자가 맨 처음에 블로그를 만들고자 마음 먹었을 때 정했던 컨셉은 '초보자도 쉽게 이해할 수 있는 기술 블로그' 였다. 기술 블로그를 표방하고 있기 때문에 구조화된 내용이 필요하다고 생각했고, 글의 전체적인 구조를 한 눈에 볼 수 있으면 독자들이 이해하기 쉬울 것이라 판단했다.

이를 해결할 수 있는 것이 바로 ToC를 구성하는 것이었고, 검색을 통해 여러가지 방법들을 쉽게 찾을 수 있었기 때문에 ToC를 내 블로그에 적용하기로 마음먹었다.

ToC 적용 시 장점

ToC를 적용할 시 아래와 같은 장점이 있다. 따라서 본인의 수필 등을 적는 개인 블로그가 아닌 이상 ToC를 적용하는 것이 여러모로 유리하다고 생각한다.

  • 본문 구조 파악이 용이해짐(독자 이해도 상승)
  • 구글 SEO에 보다 유리함(검색을 통한 유입량 상승)
  • ToC 클릭을 통해 본문의 원하는 위치로 빠른 이동이 가능

어떠한 라이브러리를 적용할 것인가?

일단 검색을 통해 알아본 결과 티스토리에 적용 가능한 ToC는 크게 두 가지 정도 라이브러리가 있는 것으로 파악됐다. TocifyTocbot이 그것인데, 서로 큰 차이점이 있지는 않았다. 둘 다 손쉽게 ToC를 적용할 수 있었으며, 여러가지 Option들을 통해 커스터마이징도 가능했다. 취향에 맞게 선택하면 되는 문제라고 생각이 되었다.

내가 선택한 방법(tocbot)

내가 선택한 방법은 Tocbot이다. 일단 Tocbot의 기본 모양이 예쁘기도 하거니와 JQuery를 최대한 사용하지 않고 native DOM method만을 사용하여 만들었다고 하기에 해당 라이브러리를 선택했다. 독자들은 다른 방법을 선택해도 무방하나, 같은 라이브러리를 선택하는 것이 전체적으로 따라하는데 수월할 것이라고 생각한다.

ToC 적용 방법

ToC를 적용하기 위해서는 티스토리 스킨을 다소 수정해야 한다. HTML(JS), CSS 등을 복사/붙여넣기 하고 일부 수정이 필요한 사항들이 발생할 수 있다. 아래를 참고하면 어렵지 않게 성공할 수 있으리라 생각한다.

html 수정

  1. 블로그 관리 > 꾸미기 > 스킨 편집 > html편집으로 이동한다. 필자는 </head> tag 바로 전에 아래 내용을 붙여넣었다.

    <!-- ToC Start -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.css">
    <!-- Toc End -->
  1. ToC를 표시할 위치 지정

    ToC가 <body> 내 어디에 위치할지 결정하는 단계이다. 원하는 위치가 있다면 티스토리 스킨 구조를 파악하거나, 아니면 크롬 개발자도구에서 위치를 확인할 수도 있겠지만, 필자는 일단 많은 블로그들에서 하는 대로 본문 오른쪽에 ToC를 표시하기로 하였다. 이럴 경우 기본 스킨에서는 <s_permalink_article_rep> 태그의 바로 다음에 하기의 코드를 붙여넣으면 된다. <s_permalink_article_rep> 는 보호글과 보호글이 아닌 일반글 두 종류가 있으며, 이 경우 일반글에 위치하는 태그 바로 다음에 입력하면 된다.

    <div class='toc'></div>
  1. 실제 javascript 코드 작성

    Tocbot 사이트에서는 tocbot.init()만 작성되어 있으나, 이것만으로는 적용이 안되는 것으로 파악되어, 일반적으로 블로거들이 사용하는 코드(아래와 같음)를 </body>태그가 끝나기 전 바로 앞에 붙여넣었다.

    <!-- TOC Start -->
    <script>
      var content = document.querySelector('.entry-content')
      var headings = content.querySelectorAll('h1, h2, h3, h4, h5, h6, h7')
      var headingMap = {}
    
      Array.prototype.forEach.call(headings, function (heading) {
          var id = heading.id ? heading.id : heading.textContent.trim().toLowerCase()
                     .split(' ').join('-').replace(/[\!\@\#\$\%\^\&\*\(\):]/ig, '')
          headingMap[id] = !isNaN(headingMap[id]) ? ++headingMap[id] : 0
          if (headingMap[id]) {
            heading.id = id + '-' + headingMap[id]
          } else {
            heading.id = id
          }
        })
    
      tocbot.init({
        tocSelector: '.toc',
        contentSelector: '.entry-content',
        headingSelector:'h1, h2, h3',
        hasInnerContainers: false,
        collapseDepth: 3
      });
    
      $(document).ready(function(){
        $('.toc').addClass('toc-absolute');
    
        var toc_top = $('.toc').offset().top - 165;
        $(window).scroll(function() {
          if ($(this).scrollTop() >= toc_top) {
            $('.toc').addClass('toc-fixed');
            $('.toc').removeClass('toc-absolute');
          } else {
            $('.toc').addClass('toc-absolute');
            $('.toc').removeClass('toc-fixed');
          }
        });
      });
    
    </script>
    <!-- TOC End -->

css 수정

CSS 편집으로 들어가서 맨 아래에 하기 코드를 붙여넣는다.

/*-- ToC Start --*/
/* for desktop size */
.toc-absolute {
  position: absolute;
  margin-top:165px;
}
.toc-fixed {
  position: fixed;
  top: 165px;
}

.toc {
  right: calc((100% - 850px) / 2 - 300px);
  width: 250px;
  padding: 10px;
  box-sizing: border-box;
}

.toc-list {
  margin-top: 10px !important;
  font-size: 0.9em;
}

.toc > .toc-list li {
  margin-bottom: 10px;
}

.toc > .toc-list li:last-child {
  margin-bottom: 0;
}

.toc > .toc-list li a {
  text-decoration: none;
}

.is-active-link::before{background-color:#3792cb !important}

/* for mobile size */
@media only screen and (max-width: 1240px){
.toc-absolute {
  display:none;
}
}
/*-- ToC End --*/

상세 설정 방법

위에까지 적용했으면 실제 h1, h2, h3 태그를 사용한 모든 글의 오른쪽에 ToC가 적용된 것을 볼 수 있다. 필자는 위에서 세팅한 것에 더불어서 아래의 세팅을 더 해서 내 입맛에 맞는 ToC를 구성하였다. 추가적인 상세 설정 방법은 Tocbot:Options 에서 확인 가능하다.

  1. CollapseDepth 설정

    위의 자바스크립트 tocbot.init()내에 하기 코드를 추가한다. 기본 설정은 0이며, 이는 모든 제목 태그를 <h2> tag아래로 collapse(접어두기) 시킨다. 필자는 3을 설정하였으며, 6을 설정하면 모든 태그는 collapsed되지 않은 상태(열린 상태)로 보여지게 된다. (이미 위쪽 코드에 적용해 놓음.)

    collapseDepth: 3
  1. ToC Active Color 설정

    ToC가 Active되었을 때 색상이 초록색인 부분이 맘에 안들었다. 그래서 아래와 같은 코드를 추가하여 파란색으로 변경하였다. 원하는 색상을 #3797cb부분에 넣은다음에 CSS에 붙여넣으면 된다. 색상은 hex color code 등의 검색어로 확인할 수 있다.

    .is-active-link::before{background-color:#3792cb !important}
  1. 추가 세팅 적용 시 작성하겠다. 아직까지는 위 두 설정이 전부이다.

ToC 적용 결과

아래 그림과 같이 ToC가 잘 적용된 것을 볼 수 있다. 추가 문의사항은 댓글로 작성하여 주시기 바란다.

TOC02

추가 설정

위와 같이 ToC 설정 이후에 Fine Tuning을 위해 추가로 설정 적용한 것을 정리하고자 한다.

문서 로딩 완료 후 ToC 보이기

ToC 관련 태그가 <body> 태그 안에 있고, css에서 absolute로 position을 정해줬기 때문에, 문서 로딩 시에 본문 위에 ToC 영역이 잠깐 깜빡이처럼 나타났다가 사라지는 문제가 있었다. 이것을 해결해주기 위해서 아래와 같이 css에서 .toc 태그에 display: none설정한 뒤 모든 문서 로딩이 끝난 다음에 display:block 설정으로 바뀌도록 적용하였다.

아래 코드를 html에 붙여넣고,

<script type="text/javascript">
    $(document).ready(function() {
    var dispWidth = $(window).width();
    if(dispWidth > 1240){
      $('.toc').addClass('dispBlock');
    }
  });
</script>

아래 코드를 css에 붙여넣으면 된다.

.toc{
    display: none;
}
/*-- for basic class start --*/
.dispBlock {display:block;}
.dispNone {display:none;}
/*-- for basic class end --*/

화면 가로 길이에 따라 ToC 길이 조절하기

일반적으로 사용하고 있는 Full HD(가로 길이 1920px)일 경우에는 문제가 없었는데, 12인치 맥북 사이즈인 가로 길이 1280px 사이즈에서는 ToC 일부분이 잘려 보이는 현상이 있었다.

이를 해결하기 위해서 화면 가로 길이에 따라 ToC 가로 길이를 조절하도록 설정하였다.

.toc를 css에서 찾아서 아래와 같이 변경해주면 된다. 자세한 의미는 calc((100% - '본문너비') / 2 - 'ToC Width+3%')로 이해하면 된다.

.toc {
    display:none;
    right: calc((100% - 800px) / 2 - 17%);
  width: 14%;
    max-width: 300px;
  padding: 10px;
  box-sizing: border-box;
}