정적 리소스 관리
디렉토리 구조
static/
├── css/
│ └── guide.css # 개발 가이드 전용 스타일 (단일 파일)
├── js/
│ └── guide.js # 개발 가이드 JS (단일 파일)
└── images/ # 이미지 파일
└── {이미지파일}
정적 리소스 참조 방법
Thymeleaf에서 정적 리소스는 th:href, th:src에 @{...} 표현식을 사용한다.
<!-- CSS 참조 -->
<link rel="stylesheet" th:href="@{/css/guide.css}">
<!-- JS 참조 -->
<script th:src="@{/js/guide.js}"></script>
<!-- 이미지 참조 -->
<img th:src="@{/images/logo.png}" alt="로고">
디자인 토큰 (CSS 변수)
:root {
--sidebar-width: 260px;
--primary: #2563eb;
--primary-hover: #1d4ed8;
--text: #111827;
--text-secondary: #6b7280;
--bg: #ffffff;
--sidebar-bg: #f8fafc;
--border: #e2e8f0;
--code-bg: #f1f5f9;
--active-bg: #eff6ff;
--active-color: #2563eb;
--active-border: #2563eb;
--font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--mono: "JetBrains Mono", "Fira Code", Consolas, monospace;
}
하드코딩 금지
/* 잘못된 예 */
color: #111827;
background: #2563eb;
/* 올바른 예 */
color: var(--text);
background: var(--primary);
외부 CDN
현재 사용 중인 외부 CDN:
| 라이브러리 | 용도 | 비고 |
|---|---|---|
| highlight.js 11.9.0 | 코드 구문 강조 | cdnjs.cloudflare.com |
그 외 외부 CDN은 최소화한다.
<!-- highlight.js CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
외부 CDN 사용 시 SRI(Subresource Integrity) 해시 적용을 권장한다:
<link rel="stylesheet"
href="https://cdn.example.com/lib.css"
integrity="sha384-..."
crossorigin="anonymous">
SRI 해시 생성: srihash.org
CSS 작성 규칙
선택자 규칙
/* BEM-like 네이밍 */
.doc-article {} /* 블록 */
.doc-article-title {} /* 요소 */
.nav-link.active {} /* 상태 */
반응형 브레이크포인트
/* 태블릿/소형 화면 */
@media (max-width: 1100px) {
.toc-aside { display: none; }
}
/* 모바일 */
@media (max-width: 768px) {
.mobile-header { display: flex; }
.sidebar { transform: translateX(-100%); }
.main-content { margin-left: 0; }
}
JavaScript 작성 규칙
// eval() 절대 금지
// innerHTML 직접 할당 금지 → textContent 또는 DOM API 사용
// 잘못된 예
element.innerHTML = userInput;
// 올바른 예
element.textContent = userInput;
// DOMContentLoaded 이후 초기화
document.addEventListener('DOMContentLoaded', () => {
// 초기화 코드
});
// 이벤트 위임 패턴 (성능 최적화)
document.querySelector('.sidebar-nav').addEventListener('click', (e) => {
const link = e.target.closest('.nav-link');
if (!link) return;
// 처리
});
이미지 관리
이미지 파일은 static/images/ 디렉토리에 위치한다.
<!-- WebP 우선, PNG 폴백 -->
<picture>
<source srcset="/images/photo.webp" type="image/webp">
<img th:src="@{/images/photo.png}" alt="설명" loading="lazy">
</picture>