AI-POT 2급 자격증 공부(N샷프롬프팅_CoT_자기성찰_멀티모달)
시험 99% 출제! N샷·CoT·멀티모달 프롬프트 완전 정리
AI-POT 시험에서 출제율이 가장 높은, 무려 99% 이상 나온다는 핵심 챕터입니다. 예시를 몇 개 주느냐로 갈리는 N샷, 단계적으로 사고하게 만드는 CoT, 그리고 텍스트와 이미지를 함께 넣는 멀티모달까지 — 이 셋만 확실히 잡으면 점수가 보입니다. 이 글에서 비유와 함께 한 번에 정리해드릴게요.
① 예시 개수가 전부 — N샷 프롬프팅
N샷 프롬프팅은 AI에게 예시(샷, shot)를 들어주며 시키는 기법입니다. 핵심은 단 하나, 예시를 몇 개 주느냐예요.
| 기법 | 예시 개수 | 한마디로 |
|---|---|---|
| 제로샷(Zero-shot) | 0개 | 예시 없이 그냥 시킴 |
| 원샷(One-shot) | 1개 | 예시 딱 하나 |
| 퓨샷(Few-shot) | 2개 이상 | 예시 여러 개 |
🔑 헷갈릴 게 없어요. 0개=제로샷, 1개=원샷, 2개 이상=퓨샷. 개수만 세면 끝.
② 단계적으로 생각하게 하라 — CoT와 자기 성찰
CoT(Chain of Thought, 체인 오브 소트) 는 복잡한 문제를 단계적으로 나눠 풀게 하는 방식입니다. 그런데 이게 세 가지 유형으로 나뉘고, 비유로 외우면 절대 안 잊어버려요.
| 유형 | 방식 | 비유 |
|---|---|---|
| 일반 CoT | 정해진 순서대로, 수정 없이 쭉 진행 | 🍳 요리 레시피 |
| 자기 성찰형 CoT | 스스로 의심하고 반론하며 재검토 | 🩺 의사 선생님 |
| 피드백 루프 설계 | 수행을 관찰해 즉각 피드백, 반복 개선 | 🏋️ 운동 코치 |
비유로 직관을 잡아볼까요. 요리 레시피는 적힌 순서대로 따라가면 끝(일반 CoT). 의사는 "정말 이 진단이 맞나?" 스스로 의심하며 재검토하죠(자기 성찰형). 운동 코치는 내 자세를 보고 그때그때 교정해줍니다(피드백 루프).
🔑 구분 한 줄: 단일 방향 순서=CoT / 의심·자기평가=자기 성찰형 / 반복 개선=피드백 루프
③ 텍스트 + 이미지 + 음성 — 멀티모달 프롬프트
멀티모달 프롬프트는 둘 이상의 데이터 유형(텍스트·이미지·음성 등)을 합쳐서 AI에 넣는 겁니다. 여기서 중요한 함정 하나!
⚠️ 텍스트만, 또는 이미지만 넣으면 멀티모달이 아닙니다. 반드시 2종 이상을 결합해야 멀티모달이에요.
멀티모달의 장점은 분명합니다. 정보를 여러 형태로 주니 AI가 딴소리(환각)를 덜 하고, 정확도가 높아집니다.
🔑 핵심: 2개 이상 데이터 유형 결합 = 멀티모달 (단일 유형은 멀티모달 X)
한 걸음 더 — 1급 향상 기법
조금 더 깊이 들어가면, 위 기법들을 한 단계 끌어올린 버전이 나옵니다.
| 기법 | 핵심 | 언제 쓰나 |
|---|---|---|
| 대조적 N샷 | 좋은 예 + 나쁜 예를 함께 제공 | AI 혼동을 줄이고 부적절한 응답을 걸러낼 때 |
| 다중 관점 CoT | 여러 페르소나(재무 분석가·마케터·운영 관리자 등)로 한 문제를 다각도 해석 | 복잡한 정책 문제, 갑론을박 상황 |
💡 대조적 N샷은 '이건 맞고 저건 틀려'를 같이 보여주는 것, 다중 관점 CoT는 '여러 전문가를 한 테이블에 앉히는 것'이라 생각하면 쉬워요.
마치며
오늘 내용을 한 문장으로 정리하면 이렇습니다.
예시 개수로 나뉘는 N샷(0·1·2+), 단계적 사고의 CoT 3유형(레시피·의사·코치), 그리고 2종 이상 결합의 멀티모달 — 이 셋이 출제율 99%의 핵심이다.
출제율이 가장 높은 만큼, 비유까지 함께 외워두면 어떤 변형 문제가 나와도 흔들리지 않습니다. N샷·CoT·멀티모달, 이 세 단어만큼은 꼭 챙기세요!
📇 핵심만 빠르게 — 한 줄 암기 카드
- N샷: 예시 0개=제로샷 / 1개=원샷 / 2개+=퓨샷
- CoT 3유형: 레시피=일반 CoT(단일방향) / 의사=자기 성찰형(의심) / 코치=피드백 루프(반복)
- 멀티모달 = 텍스트+이미지+음성 등 2종 이상 결합 (단일 유형은 ❌)
- 멀티모달 효과 = 딴소리 억제 + 정확도↑
- 1급: 대조적 N샷(긍정+부정 예시) / 다중 관점 CoT(여러 페르소나·정책·갑론을박)
이 글이 도움이 되셨다면 공감과 댓글 부탁드려요. AI 개념 정리 시리즈, 다음 편에서 계속됩니다! 🙌
'공부 > AI-POT' 카테고리의 다른 글
| AI-POT 2급 자격증 공부(프롬프트확장프로그램_연계_위험성) (0) | 2026.06.12 |
|---|---|
| AI-POT 2급 자격증 공부(생성형AI활용_구분기호_코드식별_이미지생성_시각화_정리) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(프롬프트전략_목적별구조_역설계) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(프롬프트작성원칙_파라미터_Temperature_TopP) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(AI자연어처리_NLP_프롬프트구조화_패턴) (0) | 2026.06.12 |
AI-POT 2급 자격증 공부(프롬프트전략_목적별구조_역설계)
결과물만 보고 프롬프트를 알아낸다? 프롬프트 전략과 역설계 완전 정리
멋진 AI 그림을 보고 "이건 대체 뭐라고 입력한 거지?" 궁금했던 적 있으신가요? 놀랍게도 결과물만 보고 원래 프롬프트를 거꾸로 알아내는 '역설계' 기술이 있습니다. 이 글에서는 프롬프트 5대 구성요소를 실전에서 적용하는 법, 이미지 AI별 작성 규칙, 그리고 역설계와 1급 고급 전략까지 한 번에 정리합니다.
프롬프트 5대 구성요소, 실전에서 이렇게 쓴다
좋은 프롬프트의 뼈대는 다섯 가지입니다 — 지시·맥락·입력·출력 형식·제약 조건. 이걸 자기소개서 작성 예시로 보면 감이 확 옵니다.
| 구성 요소 | 실전 적용 | 예시 |
|---|---|---|
| 지시 | 행동 동사로 명령 | "분석하라", "요약할 것" |
| 맥락 | 배경 정보 제공 | 대기업 공채, 컴공 4학년 |
| 입력 | 수행할 작업·데이터 | 자기소개서 문항 |
| 출력 형식 | 결과의 구조 지정 | 상황 소개 → 해결 과정 → 결과·배운 점 |
| 제약 조건 | 지킬 규칙 설정 | 과장 표현 지양, 500자 초과 금지 |
시험에서는 "이 문장이 어떤 구성요소냐"를 자주 묻습니다. 두 가지 패턴만 기억하세요.
🔑 "중립적 관점", "개인정보 미포함", "전문용어 최소화", "500단어 초과 금지" → 전부 제약 조건.
🔑 "친절한 수학 튜터"에 출력 형식·답변 수준·제한사항은 다 있는데 풀어야 할 수학 문제(데이터)가 없다 → 입력이 누락된 것.
텍스트 vs 이미지 — 작성 규칙이 다르다
흥미로운 차이가 있습니다. 텍스트 프롬프트는 용도에 따라 요소를 유연하게 바꿔도 되지만, 이미지 프롬프트는 작성 순서와 파라미터가 어느 정도 고정돼 있어요. 도구별로 정리하면:
| 도구 | 파라미터 작성법 |
|---|---|
| Midjourney | 프롬프트 뒤에 하이픈 두 개(--) + 호출 기호와 값 사이 띄어쓰기 |
| Stable Diffusion | 메인 프롬프트 + 네거티브 프롬프트 칸 + 파라미터는 선택 버튼 |
| DALL-E (달리) | 파라미터 없이 프롬프트 칸에 묘사 |
🔑 기출: 하이픈 두 개(
--)로 파라미터를 쓰는 방식은 미드저니의 특징입니다.
거꾸로 추적하기 — 프롬프트 역설계
이제 이번 글의 하이라이트입니다. 프롬프트 역설계(Reverse Engineering) 는 완성된 결과물(텍스트·이미지)을 보고, 그걸 만든 프롬프트를 거꾸로 추론하는 기술이에요.
왜 쓸까요? 두 가지 목적이 있습니다.
- ✍️ 효과적인 프롬프트 작성법 학습 — 잘 나온 결과물을 분해해 노하우를 배움
- 🛡️ 규칙 위반/우회 탐지 — AI 서비스의 정책을 어기거나 우회한 프롬프트를 잡아냄
역설계를 잘하려면 원하는 방식을 명확히 요청하고, 첫 결과가 별로여도 계속 개선을 요구해야 합니다. 유형별 방법은:
| 유형 | 방법 |
|---|---|
| 텍스트 역설계 | 분석 대상을 명확히 + 하이픈 세 개(---)로 문단을 끊어 입력 |
| 이미지 역설계 | 이미지와 함께 어떤 생성 AI 기반인지(미드저니/SD) 명시 |
🔑 텍스트는
---세 개로 구분, 이미지는 기반 AI를 반드시 명시하는 게 포인트.
한 걸음 더 — 1급 고급 전략 3종
1급에서는 이름부터 묵직한 세 가지 전략이 나옵니다.
| 전략 | 한마디로 |
|---|---|
| 내쉬 균형 프롬프트 | 모든 이해관계자의 전략을 고려해 모두 만족할 중간 지점 찾기 |
| 베이지안 프롬프트 | 불확실한 데이터를 모델링해 예측하고 불확실성 해소 |
| 거꾸로 프롬프트 | 원하는 답을 먼저 제시하고, 거기 도달할 질문을 역으로 생성 |
💡 헷갈리지 않게: 모두 만족 중간점 = 내쉬 균형 / 불확실성 예측 = 베이지안 / 답 먼저 = 거꾸로.
마치며
오늘 내용을 한 문장으로 정리하면 이렇습니다.
프롬프트는 5대 구성요소로 설계하고, 이미지는 도구별 규칙을 따르며, 잘 만든 결과물은 역설계로 분해해 배운다.
좋은 프롬프트를 '쓰는' 능력만큼, 잘 된 결과물을 '뜯어보는' 역설계 능력도 실력입니다. 두 방향을 모두 익히면 AI를 다루는 시야가 확 넓어져요.
📇 핵심만 빠르게 — 한 줄 암기 카드
- 5요소: 지시(행동 동사)·맥락(배경)·입력(데이터)·출력 형식(구조)·제약 조건(규칙)
- "중립·개인정보X·500자 금지" → 제약 조건 / 풀 문제·데이터 없음 → 입력 누락
- 이미지: 미드저니(
--) / 스테이블 디퓨전(메인+네거티브+버튼) / DALL-E(묘사만) - 역설계 = 결과물→프롬프트 역추론 (학습 + 규칙 위반 탐지)
- 텍스트 역설계 =
---3개 / 이미지 역설계 = 기반 AI 명시 - 1급: 내쉬균형(중간점)·베이지안(불확실성)·거꾸로(답 먼저)
이 글이 도움이 되셨다면 공감과 댓글 부탁드려요. AI 개념 정리 시리즈, 다음 편에서 계속됩니다! 🙌
'공부 > AI-POT' 카테고리의 다른 글
| AI-POT 2급 자격증 공부(생성형AI활용_구분기호_코드식별_이미지생성_시각화_정리) (0) | 2026.06.12 |
|---|---|
| AI-POT 2급 자격증 공부(N샷프롬프팅_CoT_자기성찰_멀티모달) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(프롬프트작성원칙_파라미터_Temperature_TopP) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(AI자연어처리_NLP_프롬프트구조화_패턴) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(프롬프트엔지니어링_개념_구성요소_역사) (0) | 2026.06.12 |
AI-POT 2급 자격증 공부(프롬프트작성원칙_파라미터_Temperature_TopP)
AI의 '성격'은 숫자로 정한다 — 프롬프트 원칙과 Temperature·Top P 완전 정리
똑같은 질문인데 어떤 AI는 딱딱한 보고서처럼, 어떤 AI는 시인처럼 답합니다. 이 '성격' 차이가 사실은 Temperature와 Top P라는 숫자 두 개로 조절된다는 걸 아셨나요? 이 글에서는 좋은 프롬프트의 2대 원칙부터, 출제율 1위 파라미터 Temperature·Top P, 이미지 AI별 파라미터 입력법, 그리고 1급 고급 기법까지 한 번에 정리합니다.
좋은 프롬프트의 두 기둥 — 명확성과 구체성
화려한 기법보다 먼저 잡아야 할 기본이 있습니다. 바로 명확성과 구체성이에요.
① 명확성 — 모호함을 없애고 직접적으로 지시하는 겁니다. AI가 딴생각을 못 하게요. 한 가지 팁은 같은 개념엔 같은 용어를 쓰는 것. '고객'과 '유저'를 섞어 쓰면 AI가 헷갈립니다.
② 구체성 — 상세한 정보, 특히 정량적 표현이 핵심입니다. "짧게 써줘" 대신 "300자 이내로", "몇 개 정도" 대신 "5개"처럼 숫자와 단위로 측정 가능하게 제시하세요.
여기에 맥락 정보(배경·역할 설정)와 제약 조건(분량·개수·용어 제한)까지 더하면 금상첨화입니다.
💡 예를 들어 AI 비서에게 *"내일 미팅 준비해 줘"* 라고만 하면? 무슨 미팅인지, 뭘 준비할지 맥락 정보가 부족해 제대로 응답하기 어렵습니다.
출제율 1위 — Temperature와 Top P
여기가 이번 글의 핵심이자 시험 단골입니다. 텍스트 생성 AI에서 가장 중요한 두 파라미터예요.
| 파라미터 | 무엇을 조절? | 값이 높으면 | 값이 낮으면 |
|---|---|---|---|
| Temperature | 결과의 다양성·창의성 | 창의적·무작위적 | 일관적·안정적 |
| Top P | 단어 선택의 다양성 | 다양한 단어 | 예측 가능·안정적 |
외우는 법은 의외로 간단합니다.
🔑 둘 다 "높으면 창의적·다양, 낮으면 일관·안정" 입니다.
차이는 대상이에요 — Temperature는 결과 전체의 창의성, Top P는 단어 선택의 다양성.
그림 AI는 어떻게 파라미터를 넣을까?
이미지 생성 AI는 도구마다 파라미터 입력 방식이 꽤 다릅니다.
| 도구 | 파라미터 넣는 법 | 원치 않는 요소 빼기 |
|---|---|---|
| Midjourney | 프롬프트 뒤에 하이픈 두 개(--) |
--no 로 제외 |
| Stable Diffusion | 선택 버튼이 많음 | 네거티브 프롬프트 칸이 따로 있음 |
| DALL-E | 정해진 양식 없이 프롬프트에 직접 서술 | 문장으로 직접 풀어씀 |
🔑 기출 포인트: 미드저니는
--와--no, 스테이블 디퓨전은 네거티브 프롬프트 칸, DALL-E는 스타일·퀄리티·사이즈를 그냥 문장으로 적습니다.
한 걸음 더 — 1급 고급 기법
① 전략적 모호성 (의도적 모호함) — 보통은 명확하게 쓰라고 하지만, 1급에선 반대 기법도 나옵니다. 일부러 모호하게 써서 AI에게 창의적 자유를 주는 거죠. 핵심은 *"중간까지는 구체적, 이후엔 자율권"* 입니다.
표현 예시: *"
하되", "식으로"* — "전체 분위기는 차분하게 하되, 색감은 자유롭게 표현해줘"
② 파라미터로 성격 만들기 — 가장 흥미로운 부분입니다. Temperature와 Top P를 조합하면 AI에게 인격을 부여할 수 있어요.
| 설정 | 탄생하는 인격 |
|---|---|
| 낮은 Temperature + 낮은 Top P | 정확하고 예측 가능한 교육자·전문가 |
| 높은 Temperature + 높은 Top P | 자유분방한 창의적 작가 |
마치며
오늘 내용을 한 문장으로 정리하면 이렇습니다.
좋은 프롬프트의 기본은 명확성·구체성이고, AI의 창의성은 Temperature(결과)와 Top P(단어)로 조절한다. 둘 다 높이면 작가가, 낮추면 전문가가 된다.
프롬프트의 '말'을 다듬는 것이 절반이라면, 나머지 절반은 이 파라미터라는 손잡이를 돌리는 감각입니다. 두 개를 함께 익히면 AI를 내 의도대로 부리는 힘이 생깁니다.
📇 핵심만 빠르게 — 한 줄 암기 카드
- 좋은 프롬프트 2원칙: 명확성(모호 제거·동일 용어) + 구체성(정량적·숫자·단위)
- 배경·역할 → 맥락 정보 / 분량·개수 제한 → 제약 조건
- "내일 미팅 준비해줘" → 맥락 정보 부족
- Temperature = 결과 창의성 / Top P = 단어 다양성 → 둘 다 ↑창의·다양, ↓일관·안정
- 이미지: 미드저니(
--,--no) / SD(네거티브 프롬프트 칸) / DALL-E(자유 서술) - 일부러 모호("
하되","식으로") → 전략적 모호성 - 낮은 Temp+TopP → 전문가·교육자 / 높은 Temp+TopP → 작가
이 글이 도움이 되셨다면 공감과 댓글 부탁드려요. AI 개념 정리 시리즈, 다음 편에서 계속됩니다! 🙌
'공부 > AI-POT' 카테고리의 다른 글
| AI-POT 2급 자격증 공부(N샷프롬프팅_CoT_자기성찰_멀티모달) (0) | 2026.06.12 |
|---|---|
| AI-POT 2급 자격증 공부(프롬프트전략_목적별구조_역설계) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(AI자연어처리_NLP_프롬프트구조화_패턴) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(프롬프트엔지니어링_개념_구성요소_역사) (0) | 2026.06.12 |
| AI-POT 2급 자격증 공부(ChatGPT_구조_프롬프트처리_RLHF) (0) | 2026.06.12 |
블로그 꽃단장 파일 공유(w/claude)
skin-share.html 코드 가이드
— 파일 구조, 동작 원리, 커스터마이징 지점
tistory-skin-guide.md(제작 과정/이슈 해결기)와 함께 보는 코드 레퍼런스입니다.
이 문서는 "코드가 어떻게 생겼고, 어디를 고치면 무엇이 바뀌는가"에 집중합니다.
1. 파일 한 장 요약
skin-share.html 하나에 HTML + CSS + JS가 전부 들어있습니다. (약 1,300줄)
skin-share.html
├─ <head>
│ ├─ Google Fonts 로드 (Nanum Pen Script / Noto Serif KR / Noto Sans KR)
│ └─ <style> ······································ 약 10~590행
│ ├─ ① 디자인 토큰 (:root / body.dk)
│ ├─ ② 베이스 & 레이아웃 (헤더, 그리드, 사이드바)
│ ├─ ③ 글 카드 + 미리보기 클램프
│ ├─ ④ 페이지네이션
│ ├─ ⑤ 사이드바 위젯 (검색/카테고리/태그/RSS)
│ ├─ ⑥ Tistory 자동 삽입 요소 덮어쓰기 (!important 지대)
│ ├─ ⑦ 첨부파일 재스타일 + 확장자 칩
│ └─ ⑧ 상세 페이지 모드 (body.detail …)
├─ <body class="tt-body-index">
│ ├─ 헤더 (블로그명, 카테고리 내비, 다크모드 토글)
│ ├─ 메인 컬럼: <s_list> 글 목록 + <s_article_rep> 글 상세
│ │ └─ 카드 내부에 태그/명함/댓글 등 "상세 전용 요소" 동봉
│ ├─ 사이드바: 검색 / 카테고리 / 태그 클라우드 / RSS
│ └─ 푸터
└─ <script> ········································ 약 724~1330행
├─ (a) localStorage 캐시 정리
├─ (b) 첨부파일 DOM 재구성
├─ (c) 페이지네이션 재구성
├─ (d) 페이지 타입 감지 + 상세 모드 토글 ← 가장 큰 블록
│ ├─ 사이드바 카테고리 재구성
│ ├─ 글 태그 정리(멀티 태그 분리) + 폴백
│ ├─ author-box / atags 중복 제거
│ └─ 사이드바 태그 클라우드 정리
├─ (e) 다크모드 토글 + 복원
└─ (f) 스크롤 진행 바
2. 디자인 토큰 — 색/스타일을 바꾸려면 여기만
모든 색상은 CSS 변수로 선언되어 있고, 라이트/다크가 같은 변수명을 공유합니다.
변수만 바꾸면 전체 테마가 일괄 변경됩니다.
:root { /* 라이트 모드 */
--ac:#B07828; /* 액센트 (브론즈) — 링크 호버, 현재 페이지, 칩 */
--ac-a:rgba(176,120,40,.13); /* 액센트 연한 배경 */
--bg:#F8F6F3; --nav:#EFE9E2; /* 페이지 배경 / 내비 배경 */
--tx:#1A1814; --sub:#4A4238; --mt:#6E665E; /* 본문 / 보조 / 메타 텍스트 */
--bd:#E4DDD5; --tb:#EDE7DF; --cb:#FFFEFB; /* 보더 / 태그 배경 / 카드 배경 */
}
body.dk { /* 다크 모드 — 같은 변수를 어두운 값으로 재정의 */ }
| 바꾸고 싶은 것 | 수정 위치 |
|---|---|
| 포인트 컬러 | --ac, --ac-a (라이트/다크 각각) |
| 전체 배경 톤 | --bg, --cb, --bd |
| 본문 폰트 | body{font-family:...} + <head>의 Google Fonts 링크 |
| 로고 손글씨체 | Nanum Pen Script 사용처 (헤더 로고, 아바타 이니셜) |
규칙: 색을 하드코딩하지 말 것. 새 요소를 추가할 때도 var(--ac) 등 변수를 쓰면
다크모드가 공짜로 따라옵니다. (예외: 확장자 칩 색상은 파일 형식 고유색이라 하드코딩)
3. 한 장 두 모드: 목록 ↔ 상세
이 스킨의 핵심 트릭입니다. 카드(.card) 마크업은 하나인데,
body 클래스에 따라 두 가지 모습으로 렌더됩니다.
목록 모드 (기본) 상세 모드 (body.detail)
┌─ .card ──────────┐ .card → 보더/배경 제거, 아티클화
│ 제목 (.pt) │ .pt → 28px 대제목
│ 미리보기 2줄 (.pe) │ .pe → 클램프 해제, 전문 표시
│ 태그 (compact) │ .rep-extra → 표시 (명함, 댓글 등)
└──────────────────┘ + "← 목록으로" 링크 JS 삽입
동작 순서:
<body class="tt-body-index">→ Tistory가tt-body-page(상세) 등으로 치환- JS(d블록)가 클래스를 읽어
body.detail클래스를 추가/생략 - CSS의
body.detail ...섹션(⑧)이 카드를 아티클로 변환
// 정식 판별 우선, 변수 미처리 시 휴리스틱 폴백
if (/tt-body-/.test(bodyCls)) {
isDetail = /tt-body-page(\s|$)/.test(bodyCls);
} else {
isDetail = cards.length === 1;
}
상세 전용 요소 패턴: 명함·댓글처럼 상세에서만 보일 요소는 카드 안에class="rep-extra"로 넣어두고 기본 display:none, body.detail에서만 표시합니다.
새 상세 전용 요소를 추가할 때 이 클래스만 붙이면 됩니다.
4. 미리보기 클램프 — .pe의 방어 설계
목록의 본문 미리보기는 Tistory가 어떤 HTML이든 넣을 수 있는 영역입니다.
그래서 3중 방어를 합니다:
.pe{ max-height:53px !important; overflow:hidden !important;
display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.pe img,.pe figure,.pe video,.pe iframe,.pe table{ display:none !important; } /* 미디어 제거 */
.pe *{ font-size:14px !important; margin:0 !important; ... } /* 평탄화 */
상세 모드에서는 이걸 전부 해제합니다 (body.detail .pe{max-height:none !important;...}).
미리보기 줄 수를 바꾸려면 -webkit-line-clamp 값과 max-height(줄수 × line-height)를 함께 수정하세요.
5. !important 지대 — Tistory 덮어쓰기 레이어
⑥~⑦ 섹션은 거의 모든 선언에 !important가 붙어 있습니다. 버그가 아니라 의도입니다.
Tistory가 런타임에 자체 CSS와 인라인 스타일을 주입하기 때문에, 이를 이기려면 필요합니다.
주요 덮어쓰기 대상:
| 대상 | 처리 |
|---|---|
| 공감/구독/프로필 위젯 | display:none (스킨 자체 디자인으로 대체) |
another_category (카테고리의 다른 글) |
테이블 → 이전 글/다음 글 2칸 카드 그리드로 변환. tr:first-child::before{content:'← 이전 글'} 같은 가상요소로 라벨링 |
| 첨부파일 블록 | 기본 아이콘 숨기고 확장자 칩 + DOWNLOAD 텍스트 링크로 재구성 |
| 본문 표 | border-collapse + 변수 기반 보더로 통일 |
| 댓글 React 앱 | [class*="tt_"] 셀렉터로 폰트/색만 덮어씀 (DOM은 건드리지 않음) |
여기를 수정할 때 주의: 셀렉터가 div[class*="another_category"]처럼 부분 일치인 이유는
Tistory가 클래스명을 바꾸는 경우가 있어서입니다. 정확한 클래스명에 의존하지 마세요.
6. JS 모듈별 가이드
전부 IIFE(즉시실행함수)로 독립되어 있어 하나가 죽어도 나머지는 동작합니다.
중요 로직은 try/catch로 감싸고, 실패 시 console.warn('[hyos] ...')을 남깁니다.
(b) 첨부파일 재구성
.tt_attachment등에서 파일명/크기/링크를 파싱- 확장자를 추출해
<span class="file-ext-ico" data-ext="pdf">칩 삽입 - 새 확장자 색을 추가하려면: CSS의
.file-ext-ico[data-ext="..."]규칙 한 줄 추가
(c) 페이지네이션 재구성
- 서버가 렌더한 번호 링크에서
현재 페이지(href 없는 항목),전체 페이지,URL 패턴을 수집 ‹ 1 … 4 5 6 … 23 ›형태로 다시 그림- 윈도우 크기 변경:
var win = 2(현재 ±2) 값 수정 - 변수 미치환(
[##_잔존) 시 페이지네이션 전체 숨김 — raw 텍스트 노출 방지
(d) 페이지 타입 감지 블록 (메인)
가장 큰 블록. 내부 순서가 중요합니다:
1. body_id로 상세/목록 판별 → body.detail 토글
2. 상세면: "← 목록으로" 링크 삽입
3. 사이드바 카테고리 재구성 ← try/catch (실패해도 원본 노출)
4. 글 태그 정리: '#' 멀티 태그 분리 → 칩 재구성
└ 폴백 사다리: s_tag_label 결과 → 본문 /tag/ 링크 → 페이지 JSON
→ 모바일 페이지(/m/...) fetch → 전부 실패 시 숨김
5. author-box / atags 중복 제거
6. 사이드바 태그 클라우드 정리 (멀티 태그 분리 동일 적용)
태그 폴백은 0ms / 800ms / 2500ms 3회 재시도합니다 — Tistory React가
비동기로 마운트되기 때문. 이 패턴은 React 영역을 읽는 모든 코드에 필요합니다.
(e) 다크모드
document.getElementById('b').classList.toggle('dk', dk); // className= 금지!
localStorage.setItem('hyos-dark', dk ? '1' : '0');
classList.toggle을 쓰는 이유:className =으로 덮어쓰면 Tistory의tt-body-page클래스가 날아가 레이아웃이 깨집니다 (실제 겪은 버그)- 새로고침 시 localStorage에서 복원
(f) 스크롤 진행 바
헤더 위 2px 바(#prog)의 너비를 스크롤 비율로 갱신. 필요 없으면#prog 요소와 마지막 scroll 리스너만 지우면 됩니다.
7. 공통 패턴 (새 기능 추가 시 따라할 것)
패턴 1 — 미치환 변수 가드
if (/\[##_/.test(el.innerHTML)) { /* 변수 미처리 → 폴백 or 숨김 */ }
모든 동적 영역의 첫 줄. raw 텍스트가 사용자에게 노출되는 것을 막습니다.
패턴 2 — 폴백 사다리
정식 치환자 → DOM 정규화 → 대체 소스(RSS, /m/ 페이지) → 깔끔하게 숨김
어느 단계에서 성공하든 결과 UI는 동일하게. 전부 실패하면 빈 껍데기 대신 섹션 자체를 숨깁니다.
패턴 3 — 비동기 재시도
if (!run()) {
setTimeout(function(){ run(); }, 800);
setTimeout(function(){ run(); }, 2500);
}
Tistory React 마운트를 기다리는 표준 방법. MutationObserver보다 단순하고 충분합니다.
패턴 4 — 네임스페이스
- CSS 클래스:
hyos-file,hyos-cmt처럼 접두사 사용 (Tistory 클래스와 충돌 방지) - 콘솔 로그:
console.log('[hyos] ...')— 필터링 가능 - localStorage 키:
hyos-dark,hyosTagCache_v1— 버전 붙여서 마이그레이션 대비
8. 커스터마이징 빠른 레시피
| 하고 싶은 것 | 방법 |
|---|---|
| 포인트 컬러 변경 | :root와 body.dk의 --ac, --ac-a 수정 |
| 미리보기 3줄로 | .pe의 -webkit-line-clamp:3 + max-height 재계산 |
| 사이드바 위젯 순서 변경 | <aside class="sb"> 안의 .ss 블록 순서 바꾸기 |
| 사이드바 위젯 제거 | 해당 .ss 블록 삭제 (JS는 요소 없으면 자동 skip) |
| 페이지네이션 윈도우 | JS의 var win = 2 수정 |
| 확장자 칩 색 추가 | .file-ext-ico[data-ext="확장자"]{background:...} 추가 |
| 다크모드 기본값 ON | (e) 복원 IIFE에서 localStorage 체크 앞에 dk=true;... 분기 추가 |
| 명함(author-box) 수정 | class="author-box" 블록 — 이름/소개/이니셜은 플레이스홀더 검색 |
| 댓글 영역 스타일 | #hyos-cmt 하위 CSS — DOM 구조는 Tistory React 소유, CSS만 건드릴 것 |
9. 수정 시 지켜야 할 것 (안 깨뜨리는 법)
<s_...>블록 구조를 옮기지 마세요. 치환자는 자기 블록 안에서만 동작합니다.
특히<s_tag_label>,<s_random_tags>(반복 단위 주의),<s_paging_rep>.는href="..."로 감싸면 안 됩니다. 속성 전체를 출력하는 변수입니다.- body 클래스는
classList로만 조작하세요. - React 마운트 포인트(
data-tistory-react-app) 내부 DOM을 JS로 수정하지 마세요.
리렌더 시 덮어써집니다. CSS 덮어쓰기만 허용. - JS 추가는 새 IIFE로. 기존 블록에 끼워 넣지 말고 독립 블록 + try/catch로 추가하면
실패해도 다른 기능이 살아 있습니다. - 수정 후에는 5종 페이지를 모두 확인: 홈 / 글 상세 / 카테고리 / 태그 검색 / 마지막 페이지(글 1개).
깃허브로 따로 관리를 하고있지 않아서 파일로 전달 드리니 참고바랍니다~
'IT' 카테고리의 다른 글
| 티스토리 블로그 꽃단장 가이드 및 이슈 노트(w/ Claude Design) (0) | 2026.06.12 |
|---|---|
| [Claude] Claude 엄청남, 엄청남, 엄청남, 평서문 (2) | 2026.04.30 |
티스토리 블로그 꽃단장 가이드 및 이슈 노트(w/ Claude Design)
Tistory 커스텀 스킨 제작 가이드
— 디자인 시안부터 실서비스 적용까지, 삽질 기록과 해결법
대상 독자: HTML/CSS/JS 기본기가 있는 1~3년차 개발자.
이 문서는 실제로 블로그(hyos.blog) 스킨을 디자인 시안부터 만들어 Tistory에 적용하면서
겪은 이슈와 해결 과정을 정리한 것입니다.
0. 전체 흐름 요약
1) HTML/CSS로 디자인 시안 제작 (홈 + 상세 2종)
2) 시안을 Tistory 스킨(skin.html) 구조로 변환
3) 치환자(템플릿 변수) 적용 → 업로드 → 깨지는 부분 디버깅 (대부분의 시간이 여기)
4) JS 폴백/정규화 레이어 추가로 마무리핵심 교훈을 먼저 말하면:
- Tistory 치환자는 문서대로 동작하지 않는 경우가 많다. 변수가 빈값으로 치환되거나, 아예 치환되지 않고
텍스트가 그대로 남기도 한다. - 그래서 최종 구조는 "치환자 우선 + JS 폴백"의 2중 구조가 됐다. 서버가 제대로 렌더하면 그대로 쓰고, 실패하면 JS가 DOM/RSS/모바일 페이지에서 데이터를 긁어와 채운다.
- Tistory가 주입하는 기본 스타일과 싸우려면
!important가 생각보다 자주 필요하다.
1. 스킨 파일 구조
Tistory 스킨은 최소 두 파일이다.
| 파일 | 역할 |
|---|---|
skin.html |
페이지 전체 구조. 치환자 포함 |
style.css |
스타일 (skin.html 안에 <style>로 넣어도 동작함) |
우리는 관리 편의상 skin.html 하나에 CSS/JS를 전부 인라인으로 넣었다.
업로드는 블로그 관리 → 꾸미기 → 스킨 편집 → html 편집에서 한다.
페이지 1장으로 모든 화면을 처리한다
Tistory는 홈/카테고리/태그/검색/글상세가 전부 같은 skin.html로 렌더링된다.<s_list>(목록)와 <s_article_rep>(글)을 같은 파일에 두고, 현재 페이지 타입에 따라
Tistory가 알아서 한쪽만 채워준다. 우리는 여기에 더해 JS로 상세/목록 레이아웃을 토글했다.
2. 치환자(템플릿 변수) 기초
치환자는 형태이고, 반복/조건 블록은 <s_블록명>...</s_블록명> 태그다.
<s_list> <!-- 목록 페이지에서만 렌더 -->
<s_list_rep> <!-- 글 개수만큼 반복 -->
<a href=""></a>
</s_list_rep>
</s_list>
중요한 규칙: 변수는 지정된 블록 안에서만 치환된다.
블록 밖에 변수를 쓰면 치환되지 않고 raw 텍스트가 그대로 노출된다. (아래 이슈 4 참고)
3. 겪은 이슈와 해결법
이슈 1 — 홈 목록에서 글 전문이 다 보임
증상: 홈 화면 카드에 미리보기 2줄이 아니라 본문 전체가 출력됨.
원인: 목록에서 본문 변수를 그대로 쓰면 전문이 들어온다.
해결: CSS line-clamp로 강제 제한. Tistory가 어떤 HTML을 넣어주든 2줄로 자른다.
.preview{
display:-webkit-box;
-webkit-line-clamp:2;
-webkit-box-orient:vertical;
overflow:hidden;
}
/* 본문 안의 어떤 태그가 와도 스타일 통일 */
.preview *{
font-size:14px !important;
margin:0 !important;
background:none !important;
}
포인트: 미리보기 안에는 <p>, <h2>, <figure> 등 무엇이든 들어올 수 있으므로* 셀렉터 + !important로 전부 평탄화해야 한다.
이슈 2 — 상세 페이지와 목록 페이지 구분
증상: "마지막 페이지에 글이 1개만 있으면 상세 페이지로 보임."
원인(우리 실수): 처음에 "카드가 1개면 상세"라는 휴리스틱으로 판별했다.
목록 페이지의 마지막 페이지에 글이 1개 남자 상세로 오인.
해결: Tistory 공식 변수 tt-body-index를 사용한다.
<body id="b" class="tt-body-index">
렌더되면 tt-body-index(홈), tt-body-page(글 상세), tt-body-category,tt-body-tag, tt-body-search 같은 클래스가 붙는다.
var bodyCls = document.body.className || '';
var isDetail;
if (/tt-body-/.test(bodyCls)) {
isDetail = /tt-body-page(\s|$)/.test(bodyCls); // 정식 판별
} else {
isDetail = cards.length === 1; // 변수 미처리 시 폴백
}
교훈: 휴리스틱을 쓰더라도 항상 "정식 방법 우선, 휴리스틱은 폴백"으로 겹쳐라.
이슈 3 — 다크모드 토글이 페이지 판별을 깨뜨림
증상: 다크모드를 켜면 상세 페이지 레이아웃이 풀림.
원인: 토글 코드가 body.className = 'dk'로 클래스를 통째로 덮어써서tt-body-page 클래스가 날아갔다.
해결: classList.toggle 사용.
// BAD
document.body.className = dk ? 'dk' : '';
// GOOD
document.body.classList.toggle('dk', dk);
사소해 보이지만 실제로 한참 헤맨 버그. 남의 플랫폼 위에서는 body/root 요소의
클래스를 절대 통째로 덮어쓰지 말 것.
이슈 4 — 태그가 절대 안 나옴 (최대 난관)
증상: 글 하단 태그 영역이 항상 빈값. , 등
어떤 변수를 써도 안 나옴.
원인이 3겹이었다:
블록 누락: 태그 변수는 반드시
<s_tag_label>블록 안에 있어야 치환된다.<s_tag_label> <div class="atags"></div> </s_tag_label>블록 없이 변수만 쓰면 영원히 빈값/raw 텍스트.
길이 필터에 걸림: JS 정리 로직에서 "50자 넘는 태그는 쓰레기값"으로 버렸는데,
실제로는 사용자가 태그 입력란에NLP #자연어처리 #프롬프트엔지니어링 #...처럼
#로 이어 적은 80자짜리 태그 1개가 등록되어 있었다. 통째로 필터에 걸려 0개가 됨.입력 방식 자체의 문제: Tistory 에디터 하단 태그 입력란에서는
태그 하나 입력 후 엔터로 구분해야 개별 태그가 된다.#로 이어 적으면 전부 한 덩어리 태그로 저장되고,/tag/검색도 덩어리째로만 잡힌다.
해결:
// '#'로 이어 적은 멀티 태그를 분리해서 개별 칩으로 표시
var add = function (t) {
t = (t || '').trim();
if (!t) return;
if (t.indexOf('#') > 0 || /^#.+#/.test(t)) {
t.split('#').forEach(function (p) {
p = p.trim();
if (p && !seen[p] && p.length <= 80) { seen[p] = 1; tagSet.push(p); }
});
return;
}
t = t.replace(/^#/, '');
if (!t || seen[t] || t.length > 80) return;
seen[t] = 1; tagSet.push(t);
};
교훈:
- 변수가 안 나오면 먼저 해당 변수의 필수 블록(
<s_...>)을 확인하라. - "데이터가 안 온다"고 단정하기 전에 내 필터 로직이 데이터를 버리고 있는지 의심하라.
- 디버깅할 땐 기존(잘 동작하는) 스킨의 렌더 결과 HTML을 직접 까보는 게 가장 빠르다.
개발자도구에서 동작하는 스킨의 태그 영역 HTML을 복사해 비교하면서 원인을 찾았다.
이슈 5 — 사이드바 태그 클라우드의 반복 단위
증상: <s_random_tags>로 감싼 TAGS 섹션이 뜨긴 뜨는데 구조가 깨지거나,
섹션 제목까지 태그 개수만큼 복제됨.
원인: <s_random_tags>는 반복 블록이다. 섹션 전체를 감싸면 섹션이 통째로 반복된다.
<!-- BAD: 섹션 전체가 태그 수만큼 반복됨 -->
<s_random_tags>
<div class="ss">
<h3>TAGS</h3>
<div class="tc"><a href=""></a></div>
</div>
</s_random_tags>
<!-- GOOD: 반복시킬 <a> 하나만 감싼다 -->
<div class="ss">
<h3>TAGS</h3>
<div class="tc">
<s_random_tags><a href=""></a></s_random_tags>
</div>
</div>
교훈: <s_..._rep> 류 블록을 만나면 "이 블록의 반복 단위가 무엇인가"를 먼저 정하라.
이슈 6 — 페이지네이션 링크가 href= 로 깨짐
증상: 페이지 번호를 누르면 https://blog.com/href= 같은 이상한 URL로 이동.
원인: 는 URL이 아니라 href="..." 속성 전체를 출력하는
변수다. href="[##_...]"처럼 감싸면 href="href=..."로 깨진다.
<!-- BAD -->
<a href=""></a>
<!-- GOOD -->
<a ></a>
교훈: 치환자마다 출력 형식(URL만 vs 속성 전체)이 다르다. 깨지면
렌더된 HTML을 개발자도구로 열어 변수가 뭘 뱉었는지 확인하는 게 정답.
이슈 7 — ‹ › 버튼이 없는 페이지로 이동
증상: 이전/다음 화살표를 누르면 "없는 페이지" 에러.
해결: 서버 변수에 의존하지 않고 JS로 페이지네이션을 재구성했다.
- 서버가 렌더한 번호 링크에서 현재 페이지(href 없는 번호), 전체 페이지 수, URL 패턴을 수집
‹ 1 … 4 5 6 … 23 ›형태로 다시 그림 (현재 ±2 윈도우 + 첫/끝 + 줄임표)- 첫 페이지의
‹, 마지막 페이지의›는pointer-events:none+ 흐림 처리
var win = 2, lo = Math.max(1, cur - win), hi = Math.min(total, cur + win);
var pages = [1];
if (lo > 2) pages.push('…');
for (var i = lo; i <= hi; i++) { if (i > 1 && i < total) pages.push(i); }
if (hi < total - 1) pages.push('…');
if (total > 1) pages.push(total);
이슈 8 — 댓글 수가 항상 0
증상: 목록 카드의 댓글 카운트 변수가 4종
(rp_cnt, comment_count, comment_cnt, reply_cnt) 전부 빈값/0.
해결: RSS 폴백. Tistory RSS(/rss)의 각 <item>에는 댓글 수가 들어있다.
fetch('/rss').then(r => r.text()).then(xml => {
var doc = new DOMParser().parseFromString(xml, 'text/xml');
doc.querySelectorAll('item').forEach(it => {
var link = it.querySelector('link').textContent;
var slash = it.getElementsByTagNameNS(
'http://purl.org/rss/1.0/modules/slash/', 'comments')[0];
var cnt = slash ? parseInt(slash.textContent, 10) : 0;
// link의 pathname으로 카드와 매칭해서 카운트 표시
});
});
같은 도메인이라 CORS 문제 없음. 단, RSS 공개 설정(블로그 관리 → 콘텐츠)이 켜져 있어야 하고
RSS에 노출되는 글 수 제한이 있다는 점은 감안할 것.
이슈 9 — 신형 댓글/프로필은 React 마운트 방식
증상: 댓글 영역이 아예 비어 있음. 직접 <form>을 그려도 동작 안 함.
원인: 최신 Tistory는 댓글·프로필 카드를 React 앱으로 클라이언트에서 마운트한다.
스킨은 마운트 포인트만 제공해야 한다.
<div data-tistory-react-app="Comment"></div>
이 div를 두면 Tistory 스크립트가 댓글 목록+입력창을 통째로 렌더해준다.
디자인 통일은 마운트된 DOM을 CSS로 덮는 방식으로 처리:
#hyos-cmt [class*="tt_"] { font-family:'Noto Sans KR',sans-serif !important; }
주의: React가 비동기로 마운트되므로, 관련 DOM을 읽는 JS는setTimeout 재시도(예: 0ms / 800ms / 2500ms)를 걸어야 한다.
이슈 10 — 첨부파일 영역 깨짐 + 확장자 아이콘
증상: <s_attachment> 영역이 Tistory 기본 스타일과 충돌해 깨짐.
해결:
- 파일명에서 확장자를 JS로 파싱해
data-ext속성 부여 - 확장자별 색상 칩(PDF=빨강, HWP=파랑, XLS=초록...)을 CSS로 표시
- Tistory가 background를 덮어써서 칩 색상에
!important필수였다
.file-ext-ico[data-ext="pdf"]{ background:#c0392b !important; color:#fff !important; }
.file-ext-ico[data-ext="hwp"]{ background:#2e6ab0 !important; color:#fff !important; }
이슈 11 — 본문 표(table)가 안 보임
증상: 에디터에서 만든 표가 본문에서 투명/무스타일로 렌더됨.
원인: 에디터는 <table data-ke-align="..."> 형태로 저장하는데, 스킨 CSS에
table 스타일이 전혀 없었고 리셋 CSS가 보더를 다 지워버렸다.
해결: 본문 영역(.pe) 한정으로 table 스타일을 명시.
.pe table{border-collapse:collapse;width:100%;margin:20px 0;}
.pe th,.pe td{border:1px solid var(--bd);padding:10px 14px;text-align:left;}
.pe thead th{background:var(--tb);font-weight:600;}
교훈: 본문에는 에디터가 생성하는 모든 마크업(표, 인용, 코드, 이미지 캡션...)이
들어올 수 있다. 스킨 만들 때 에디터로 온갖 요소를 넣은 테스트 글을 하나 만들어두면
디버깅이 훨씬 빨라진다.
4. 최종 아키텍처: "치환자 우선 + JS 폴백"
여러 이슈를 거치며 정착한 패턴. 모든 동적 데이터에 동일하게 적용했다.
┌─ 1순위: Tistory 치환자가 정상 렌더 → 그대로 사용
├─ 2순위: DOM에 남은 흔적(미처리 변수, 링크 등)을 JS로 정규화
├─ 3순위: 다른 소스에서 페치 (RSS, 모바일 페이지 /m/...)
└─ 실패: 해당 섹션을 깔끔하게 숨김 (빈 껍데기 노출 금지)체크 코드 패턴:
var raw = el.innerHTML || '';
if (/\[##_/.test(raw)) {
// 치환자가 처리되지 않음 → 폴백 또는 숨김
}
[##_ 문자열이 남아있으면 변수 미처리라는 뜻이다. 이 체크 하나로
"raw 변수 텍스트가 사용자에게 노출되는" 최악의 상황을 방지할 수 있다.
5. 디버깅 워크플로우 (시간 아끼는 법)
- 개발자도구 → Elements가 진실이다. 스킨 코드가 아니라 렌더된 결과를 봐라.
변수가 뭘로 치환됐는지, 빈값인지, raw로 남았는지 바로 보인다. console.log를 스킨 JS에 심어라. 우리는[hyos]접두사로 통일해서[hyos] 태그 추출 결과: []처럼 각 폴백 단계의 결과를 찍었다.- 잘 동작하는 다른 스킨과 비교하라. 같은 블로그에 기본 스킨을 잠깐 적용해보고
해당 영역의 렌더 HTML을 복사해두면, 내 스킨에서 뭐가 다른지 즉시 비교된다. - 테스트용 글을 만들어라. 표, 코드블록, 이미지, 첨부파일, 태그 여러 개,
댓글 있는 글 — 전부 들어간 글 하나면 회귀 테스트가 된다. - 스킨 저장 후 강력 새로고침(Ctrl+Shift+R). Tistory는 캐시가 꽤 끈질기다.
6. 치환자 빠른 참조 (이번에 실제로 쓴 것들)
| 치환자 / 블록 | 용도 | 함정 |
|---|---|---|
tt-body-index |
페이지 타입 (tt-body-page 등) |
body class에 넣고 classList로만 조작 |
<s_list> / <s_list_rep> |
글 목록 / 반복 | 반복 단위에 주의 |
<s_article_rep> |
글 상세 | |
<s_tag_label> + |
글 태그 | 블록 필수. 변수 단독으론 절대 안 나옴 |
<s_random_tags> + |
사이드바 태그 클라우드 | 반복 블록임 — <a> 하나만 감싸기 |
|
페이지 링크 | href= 포함 속성 전체 출력. href="..."로 감싸면 깨짐 |
<s_attachment> |
첨부파일 | Tistory 기본 스타일과 충돌 → !important |
data-tistory-react-app="Comment" |
댓글 (신형) | React 비동기 마운트. JS 재시도 필요 |
/rss |
댓글 수 폴백 | slash:comments 네임스페이스 파싱 |
/m/{글번호} |
모바일 렌더 페이지 | 태그 등 데이터 폴백 소스로 활용 가능 |
7. 마지막 조언
- 처음부터 Tistory 구조에 맞춰 디자인하지 마라. 순수 HTML 시안을 먼저 완성하고
(디자인 의사결정이 자유로움), 그 다음 스킨으로 이식하는 편이 결과물이 훨씬 좋다. - 이식은 한 섹션씩. 헤더 → 목록 → 상세 → 사이드바 → 댓글 순으로 하나씩 옮기고
매번 업로드해서 확인해라. 한 번에 다 옮기면 어디서 깨졌는지 못 찾는다. - 플랫폼과 싸우지 말고 폴백을 쌓아라. 치환자가 안 먹는 건 흔한 일이다.
"정식 방법 → 정규화 → 대체 소스 → 숨김"의 사다리를 만들면 어떤 상황에도 깨지지 않는다.
행운을 빕니다. 🛠
'IT' 카테고리의 다른 글
| 블로그 꽃단장 파일 공유(w/claude) (1) | 2026.06.12 |
|---|---|
| [Claude] Claude 엄청남, 엄청남, 엄청남, 평서문 (2) | 2026.04.30 |