시간이 점차 흐르면서 웹, 모바일 서비스를 구축하는 데 있어서 프로젝트의 규모나 복잡도가 점점 커지고 함께 작업해야할 팀원의 수도 더 많아지고 있다. 뿐만 아니라 모바일, 태블릿을 비롯한 다양한 디바이스가 등장하면서 웹사이트가 다양한 디스플레이를 호환할 수 있어야 하기 때문에 CSS는 더 복잡하게 되었다. 때문에 쉽게 지저분해지고 유지보수도 어려운 단점을 가지고 있다.
이런 이유로 CSS 작업을 효율적으로 하기 위해서 구조화된 CSS의 필요성이 대두되고, CSS를 구조화 하는 효율적인 방법이 필요해졌다.
CSS의 태생적 한계를 보완하기 위해서 CSS 전처리기(CSS Preprocessor) 라는 개념이 등장했는데, 이 CSS 전처리만으로는 CSS 문서를 웹 서버가 인지하지 못한다. 때문에 CSS 전처리기에 맞는 컴파일러를 사용해야 하는데, 이것을 컴파일 하게 되면 실제 사용되는 CSS 문서로 변환된다.
CSS 전처리기 중에서 가장 유명한 SASS(Syntactically Awesome Style Sheets) 는 CSS를 확장해 주는 스크립팅 언어다. CSS의 한계와 단점을 보완하여 보다 가독성이 높고 코드의 재사용에 유리한 CSS를 생성할 수 있게 해주는 CSS의 확장(extension)이다.
CSS의 단점을 보완하기 위해서 SASS는 다음과 같은 추가 기능과 유용한 도구들을 제공한다.
장점
SASS는 CSS보다 심플한 표기법으로 CSS를 구조화하여 표현할 수 있고, 다른 팀원들과의 작업 시 발생할 수 있는 구문의 수준 차이를 평준화할 수 있다. 그리고 CSS에서는 존재하지 않는 Mixin 등의 강력한 기능을 활용해서 CSS 유지보수 편의성을 크게 향상시킬 수 있다.
단점
하지만 SASS가 'CSS의 구조화'를 해결해 주는 것의 장점보다 다른 문제들을 더 많이 야기시킨다는 것이 밝혀졌다. 전처리기의 내부 작동이 어떻게 되는지 알지못한 채, 스타일이 겹치는 문제를 해결하기 위해서 단순한 계층 구조를 만들어 내는 것에 의지했는데, 이게 컴파일된 CSS의 용량을 엄청나게 커지게 만드는 원인이었다.
위의 단점에서 언급한 CSS 전처리기의 문제를 보완하기 위해서 BEM, OOCSS, SMACSS 같은 CSS 방법론이 대두되었는데, 각각의 장단점이 있으나 결국 세 방법론 모두 같은 지향점을 갖고 있다.
// 1.Block 2.Element 3.Modifier
.header__navigation--navi-text {
color: red;
대표적 CSS 방법론으로 BEM이 있다.
장점
BEM은 Block, Element, Modifier로 구분해서 클래스명을 작성하는 방법인데, 각각 -
와 _
로 구분한다. 클래스명은 BEM 방식으로 여러 번 반복해서 재사용할 수 있고, HTML/CSS/SASS 파일에서도 더욱 일관된 코딩 구조를 만들어 준다.
단점
하지만 여기서도 문제점이 발생한다. 클래스명 selector(선택자)가 장황해지고, 긴 클래스명 때문에 마크업이 불필요하게 커지고, 재사용 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야 한다.
또한 SASS와 BEM가 고치지 못했던 몇 가지 문제들은 캡슐화 (encapsulation : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념) 의 개념이 없다는 것이었다.
어플리케이션 중심 개발 방향으로 발전하면서 컴포넌트 단위 개발은 캡슐화(Encapsulation)의 중요성을 일깨워줬다. CSS는 컴포넌트 기반 방식을 위해서 만들어진 적이 없었는데, 결국 CSS도 컴포넌트 영역으로 불러오기 위해서 CSS-in-JS가 탄생했다.
CSS-in-JS에는 대표적으로 Styled-Component가 있다.
Styled-Component는 React의 컴포넌트 기반 개발 환경에서 스타일링을 위한 CSS 성능 향상을 위해 만들어졌다. Styled-Component를 사용하면 기존 CSS 문법으로도 스타일 속성이 추가된 React 컴포넌트를 만들 수 있다.
예시로 Styled-Component를 이용하여 어플리케이션 내에 다른 웹페이지로 이동하는 기능을 가진 Button
을 하나 만든다면 아래 코드와 같을 것이다.
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
`
방식은 기존 JavaScript, CSS와 큰 차이가 없다. JavaScript에서 변수를 선언하듯이(혹은 React 에서 컴포넌트를 만들듯이) Button
을 만들고, tag
의 속성(property)을 정의하고 (여기서는 a
tag), back-ticks (``)
안에 기존 CSS 문법을 이용하여 스타일 속성을 정의해 주는 것 뿐이다.
Styled-Component의 특징은 아래와 같다.
Automactic critical CSS
Styled-Component는 화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서
해당하는 컴포넌트에 대한 스타일을 자동 삽입한다. 코드를 적절히 분배해 놓으면 사용자가 앱을 사용할 때 최소한의 코드만으로 화면이 띄워지도록 할 수 있다.
No class name bugs
Styled-Component는 스스로 유니크한 className
을 생성한다. 때문에 className
의 중복이나 오타로 인한 버그를 줄여준다.
Easier deletion of CSS
기존에는 더 이상 사용하지 않거나 삭제한 컴포넌트에 해당하는 스타일 속성을 제거하기 위해서 CSS 파일 안의 className
을 찾아야 했지만, Styled Component는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 컴포넌트를 사용하지 않아서 삭제할 경우에 이에 대한 스타일 속성도 함께 삭제된다.
Simple dynamic styling
className
을 일일이 수동으로 관리할 필요 없이 React의 props나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적이다.
Painless maintenance
컴포넌트에 스타일을 상속하는 속성을 찾아서 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않다.
Automatic vendor prefixing
개별 컴포넌트마다 기존의 CSS를 이용하여 스타일 속성을 정의하면 된다. 이외의 것들은 컴포넌트가 알아서 처리해준다.