highlight.js 적용 및 CSS Specificity

nearworld·2023년 8월 8일
0

Second는 코드 블럭으로 사용할 것입니다.
FirstSecond에 있는 코드의 실행 결과를 보는 곳입니다.

이를 위해서 Second에 표현되는 코드들이 Syntax hightligting이 되어야 가독성이 올라갈 것이라 생각했습니다.

Code block 구현

1. highlight.js

찾아보던 중, highlight.js라는 라이브러리를 발견했습니다.

출처
https://highlightjs.org/

설치법

yarn add highlight.js

사용법

import hljs from 'highlight.js';

useEffect(() => {
	hljs.highlightAll();
}, [])

안내

hljs.highlightAll();

위 코드를 사용하면 모든 <pre>, <code> 태그에 syntax highlighting 을 적용합니다. 그리고 어떤 테마로 하이라이팅을 해줄지 설정해줘야합니다.

import "highlight.js/styles/github-dark-dimmed.css";

위 import문을 보면 highlight.js 라이브러리 폴더 내에 css 파일들이 테마별로 내장되어 있음을 알 수 있습니다. 위 스타일을 적용한 결과는 아래와 같이 보이게 됩니다.

2. marked

highlight.js 라이브러리를 통해 syntax highlighting을 적용할 발판을 마련했습니다.
이제는 스타일이 적용될 <pre>, <code> 를 jsx 부분에 삽입하여 코드를 작성할 차례입니다.

<code> 태그에 그냥 코드를 텍스트로 삽입할때 생기는 문제

<pre>
	<code>
    	const x = 10;
    </code>
</pre>

위 방식으로 코드를 그냥 텍스트로 삽입해보겠습니다.
highlight.js는 자동으로 해당 코드가 어떤 프로그래밍 언어로 작성됐는지 체크합니다.
내부 로직에 의해 판별된 언어로 하이라이팅을 적용합니다.
프로그램은 정상적으로 실행되고 하이라이팅된 코드가 브라우저에 보이게 됩니다.
하지만 테스트 해 본 결과, 어떤 코드인지 자동으로 식별하게 하면 제대로 언어를 판별하지 못하는 것으로 보입니다. 테스트 방식은 수동으로 언어를 지정해준 결과와 비교해보는 식이었습니다.

수동으로 언어를 지정해주는 방식으로 제가 발견한 것은 2가지가 있습니다.

  • class를 이용한 프로그래밍 언어 지정
  • marked를 이용한 string template 파싱

class 방식

<pre>
	<code className='language-typescript'>
    	const x = 10;
    </code>
</pre>

language-해당언어 방식으로 클래스 이름을 명명해주면 됩니다.

marked 방식

yarn add marked

marked 라는 라이브러리를 사용하는 방식이 있습니다.

출처
https://www.npmjs.com/package/marked

다운로드 수가 현재 글을 쓰는 시점으로 6,394,315 입니다.

사용 방식은 아래와 같습니다.

import { marked } from 'marked';

const code = `
	\`\`\`tsx
		const x = 10;
	\`\`\`
`

function App() {
  return (
  	<div dangerouslySetInnerHTML={{__html: marked(code)}}>	
    </div>
  )
}

위 2가지 방식 이외에도 react-lowlight 도 존재합니다.
사용법을 보니 highlight.js 를 기반으로 두고 있습니다.
그런데 위 방식들보다 복잡하다고 생각했습니다.

CSS specificity

반응형 레이아웃을 적용하려다가 발견한 이슈입니다.
display grid 를 쓰고 있고 이 그리드 레이아웃은 기본 3개 열을 가지고 있습니다.
그러나 브라우저 width가 786px 로 줄어들면 열을 1개로 만듭니다.
그리고 나머지 2개 열은 보이지 않게 만들려고 했습니다.

이를 위해 아래 코드를 적용했습니다.

// App.css

section {
	display: grid;
    grid-template-column: 1fr 1fr auto;
    min-height: 100vh;
}

@media (max-width) {
	section {
    	grid-template-column: 1fr 0 0;
    }
}

하지만 위 코드가 적용되지 않는 것을 발견했습니다.
처음에는 원인이 뭔지 집지 못하고 헤매다가 index.css에 적용되어 있던 reset css 코드가 영향을 미치고 있다는 생각이 들어 확인해봤습니다.

// idnex.css

section {
	display: block;
}

index.css에 있던 코드 때문에 grid 가 적용되지 않고 있던걸 확인했습니다.
저는 reset css를 이용해 디폴트로 적용된 display block 을 지우고 싶지 않았습니다.
이를 위해 찾아보던 중 CSS specificity 라는 개념을 발견하게 되었습니다.
사실 이 개념은 예전에 알고 있었으나 CSS-in-JS 라이브러리들을 사용해오면서 잊어버렸습니다. CSS specificity는 css 배울때 선택자를 어떤 방식으로 사용하는지에 따라 우선순위가 다르게 적용되는 것을 의미합니다.

그냥 태그 이름을 선택자로 사용하면 이 Specificity 값이 1이라 가장 낮습니다.
값이 높아질수록 우선순위가 올라갑니다.
그래서 저는 클래스 이름의 specificity 값을 확인하고 App.css에서 클래스를 적용하여 grid 레이아웃을 적용하기로 했습니다.
그러면 index.css에 있는 display block은 낮은 우선순위로 인해 무시되고 App.css의 클래스 이름으로 지정된 스타일이 선택되어 적용됩니다.

반응형 레이아웃 적용 결과는 위와 같습니다.

profile
깃허브: https://github.com/nearworld

0개의 댓글