📁JavaScript

JS로 CSS를 직접 제어하면 결국 남는 건 유지보수 지옥이다

📝 가장 많이 빠지는 함정

프론트엔드 개발을 하다 보면 자바스크립트로 CSS를 직접 제어하는 상황을 자주 만나게 됩니다.

element.style.display = 'none'
element.style.color = 'red'
JavaScript

위와 같은 코드는 당장 원하는 결과를 빠르게 만들어 줍니다.

이런 방식은 프로젝트가 커질수록 구조를 서서히 무너뜨리는 원인이 되는 경우가 많습니다.
이 글에서는 왜 JS로 CSS를 직접 제어하면 문제가 생기는지 그리고 어떤 방식이 더 나은 선택인지를 개발자 관점에서 정리해 보겠습니다.

📝 왜 JS로 CSS를 직접 제어하게 될까🤔

CSS보다 JS가 더 “확실해 보이기 때문”
눈앞의 UI 문제를 빠르게 해결해야 하기 때문
상태 개념 없이도 바로 결과가 나오기 때문

이 선택은 시간이 지날수록 여러 구조적 문제를 드러냅니다.

📢 문제 1. 스타일과 로직의 경계가 무너진다

JS에서 스타일 값을 직접 수정하기 시작하면 코드의 역할이 불분명해집니다.

button.style.backgroundColor = '#3182f6';
button.style.marginTop = '12px';
JavaScript

이 코드에는 구조적인 문제가 숨어 있습니다.

스타일 규칙이 JS 안에 흩어짐
같은 UI 규칙을 재사용하기 어려워짐

이상적인 프론트엔드 구조에서 이런걸 담당합니다.

하지만 JS가 스타일을 직접 제어하면 이 역할 분리가 깨집니다.

📢 문제 2. 상태(state)가 코드에 드러나지 않는다

JS로 CSS를 직접 제어할 때 가장 많이 놓치는 부분이 상태 관리입니다.

if (menu.style.display === 'none') {
  menu.style.display = 'block';
} else {
  menu.style.display = 'none';
}
JavaScript

이 코드는 동작은 하지만
메뉴가 왜 block 상태에 있는지, 현재 어떤 상태인지가 명확히 드러나지 않습니다.

상태가 코드에 표현되지 않으면:

조건 분기가 늘어날수록 로직이 복잡해지고
예외 상황이 증가하며
디버깅과 유지보수가 어려워집니다.

📢 문제 3. 반응형과 CSS 규칙과 충돌한다

JS로 inline style을 제어하면
CSS의 핵심 기능인 미디어 쿼리와 쉽게 충돌합니다.

예를 들어

데스크톱에서는 보이게
모바일에서는 숨기게

이런 규칙을 CSS로 정의해 두었더라도
JS가 스타일 값을 직접 덮어쓰면
반응형 규칙은 무력화됩니다.

결과적으로

화면 크기별 조건문 증가
JS가 CSS 역할까지 떠안음
전체 구조 복잡도 상승

📢 문제 4. 유지보수 시 의도가 보이지 않는다

시간이 지나 코드를 다시 보게 되면 이런 질문이 생깁니다.

왜 여기서 이 색을 바꾸는 걸까?
이 display 변경은 어떤 상태를 의미할까?
CSS에서 고쳐야 할까, JS에서 고쳐야 할까?

이 질문에 바로 답할 수 없다면
이미 구조는 흔들리고 있는 상태입니다.

📝 JS는 상태만, CSS는 표현만

실무에서 가장 안정적인 패턴은 명확합니다.

JS는 상태를 클래스 형태로 표현
CSS는 그 상태를 해석해 스타일을 적용
menu.classList.add('is-open');
menu.classList.remove('is-open');
JavaScript
.menu {
  display: none;
}

.menu.is-open {
  display: block;
}
CSS

이 구조의 장점은 분명합니다.

상태가 코드에 드러남
스타일 규칙이 CSS로 집중됨
반응형, 다크모드 대응 쉬움
구조 이해와 유지보수 비용 감소

📝 판단 기준

JS로 CSS를 직접 제어하려는 순간,
아래 질문을 스스로에게 던져보는 것이 좋습니다.

이것은 스타일 문제인가, 상태 문제인가?
값 자체를 바꾸고 싶은가, 상태를 표현하고 싶은가?
CSS만 봐도 UI 규칙이 이해될까?

이 질문에 명확히 답하기 어렵다면
JS에서 스타일을 직접 제어하는 선택은 다시 고민해볼 필요가 있습니다.