CSS를 작성하는 방법은 무척이나 다양합니다. 언제나 더 쉽게 프로그래밍을 할 방법을 찾는 수 많은 개발자들이 있기 때문이죠. Vanilla CSS부터 Styled Components와 Tailwind까지 간략하게 장단점 위주로 알아봅시다.

Vanilla CSS

먼저 웹 개발자라면 누구나 알고 있을 기본 CSS입니다. 다른 방법의 CSS와 구분하기 위해 'Vanilla'라는 표현을 사용하였습니다. 마치 아무런 라이브러리를 사용하지 않는 자바스크립트를 바닐라 자바스크립트(Vanilla JS)라고 부르는 것처럼요.

 

바닐라 CSS의 장점을 뽑으라면 기본적인 CSS 외에는 추가 학습이 필요하지 않다는 점입니다. 웹 개발자라면 누구나 배웠을 CSS만 알고 있으면 사용이 가능합니다. 하지만 이점은 동시에 단점이 되기도 합니다. CSS를 사용하면서 느꼈을 불편한 점을 그대로 가지고 있습니다. 저에게 CSS의 불편한 점을 뽑으라고 한다면 사용하지 않는 코드가 있는지 파악하기 조차 어렵다는 점, 코드 중에 부분이 적용되는 지 정확히 파악하기 어려운 점을 이야기 하겠습니다.

 

그러나 가장 큰 단점은 따로 있습니다. CSS의 스타일링은 하나의 요소(혹은 컴포넌트)만으로 스코핑되지 않고 HTML에 그려진 모든 코드에 적용됩니다. 따라서 프로젝트의 규모가 커질수록 스타일 충돌이 발생할 가능성이 매우 높습니다. 클래스의 이름을 모두 다르게 설정하는 일은 프로젝트가 커질수록 힘들어지기 때문입니다. 물론 스타일 충돌을 막기 위해 인라인 스타일을 사용할 수 있겠지만, 모든 요소를 개별적으로 작성해야하므로 상당히 수고스러운 일이 될 것입니다. 이러한 스타일 충돌을 막기 위해 CSS module이 등장하였습니다.

CSS module

CSS 모듈 컴파일 과정 (출처: JavaScript Stuff, What are CSS Modules? A visual introduction)

CSS module의 사용은 간단합니다. 파일이름.module.css 의 형태로 파일을 생성하면 됩니다. 나머지는 프로젝트에 포함된 번들러가 해결해 줄 겁니다. css뿐만 아니라 SCSS나 SASS등의 Sytle Sheets도 module을 사용하여 스타일 충돌 문제를 해결할 수 있습니다. 프로젝트가 빌드될 때 빌드 프로세스는 각 CSS 스타일에 해시값을 이용해 고유한 클래스 이름을 생성합니다. 그러면 모든 CSS 속성은 다른 값을 지니게 되어 스타일 충돌이 발생하지 않습니다. 더불어 고유한 클래스 이름을 가진다는 점은 CSS를 스코핑할 수 있게 만들어줍니다. 물론 CSS module의 스코핑이 상속이 되지 않음을 의미하지는 않습니다. 클래스 이름을 통한 스코핑이기 때문에 스타일 속성에 따라 자식 컴포넌트에 스타일이 상속되기도 합니다.

 

CSS module 역시 CSS와 같은 문법을 사용하기 때문에 따로 공부할 필요가 없다는 장점이 있습니다. 고유한 클래스 이름을 만드는 작업은 자동으로 이루어지기 때문에 개발자는 그저 CSS를 사용하듯이 사용하면 됩니다. 다만 각 컴포넌트마다 다른 module.css 파일이 필요하여 프로젝트에 수많은 css 파일이 생길 수 있습니다. 물론 어떤 개발자들은 디자인과 기능적인 면이 분리되어 더 편하다고 생각할 수 있습니다. 하지만 어떤 개발자들은 프로젝트 구조가 더 복잡해지고 관리하기가 더 어려워진다고 생각합니다. 프로젝트가 커질 수록 이는 단점에 가까워지죠.

또한 CSS module은 Vanilla CSS의 단점 중 스타일 충돌을 제외한 단점을 그대로 가지고 있습니다. SCSS등을 사용한다면 재사용성을 증가시키거나 변수를 사용할 수 있지만 여전히 조건부 스타일링같이 동적인 스타일링은 번거롭습니다. 유연성이 떨어지는 것이죠.

Styled Components

Styled Components

Styled Components는 CSS를 가장 유연하게 사용할 수 있는 방법입니다. CSS module과 마찬가지로 고유한 클래스 이름을 생성하기에 스타일 충돌이 발생하지 않습니다. 또한 앞서 언급한 CSS module의 동적인 스타일링을 아주 간편하게 만들 수 있죠. Styled Components는 CSS-in-JS라는 방법론으로 자바스크립트에서 CSS를 사용합니다. CSS-in-JS는 자바스크립트 안에서 작성된 스타일링 코드는 런타임에 CSS로 스타일을 해석하고 적용합니다. CSS-in-JS에는 Styled Components 외에도 Emotion이라는 라이브러리도 존재합니다.

 

장점

Styled Components의 가장 큰 장점은 CSS가 자바스크립트에서 작성되기 때문에 자바스크립트 변수를 스타일링에 사용할 수 있다는 것입니다. 따라서 조건부 스타일링 등의 동적인 스타일링이 아주 간편하게 처리됩니다. Template literal이라는 문법을 사용하여 CSS를 작성하죠. 그뿐만이 아닙니다. Styled Components 내에 작성된 코드는 해당 컴포넌트에만 영향을 미칩니다. 의도하지 않은 넓은 범위로 스타일이 적용되는 것을 원천적으로 막아주죠. 앞서 작성한 코드를 잊더라도 상관없습니다. 그 코드들은 오늘 작성할 코드에 영향을 주지 않을테니 말이죠. Styled Components의 마지막 장점은 하나의 파일 안에 하나의 컴포넌트를 '완전히' 넣을 수 있다는 점입니다. CSS-in-CSS(CSS-in-JS와 대비되는 개념으로 CSS파일에 CSS를 작성하는 방법론)를 사용할 때는 스타일이 컴포넌트에서 분리되어 있었지만 Styled Components를 사용하면 하나의 파일에 완전한 컴포넌트가 들어가는 셈이죠.

 

단점

CSS-in-JS가 인기있고 상대적으로 신기술인 것도 맞지만 장점만 있는 것은 아닙니다. 가장 큰 단점으로는 런타임에 오버헤드를 추가한다는 점이죠. 컴포넌트가 렌더링될 때마다 Styled Components는 자바스크립트로 작성된 스타일을 CSS로 변환하는 과정을 거쳐야 합니다. 이 때문에 CSS-in-CSS를 사용하는 것보다 렌더링 속도가 느릴 수 밖에 없습니다. 얼마나 큰 차이가 날지는 앱마다 다르겠지만 CSS-in-JS가 더 느린 것은 사실같아 보입니다. 성능에 대해 더 자세히 알아보고 싶다면 참고 자료의 글을 참고하세요(가장 마지막 글을 제외하고는 성능에 대한 이야기가 나오니 마음에 드는 글 하나만 읽어 보셔도 좋습니다.).

 

다른 단점으로는 하나의 파일에 디자인과 기능이 모두 추가된다는 점입니다. 물론 앞서 CSS module에서 언급했듯이 이는 누군가에겐 단점이겠지만 누군가에겐 장점이 될 수도 있습니다. 다만 한가지 확실한 점은, 컴포넌트에서 기능적인 부분과 디자인적인 부분을 구분하기 어렵다는 점입니다. 구분을 위해 wrapper 컴포넌트로 따로 작성한다고 하더라도 모두 JS 파일이기 때문에 한눈에 구별되지는 않는 문제가 있습니다. 다만 이는 명확하게 단점이라고 보기는 어렵습니다. 언급했듯이 개인의 취향이 더 크게 작용하는 부분입니다.

Tailwind CSS

tailwind CSS

Tailwind는 Bootstrap과 함께 가장 유명한 CSS 프레임워크입니다. 미리 정의된 스타일을 적용만 하면 되기 때문에 CSS를 몰라도 사용이 가능하다는 엄청난 장점이 있습니다. 그리고 여러 동적 스타일을 쉽게 적용할 수 있고 클래스 이름이 미리 정의되어 있기 때문에 스타일 충돌이 발생하지 않습니다. 동시에 높은 수준의 커스터마이징이 가능하는 점이 Bootstrap과 차별화되는 점입니다. 미리 만들어진 스타일을 사용하여 개발 시간을 단축할 수 있다는 점이 Tailwind와 Bootstrap의 가장 큰 장점입니다. 다만 여러 개의 클래스를 중첩하여 사용하면서 코드가 길어뎌 가독성이 심하게 떨어질 수 있어 개인적으로는 선호하지 않습니다.

자세한 내용은 각 공식문서를 참고하세요.

Tailwind CSS  Bootstrap

 

그래서 뭐를 쓰는 게 좋을까?

여러 CSS 라이브러리/프레임워크 중에 무엇을 선택할지는 개인의 취향과 프로젝트의 성격에 달려있습니다. Tailwind와 Styled Componets를 같이 사용하는 등 하나만 선택할 필요도 없기 때문에 프로젝트마다 가장 적합한 방법이 무엇일지 고민하는 과정이 필요합니다.

참고자료

kakao ENTERTAINMENT FE 기술블로그 카카오웹툰은 CSS를 어떻게 작성하고 있을까?

SAMSUNG SDS 웹 컴포넌트 스타일링 관리 : CSS-in-JS vs CSS-in-CSS

Medium [(번역) 우리가 CSS-in-JS와 헤어지는 이유, CSS의 진화 과정]

+ Recent posts