내가 추구하는 건강한 CSS 설계 원칙을 정리해 보았다. 실수 투성이었던 과거의 나에게 이런 편지를 보내고 싶다.
common.css는 보통 모든 페이지에서 참조하는 스타일로 수많은 코드가 쓰레기다. 지금 당장 common.css 파일이 몇 줄인 지, 그리고 얼마나 많은 코드를 낭비하는지 확인해 보길 바란다.
크롬 개발자 도구에서 명령어 실행 창(Cmd-Shift-P)을 열어 Show Coverage 탭을 활성화한 다음 유효한 CSS 코드가 몇 줄이나 되는지 점검해 보자. 그래프에서 붉은색으로 표시한 영역이 낭비한 CSS 코드 비율이고 친절하게 몇 ‘%’ 수준인지 알려준다.
사용하지 않는 코드를 참조하지 않는 것이 중요하다. common.css 파일에 코드가 늘어날수록 이틀 뒤 너의 한숨도 늘어날 것이다. 외부 스타일(external style)을 사용하는 것은 더 이상 미덕이 아니다. 내장 스타일(embeded style)로 책임 범위를 명확하게 줄이는 것이 성능과 유지 보수에 도움이 된다.
A 페이지와 B 페이지가 같은 스타일을 공유할 때 C 페이지에서는 절대로 참조하지 않도록 한다. 차라리 중복 코드가 발생하더라도 내장 스타일을 쓰는 게 낫다.
이런 규칙을 적용하면 네가 작성한 CSS 코드의 책임 범위가 명확해진다. 유지 보수할 때 사이드 이펙트를 줄일 수 있고 생명 주기가 끝난 코드를 안전하게 제거할 수 있다.
reset.css 따위의 전역 스타일로 공용 선택자 또는 타입 선택자를 초기화하는 경우가 있다. 꼭 필요한 경우는 극히 제한적인데 과도한 초기화가 문제다. 다시 덮어쓸 수 있는 속성은 선언하지 말고 이미 선언한 속성은 다시 덮어쓰지 말자.
공용 선택자 ‘*‘를 초기화하면 이 선택자에 적용한 속성은 언젠가 틀림없이 덮어쓰게 된다. 한두 번 정도가 아니라 덮어쓰기를 계속해서 반복할 것이다. 반복해서 덮어써야 하는 속성을 초기화하는 게 맞는지 고민해 볼 필요가 있다. 타입 선택자를 초기화하는 것도 마찬가지다.
개발자 도구에서 Styles 탭을 열어 얼마나 많은 코드에 취소선이 그어져 있는지 확인해 보자. 취소선은 기존에 작성한 코드가 더 이상 유효하지 않은 상태라는 것을 의미한다.
취소한 코드는 쓰레기다. 쓰레기 밭에서 뭔가 발견하려고 애쓰던 수많은 시간이 안타깝다. 덮어쓰기를 안 할 수는 없다. 극도로 지양하는 것이 좋다.
누군가 내 선택자를 덮어쓸 수 있다는 것을 염두하면 내가 작성하는 선택자의 명시도(specificity)는 가능한 낮게 유지해야 한다. 기본으로 10점을 유지하고 최대 20점을 초과하지 않도록 한다. 명시도 점수 계산기.
선택자를 보면 내용을 이해할 수 있는 시멘틱한 표현이 좋다. 스타일을 연상하는 이름은 피하는 게 좋다. 스타일은 언제든 변경의 여지가 있으니까.
id 선택자는 JavaScript에서 DOM을 선택하는 용도로 사용하고, class 선택자는 스타일을 위해 사용한다.
// DO NOT
// 명시도 30점, 표현, 각진 붉은 스타일로 바꾸면 선택자 이름도 바꿔야
.box.round.blue { ... }
// DO THIS
// 명시도 10점, 내용, 다른 스타일로 변경해도 선택자 이름은 유효하다
.news__item { ... }
이런 고민을 하다가 만난 것이 BEM(Block-Element-Modifier)이다. BEM은 선택자를 의미 있는 이름으로 작성하도록 하고 명시도를 낮추는 데 효과적이었다.
처음 CSS를 접했을 때 한 번 선언한 코드를 여러 곳에서 다시 조립하여 재사용할 수 있는 것이 축복처럼 느껴졌다. 하지만 이제는 쓰레기 더미에서 진주알을 찾는 기분이다. CSS 코드의 책임 범위를 명확하게 축소하자. 유효한 코드보다 쓰레기와 취소선이 더 많은 디스토피아를 만들지 않기를 바란다.
마지막으로 오랜 경험에 따라 꼭 필요했던 속성을 초기화하고 선택자 명시도를 ‘0점’으로 만든 나만의 reset.css를 공유해 본다. 나는 매 프로젝트마다 이 코드에서 점진적으로 불필요한 코드를 제거하고 필요한 코드를 몇 줄 추가하는 편이다.