크롬익스텐션 만들어보기(2) - Tailwind Converter - 2

용인사는 개발자·2025년 11월 2일
post-thumbnail

인트로

전편에선 컨버터를 만들기 위한 세팅작업을 하다가 끝이났다. 크롬익스텐션 환경이 처음이기에 생각보다 오래걸렸고 예상치 못한 문제들이 많았다. UI적으로 짜잘한 수정도 있었지만(드래그,팝업 위치 업데이트 등) 이번글에선 엘리먼트의 css를 테일윈드로 변환하는 과정을 글로 정리하려고 한다

과정

1. 어떻게 변환 시킬것인가?

깊이 고민하진 않았다. 어차피 GPT(라고 쓰고 바이브코딩이라 부른다)에게 물어보면 되겠지 싶었다. 그런데 막상 물어보니, 생각보다 간단한 문제는 아니었다.

생각했던 과정

  • getComputedStyle을 통해 엘리먼트의 css를 가져온다
  • GPT가 테일윈드로 1:1변환 시키는방법을 알아서 찾는다(?)
  • 변환시킨 문자열을 편하게 볼수있게 UI를 꾸며준다
  • 완성(??)

단순하게 “DOM에서 스타일만 읽어와서 Tailwind로 변환하면 되잖아?”였지만,
막상 구현해보니 곳곳에서 예상치 못한 문제들이 튀어나왔다.

2. 문제와 해결

문제1

getComputedStyle이 너무많다..

getComputedStyle은 엘리먼트에 적용된 모든 스타일을 반환한다.
즉, 상속된 값, 브라우저 기본 스타일, 의미 없는 0px 값까지 전부 나온다.
처음엔 이걸 그대로 변환했는데 결과가 끔찍했다.
의미없는 css의 양이 너무 많았기에 핵심만 남기고 나머지는 전부 버려야 했다.

block w-[auto] h-[auto] color-[rgb(0_0_0)] margin-[0px] padding-[0px] border-[none] ...

해결방법

<div>, <button> 등 동일 태그의 기본값(getComputedStyle(document.createElement(tag)))과 비교
실제로 “차이 나는” 속성만 남기고, allowedProps 배열로 필요한 속성만 필터링하였다.

const allowedProps = [
  "display", "color", "background-color",
  "width", "height",
  "margin-top", "margin-right", "margin-bottom", "margin-left",
  "padding-top", "padding-right", "padding-bottom", "padding-left",
  "font-size", "font-weight",
  "box-shadow", "border-radius", "border-width", "border-color"
];

문제2

Tailwind 변환의 까다로움

getComputedStyle로 가져온 CSS를 그대로 Tailwind로 바꾸는 건 생각보다 간단하지 않았다.
우선 브라우저가 반환하는 스타일 값은 너무 다양하고,
Tailwind의 설정값(theme.spacing, fontSize, borderRadius 등)과 완벽히 일치하지 않기 때문이다. 실제 테일윈드처럼 깔끔하게 변환시킬순 없었고 어느정도는 타협해서 변환시키기로 했다.

해결방법

우선 Tailwind 설정을 전부 JSON 형태로 덤프(tailwind.json) 떠서
하나의 매핑 기준 데이터셋으로 만들었다.
이 파일에는 "4px" → "p-1", "1rem" → "text-base" 같은 식으로
Tailwind 클래스와 실제 CSS 값이 모두 담겨 있다.

변환 과정은 단순했다.
우선 각 CSS 속성값을 숫자로 변환해서 tailwind.json 안에서 가장 가까운 값(근사값) 을 찾고,
일치하는 키가 있으면 그걸 Tailwind 클래스로 매핑했다.
예를 들어 font-size: 15.9px → text-base, margin-top: 32px → mt-8 식으로 변환된다.
근사값조차 없을 경우엔 [prop:value] 형태로 fallback 처리했다.

하지만 색상(color, background-color) 계열은 예외였다.
CSS에는 rgb(), hsl(), oklab(), color(display-p3 ...) 같은 다양한 포맷이 섞여 있어서
Tailwind의 팔레트(red-500, blue-600)과 정확히 맞출 수가 없었다.
그래서 색상은 아예 매칭을 포기하고,
그냥 [background-color:#e90000], [color:rgb(233_0_0)] 같은 브라켓 형식으로 그대로 변환했다.

결과만 정리하자면,

색상은 완벽 매칭 불가능 → [prop:value] 형식으로 처리
나머지 속성은 Tailwind JSON 기준으로 근사 매칭 → 없으면 [prop:value] fallback

많은 노가다가 들어가고 완벽하진 않지만 만족스럽게 해결이 되었다.

3. 결과물

Tailwind 변환 로직은 모두 완성됐다.
이제 남은 건 단순히 그 결과를 UI로 보여주는 일뿐이었다.
변환에 사용된 함수들은 따로 useConverter 훅으로 분리해 관리했고,
content 스크립트에서 사용자가 변환된 결과를 바로 확인할 수 있도록 렌더링했다.

상단에는 변환된 Tailwind 문자열 전체를 한눈에 볼 수 있도록 표시하고,
원하는 경우 쉽게 복사할 수 있는 기능을 추가했다.
하단에는 변환된 클래스들을 Typography, Color, Box Model, Layout, Effects, Other
여섯 가지 카테고리로 구분해, 각 항목을 버튼 컴포넌트 형태로 렌더링했다.
각 버튼을 클릭하면 해당 클래스를 즉시 클립보드로 복사할 수 있도록 구현했다.

마치며

만드는 과정은 꽤 재미있었다.
비록 완벽하진 않지만, 처음부터 그걸 목표로 한 건 아니었다.
“완벽함보다는 도전” — 그 마음으로 시작했고,
지금은 일단 시도했다는 사실만으로도 충분히 의미가 있었다.
앞으로는 조금씩 다듬고, 천천히 리팩토링해가면 된다.

profile
용인에 거주하는 개발자입니다. 사이드프로젝트의 진행사항, 오류해결, 배운것들을 적습니다

0개의 댓글