하지만 웹 개발자 관점에서 볼 때 누군가는 속도가 왕이라고 주장할 것이다. 나는 점차 그 입장을 지지하게 되었다. 최근 몇 년 간 경험이 풍부한 프런트엔드 엔지니어들이 성능 모범 사례를 활용하여 사용자 경험을 개선할 수 있는 방법을 제시해왔다.
스매싱매거진 기사 더 읽어보기
많은 개발자가 (좋은 이유에서) 자바스크립트 성능과 다른 분야에 주로 초점을 맞추는 동안 불행히도 CSS는 이 분야에서 다소 간과된 것 같다.
이 글에서 나는 자주 간과되는 영역을 다룰 것이다. 객체 지향 CSS(Object Oriented CSS : OOCSS) 개념을 소개하고, 이것이 웹 페이지의 성능과 유지보수 용이성을 둘 다 개선하는 데 도움이 될 수 있는 방법이라는 것을 설명할 것이다.
OOCSS의 원칙
다른 객체 기반 코딩 방법론처럼 OOCSS의 목적도 코드 재사용을 촉진하고 궁극적으로는 더 빠르고 효율적이며 추가와 유지보수가 쉬운 스타일시트를 만드는 것이다.
OOCSS GitHub 위키 페이지에서 설명하는 바와 같이 OOCSS는 두 가지 주요 원칙에 기초한다.
겉모양에서 골격 분리하기
스타일을 입힌 웹 페이지의 거의 모든 요소에는 다른 맥락에서 반복적으로 등장하는 서로 다른 시각적 특징(‘겉모양’)이 있다. 웹사이트 브랜딩(색이나 섬세한 그러데이션 사용 또는 보이는 선)에 대해 생각해보라. 한편, 일반적이고 보이지 않는 특징(골격)은 똑같이 반복된다.
이렇게 서로 다른 특징을 클래스 기반 모듈로 추출하면 재사용이 가능하고 어떤 요소에도 적용할 수 있으며 똑같은 기본 결과를 얻을 수 있다. 코드를 다듬기 전과 후를 비교해보면 무슨 이야기를 하는지 알 수 있을 것이다.
OOCSS 원칙을 적용하기 전에는 다음과 같은 CSS를 작성했을 것이다.
앞의 세 요소는 각각 독자적인 스타일이 있고 재사용할 수 없는 ID 선택자를 스타일 정의에 사용한다. 하지만 공통 스타일도 다수 등장한다. 공통 스타일은 브랜딩이나 디자인의 일관성을 위해 존재할 것이다.
깊이 생각하고 계획을 세우면 공통 스타일을 추출할 수 있고 CSS는 결국 다음과 같이 바뀔 것이다.
이제 모든 요소가 클래스를 사용한다. 공통 스타일은 재사용 가능한 ‘skin’으로 묶였고 불필요한 반복이 없어졌다. ‘skin’ 클래스를 모든 요소에 적용하면 되고 코드가 더 적어지고 재사용 가능성이 더 나아졌다는 점만 제외하면 결과는 처음 예제와 같다.
컨테이너와 콘텐츠 분리하기
OOCSS Github 위키 페이지가 설명하는 두 번째 원칙은 콘텐츠에서 컨테이너를 분리하는 것이다. 이것이 왜 중요한지 명확히 하려면 다음 CSS를 살펴보자.
이 스타일은 #sidebar
요소의 자식 요소인 h3 모두에 적용될 것이다. 하지만 글자 크기와 그림자를 제외한 나머지 스타일을 푸터의 h3에도 똑같이 적용하고 싶다면 어떻게 해야 할까?
다음과 같이 해야 한다.
또는 더 안 좋은 방식으로 할 수도 있다.
우리는 불필요하게 스타일을 중복하고 있지만 그것을 알아차리지 못하거나 신경 쓰지 않을 수도 있다. OOCSS는 서로 다른 요소를 꼼꼼히 살펴 공통된 부분을 찾아내고 공통 특징을 분리하여 어디서나 재사용할 수 있는 모듈이나 객체로 만든다.
앞의 예제처럼 자손 선택자를 사용하여 선언한 스타일은 재사용할 수 없다. 특정 컨테이너에 종속되기 때문이다(예제는 사이드바나 푸터에 종속되었다).
OOCSS의 클래스 기반 모듈 구축으로 우리는 스타일이 어떤 컨테이너 요소에도 종속되지 않게 할 수 있다. 이것은 구조적 맥락에 상관없이 클래스를 문서 어디에서나 재사용할 수 있음을 의미한다.
실제 사례
OOCSS를 어떻게 사용할 수 있는지 좀더 명확히 설명하기 위해 이전에 리디자인한 내 사이트에 적용한 것과 비슷한 예를 활용할 것이다. 나는 헤더 안의 요소를 코딩한 뒤 헤더 안 기본 골격 스타일을 페이지의 다른 요소에 재사용할 수 있다는 사실을 깨달았다.
다음은 사이트의 헤더를 꾸밀 때 사용한 코드다.
.header-inside
요소에 필요한 것은 몇 가지고 나머지는 재사용 가능한 모듈로 만들 수 있다. 그래서 골격 관련 스타일을 골격만 담당하는 재사용 가능한 클래스로 추출했다. 그 결과물은 다음과 같다.
.globalwidth
클래스에 속하는 스타일은 다음과 같다.
- 고정 너비
- 마진을 이용한 가운데 정렬: auto
- 자식 요소를 위해 위치 문맥을 생성하는 상대 위치Relative positioning 지정하기
- 좌우 20px 패딩
- 클리어픽스clearfix(float 요소의 높이를 컨테이너에 반영하기 위한 기법 ― 옮긴이)를 위한 overflow: hidden
이제는 이 스타일을CSS를 한 줄도 작성하지 않고 그냥 클래스만 추가하여 같은 특성이 필요한 어떤 요소에든 자유롭게 사용할 수 있다.
내 사이트에는 골격용 스타일을 주요 콘텐츠 요소와 푸터 내부 요소에 재사용했다. 디자인에 따라 이 스타일은 헤더와 콘텐츠 사이에 있는 수평 내비게이션 요소에 적용될 수 있다. 또는 페이지 가운데에 와야 하는 고정 너비 요소에 사용할 수도 있을 것이다.
‘globalwidth’ 스타일을 여러 요소에 추가한 뒤 마크업은 다음과 같이 보일 것이다.
어떤 사람들은 이런 식의 스타일 추출이 HTML을 어지럽게 만들고 표현에서 마크업을 분리하는 원칙을 위배한다고 생각할 것이다.
하지만 이것이 마크업에 어떤 영향을 미칠지에 대한 논쟁은 제쳐두고 스타일 추출이 세 요소의 골격을 잡는 데 사용한 공통 스타일을 추적하고 수정을 더 쉽게 해주었다는 사실에는 아무도 의문을 제기할 수 없을 것이다.
미디어 객체
니콜 설리번Nicole Sullivan은 OOCSS 운동의 개척자 중 한 명이다. 그는 미디어 객체라 부르는 재사용 가능 모듈을 만들었다. 니콜이 설명한 것처럼 이 모듈로 코드의 양을 대폭 줄일 수 있다.
미디어 객체는 OOCSS의 강력함을 보여주는 훌륭한 예다. 콘텐츠 좌측에 크기와 상관없이 미디어 요소를 배치할 수 있게 해주기 때문이다. 비록 콘텐츠 안쪽에 적용되는 많은 스타일이(심지어 미디어 요소 자체의 크기도) 변할 수 있지만 미디어 객체 자체에는 불필요한 중복을 피하도록 해주는 공통된 스타일이 있다.
OOCSS의 이점
앞서 설명한 OOCSS의 이점 몇 가지를 좀더 확장해서 다룰 것이다.
더 빠른 웹사이트
OOCSS의 성능 이점은 꽤 명확할 것이다. CSS에 중복이 거의 없다면 자연스레 파일 크기가 작아지고 그에 따라 소스 다운로드도 더 빨라질 것이다.
마크업이 더 지저분해지고 용량이 큰 HTML 파일을 만들 것이라는 점은 사실이다. 하지만 많은 경우 스타일시트를 통해 얻는 성능 향상이 마크업 용량이 늘어난 탓에 생기는 성능 손실을 훨씬 넘어선다.
명심할 또 다른 개념은 OOCSS 위키에서 성능 쿠폰 performance freebie이라고 일컫는 것이다. 이는 여러분이 CSS에서 뭔가를 재사용할 때마다 기본적으로 단 한 줄의 CSS 코드 없이 새로운 스타일 요소를 생성하고 있다는 것을 가리킨다. 규모가 큰 대량 트래픽 프로젝트에서 이 ‘쿠폰’은 결정적인 성능 이득이 될 수 있다(사이트 로딩이 빠르면 매출이 늘어난다. 예컨대 로딩이 0.1초 느려졌을 때 아마존은 매출이 1퍼센트 줄어들었다. 그래서 속도가 빠른 것은 고객을 유인하는 ‘쿠폰’과 같다고 비유한 것이다 ― 옮긴이).
유지보수가 쉬운 스타일시트
OOCSS를 사용하면 점점 늘어나는 특정도specificity 전쟁(이미 적용되어 있는 스타일을 덮어쓰기 위해 선택자를 계속 늘려 CSS의 특정도를 높이는 현상 ― 옮긴이)으로 가득한 스타일시트 대신 자연스러운 캐스케이드(다양한 소스에서 비롯한 스타일 중 어떤 스타일을 적용할지 정하는 알고리즘 ― 옮긴이)가 중요한 역할을 수행하는 유지보수가 쉬운 모듈 세트가 생길 것이다.
이제 우리는 기존 사이트에 뭔가를 추가할 때 이전에 무엇이 있었든 신경 쓰지 않고 스타일시트 맨 밑에 새로운 스타일을 추가하지 않을 것이다. 대신에 기존 스타일을 재사용하고 기존 규칙 세트를 기반으로 스타일을 확장하게 될 것이다.
이런 식으로 계획하면 아주 적은 CSS만으로도 전체 페이지를 만들 수 있다. 기존 CSS 모듈 중 어떤 것이든 새로운 페이지의 기반이 될 수 있으며 새로 짜는 CSS는 최소화될 것이다. 심지어는 CSS를 한 줄도 쓰지 않고 완전히 새로 스타일한 페이지를 만들 수도 있다.
유지보수가 쉬우면 스타일시트가 견고해진다. 스타일이 모듈로 되어 있기 때문에 OOCSS에 기반한 페이지는 새 개발자가 스타일시트를 사용할 때 깨질 가능성이 적다.
주목할 가치가 있는 것
OOCSS는 커뮤니티에서 많은 토론을 야기했고 약간의 논쟁도 불러일으켰다. 여기에서는 몇 가지 일반적인 오해를 풀어볼 것이다.
여전히 ID를 사용할 수 있다
OOCSS 방법으로만 작업하기로 했다면 주로 CSS 클래스에 기반해 스타일을 입히게 될 것이고, ID 선택자를 사용하여 요소에 스타일을 입히지는 않을 것이다.
그렇기 때문에 사람들은 OOCSS가 ID를 완전히 버리기를 권한다고 잘못 주장해왔다. 하지만 이는 사실이 아니다.
ID를 피하라는 규칙을 좀더 구체적으로 말하면 ‘ID를 선택자로 사용하지 말라’는 뜻이다. 따라서 HTML에서 자바스크립트 이벤트 훅과 책갈피(프래그먼트 식별자)에 ID를 사용하면서 OOCSS 원칙을 사용하는 것은 충분히 허용되는 일이다(따라서 ID 선택자로 스타일을 입히는 것은 피한다).
물론 이미 ID를 적용한 요소가 있고 그 요소는 페이지에서 유일할 수도 있다. 클래스 대신 ID 선택자를 사용하여 몇 바이트는 절약할 수 있다. 하지만 이런 경우조차 나중에 특정도 문제에 부딪히지 않으려면 클래스를 사용하는 것이 더 안전하다.
더 작은 프로젝트 다루기
소규모 사이트와 앱에서 OOCSS를 사용하는 것은 지나칠 수도 있다. 그러므로 이 글을 모든 상황에서 OOCSS를 옹호하는 것으로 받아들이지 말기 바란다. 상황은 프로젝트에 따라 다를 것이다.
그렇지만 적어도 모든 프로젝트를 OOCSS 관점으로 보는 것은 좋은 생각이다. 일단 익숙해지면 OOCSS의 이점이 더 두드러지고 그와 딱 들어맞을 대규모 프로젝트에서 훨씬 더 쉽게 작업할 수 있다는 사실을 알게 될 것이다.
구현 가이드라인
OOCSS를 처음 시작하려면 시간이 조금 걸릴 수 있다. 여전히 노력 중이기 때문에 나는 이 분야에 관한 모든 답을 알고 있다거나 모든 경험을 했다고 주장할 생각은 없다.
그러나 OOCSS 사고방식을 익히는 데 도움이 될 만한 몇 가지 사항이 있다.
- 자손 선택자 피하기(즉
.sidebar h3
사용 안 하기) - ID에는 스타일 적용 피하기
- 스타일시트 요소에 클래스 붙이는 것 피하기(
div.header
,h1.title
과 같이 하지 않기). - 정말 드문 경우 외에는
!important
사용 피하기 - CSS Lint를 사용하여 CSS 검사하기(Lint의 엄청난 옵션과 방법 배우기).
- CSS 그리드 사용하기
나중에 이 규칙 중 일부는 깨질 수도 있다. 하지만 전체적으로 이 규칙은 발전하는 데 도움이 되는 좋은 습관이고 스타일시트를 더 작고 유지보수하기 쉽게 만들어 줄 것이다.
니콜 설리번의 작업 살피기
OOCSS를 계속 배우고 싶다면 이 업계에서 알아야 할 가장 중요한 사람은 니콜 설리번이다.
니콜은 자신의 블로그에 OOCSS에 관한 글을 정기적으로 올렸을 뿐 아니라 슬라이드쇼를 활용하여 발표도 많이 했다. 다음은 그가 발표한 볼 만한 자료다.
- 객체 지향 CSS(슬라이드쇼)
- 우리의 모범 사례가 우리를 죽이고 있다(슬라이드쇼)
- 과잉 CSS(슬라이드쇼)
결론
많은 사람이 OOCSS 관념을 두려워한다. 우리가 배워온 이른바 모범 사례와 반대되는 것으로 보이기 때문이다. 하지만 OOCSS의 장기적 이점을 이해하면 많은 개발자가 전향할 것이다.
전반적으로 나는 CSS 개발에서 OOCSS의 미래가 밝다고 생각한다. OOCSS는 더 빠르고 효율적이고 유지보수가 쉬운 웹 페이지를 만들게 해준다. 이는 모든 개발자가 적어도 어느 정도는 프로젝트에 받아들여야 하는 개념이다.
레이철 앤드루의 『새로운 CSS 레이아웃』
그리드를 사용한 레이아웃을 기존 레이아웃과 비교해서 살펴볼 수 있습니다. 예제를 통해 그리드 레이아웃이 어떻게 활용되는지 확인해보세요. 레이아웃만을 다룬 국내 유일 ‘그리드 레이아웃’ 전문서 『새로운 CSS 레이아웃』입니다.