아핫 일단 나는 현업에서 일을 할 때에는 CSS, SCSS 밖에 사용을 해보지 않았다.
내가 퍼블리셔로 일을 할 때 그 회사에선 CSS만 사용을 하고 있었고 이후에 SCSS를 도입해서 사용했던 것으로 기억한다.
회사 특성상 쇼핑몰 솔루션을 이용한 프로젝트가 많기 때문에 기존 셋팅 되어있는 CSS를 사용하고 이러한 익숙한 방식을 사용하다 보니, 다른 프로젝트에서도 같은 방법을 이용했던 것 같다.
프론트엔드 개발을 공부하면서 UI를 스타일링 하는 방식이 정말 다양하다는 것을 느꼈고 이 점을 한번 정리해보고자 한다.
CSS는 웹 페이지의 모양와 스타일을 정하는 언어다.
주로 별도의 .css 파일을 생성해 <link>
태그로 연결하거나, HTML 내부의 <style>
태그를 이용해 스타일을 적용하는 방식이 있다.
이러한 방식은 가장 기본적이고 오랫동안 사용되어 왔으며, 브라우저가 직접 해석할 수 있기 때문에 빠른 렌더링이 가능하다.
프론트엔드 개발을 시작하기 전에 반드시 익혀야 하는 필수 개념 중 하나이며,
레이아웃 구성, 색상 지정, 반응형 웹 디자인 등 웹 페이지의 전반적인 디자인을 담당한다.
1. 외부 CSS 파일 사용
<link rel="stylesheet" href="styles.css" />
2. 내부 스타일 적용
<style>
.button {
color: blue;
font-size: 16px;
}
</style>
3. 인라인 스타일 적용
<button style="color: red; font-size: 18px;">클릭</button>
Vanilla CSS
기본 순수 CSS를 사용하여 스타일을 적용하는 가장 전통적인 방식
SCSS/SASS
변수, 중첩, 믹스인 등의 기능을 제공해 CSS의 재사용성과 유지보수성을 높인 스타일링 방식
CSS Modules
컴포넌트 단위로 CSS를 캡슐화하여 클래스명 충돌을 방지하고, 유지보수를 쉽게 할 수 있도록 지원하는 방식
리액트를 비롯한 컴포넌트 기반 라이브러리가 발전하면서, 전통적인 CSS 방식은 컴포넌트 기반 개발의 장점을 제대로 살리지 못하기 시작했다.
CSS는 전역적으로 스타일이 적용되기 때문에, 서로 다른 컴포넌트 간에 클래스 이름이 충돌하거나 의도하지 않은 스타일이 적용되는 문제가 발생할 수 있다.
이러한 문제를 해결하기 위해 다양한 스타일링 기법이 등장했으며, 그중 대표적인 방식이 CSS-in-JS 접근법이다.
JavaScript 안에서 CSS를 작성하는 방식으로, 컴포넌트 단위로 스타일을 정의할 수 있다.
import styled from 'styled-components';
const Button = styled.button`
color: ${(props) => (props.primary ? 'blue' : 'gray')};
font-size: 16px;
`;
export default function App() {
return <Button primary>클릭</Button>;
}
Next.js와 같이 SSR 방식을 사용할 때, 스타일이 늦게 적용되면서 화면이 잠깐 깨지는 문제가 생길 수 있다.
또, 서버에서 만든 페이지와 클라이언트가 다시 화면을 만들 때 스타일이 달라지면 오류가 나고, 화면이 제대로 보이지 않을 수 있다. 이 오류를 Hydration 라고 한다.
특히, styled-components 같은 CSS-in-JS 방식은 스타일을 실시간으로 만들어서 적용하기 때문에, Next.js 같은 서버 환경에서는 설정이 어렵고 복잡할 수 있다.
이 문제를 해결하려면, 서버에서 스타일을 미리 생성해서 클라이언트로 전달해야 한다.
이를 위해 styled-components의 ServerStyleSheet API를 사용하면 된다.
아래 방식은 리액트에서 만약에 SSR 방식을 사용할 경우에 Hydration를 방지하기 위해 아래와 같은 코드를 추가하여, 수정할 수 있다.
import { ServerStyleSheet } from 'styled-components';
// 스타일 시트 생성 (서버에서 스타일을 모아둘 공간)
const sheet = new ServerStyleSheet();
// 서버에서 스타일이 적용된 HTML 생성 (React 컴포넌트 렌더링)
const html = renderToString(sheet.collectStyles(<App />));
// 생성된 스타일을 클라이언트로 전달 (이 스타일을 HTML에 삽입)
const styleTags = sheet.getStyleElement();
Next.js와 같은 SSR 환경에서 styled-components를 사용할 때는 추가 설정이 필요하지만, 복잡하지 않은 프로젝트라면 Tailwind CSS나 CSS Modules을 사용하는 것이 더 쉬울 수 있다.
기본 순수 CSS를 사용하여 스타일을 적용하는 가장 전통적인 방식
변수, 중첩, 믹스인 등의 기능을 제공해 CSS의 재사용성과 유지보수성을 높인 스타일링 방식
위에 CSS-in-JS 방식 처럼 컴포넌트 기반 프레임워크(리액트, 뷰) 같은 경우 JS와 CSS 분리가 오히려 개발 효율성을 떨어뜨리는 경우가 많았다.
CSS-in-JS 방식도 컴포넌트 내부에서 스타일을 적용할 수 있지만, 런타임 성능 저하 문제와 빌드 시간 증가가 단점으로 작용했다.
이러한 문제들을 해결하기 위해 재사용 가능한 유틸리티 클래스 기반의 새로운 접근 방식이 필요했고, 2017년 Tailwind CSS가 등장하게 되었다.
유틸리티 퍼스트(Utility-First) 프레임워크로, 미리 정의된 클래스를 조합하여 스타일을 적용하는 방식이다.
HTML에서 직접 클래스를 추가하여 빠르게 UI를 구현할 수 있다.
<button class="text-white bg-blue-500 px-4 py-2 rounded">클릭</button>
각 스타일링 방식은 장단점이 있기 때문에, 프로젝트의 특성에 따라 적절한 방식을 선택하는 것이 중요하다.
정말 내가 작은 프로젝트나 CSS 기본기를 익히고 싶다! -> CSS
리액트 프로젝트에서 컴포넌트 단위로 스타일링을 깔끔하게 하고 싶다. -> styled-components
디자인을 빨리 적용하고 싶고, 일관된 스타일을 유지해야 한다 -> Tailwind CSS
프로젝트의 규모, 팀 구성, 유지보수 계획 등을 고려해서 적절한 스타일링 방식을 선택하는 것이 중요하다.
미리 디자인된 UI 컴포넌트(버튼, 카드, 모달 등)를 제공하여 빠른 개발을 도와주는 라이브러리
주로 컴포넌트 기반으로 동작하며, React, Vue 같은 프레임워크에서 많이 사용된다.
가장 널리 사용되는 CSS/UI 프레임워크로, 반응형 레이아웃 시스템과 다양한 스타일의 기본 컴포넌트를 제공해 빠르고 일관된 웹 디자인을 적용할 수 있다.
Google의 Material Design 시스템을 기반으로 한 React UI 프레임워크로 미리 만들어진 컴포넌트(버튼, 입력 필드, 카드 등)를 제공해 빠른 개발이 가능하며, 테마 설정을 통해 손쉽게 디자인을 커스터마이징할 수 있다.
비즈니스 애플리케이션에 최적화된 UI 프레임워크로, 테이블, 폼, 모달 등 다양한 고급 컴포넌트를 제공하여 대시보드 및 관리 시스템 구축에 유용한다.
최근 2년간의 npm 트렌드를 살펴보면, 스타일링 방식의 변화를 확인할 수 있다.
2년 전까지만 해도 전통적인 CSS가 가장 많이 사용되었지만, React와 Next.js와 같은 프레임워크의 성장과 함께 styled-components와 Tailwind CSS가 빠르게 인기를 얻고 있다.
특히, 최근에는 Tailwind CSS가 가장 많이 사용되는 스타일링 라이브러리로 자리 잡고 있는 추세다.
https://npmtrends.com/css-vs-styled-components-vs-tailwindcss
2024년에 깃허브에서 자바스크립트 관련 프로젝트에서 가장 많은 ⭐을 받은 스타일링 및 CSS in JS다.
1위는 단연 Tailwind CSS가 차지하는 것을 확인할 수 있었고 2위도 Tailwind CSS 기반의 UI 컴포넌트 라이브러리인 DaisyUI인 것을 확인할 수 있다.
스타일링 이외에도 2024년에 ⭐을 많이 받은 프로젝트를 확인하고 싶다면 아래 링크를 확인하면 된다.
https://risingstars.js.org/2024/en#section-css-in-js
CSS, styled-components, Tailwind CSS는 각각의 장단점이 있으며, 프로젝트의 요구사항에 따라 적절한 방식을 선택해야 한다.
styled-components는 컴포넌트 기반 개발에 적합하고, Tailwind CSS는 빠른 개발과 일관된 디자인에 강점이 있다.
간단한 프로젝트에는 전통적인 CSS, 유지보수와 확장성이 중요한 경우에는 CSS-in-JS나 유틸리티-first 프레임워크를 고려하는 것이 좋다.
정말 트렌드는 하루가 다르게 빠르게 변하는 것 같다.
이제 막 CSS에서 컴포넌트 기반 스타일링 방법을 하나둘 익혀가고 있는데, 벌써 styled-components를 넘어 Tailwind CSS가 더 많이 사용되고 있다니 놀랍다.
마치 리덕스를 배우자마자, 요즘은 더 가벼운 상태 관리 라이브러리인 Zustand가 인기를 끌고 있다는 얘기를 들었을 때와 비슷한 충격을 받았다.
새로운 기술을 배우기 전에 그 배경을 이해하는 것이 중요하다는 걸 다시 한번 느낀다.
예전에는 전통적인 CSS 방식만으로도 충분했지만, 기술이 발전하면서 기존 방식의 불편함이 드러났고,
그 결과 더 효율적인 새로운 스타일링 방법들이 등장했다.
개발 생태계는 정말 넓고, 끊임없이 변화하고 있다는 걸 실감하게 된다.......!!!!
참고한 사이트들
https://www.elancer.co.kr/blog/detail/290
https://npmtrends.com
https://risingstars.js.org/2024