Hello Enact #2 - CSS 추가하기

Hello Enact #2 - CSS 추가하기

지난 시간 Hello Enact! #1기본에서 만든 앱에 약간의 스타일을 입히겠습니다. React 에서 CSS class를 정의하고 이어서 CSS modules를 살펴 보겠습니다.

React 에서 CSS Class

CSS 클래스는 앱에 시각적 효과를 입히는 기본적인 도구 입니다. 컴포넌트에 clssName
prop을 이용해 CSS Class 를 적용합니다.

<div className="customClass">Content</div>

아래와 같이 DOM에 비슷하게 렌더링 합니다.

<div class="customClass">Content</div>

JSX를 처음 접하는 분은 className이 아닌class를 써서 HTML에 적용되기를 기대하실 수도 있겠습니다만, JSX는 JavaScript로 트랜스파일 되고, class는 예약어 이기 때문에 똑같이 사용하는 것은 불가능 합니다. 상세 내용은 React 가이드 DOM Elements를 참고하세요.

여러분은 하이픈으로 연결된 클래스 이름을 사용하고 싶을 수 있습니다만(custom-clss), 잠시 후 다룰 CSS Modules에서는 클래스 이름에 카멜케이스를 사용하기를 권장합니다. 자세한 사항은 링크의 Naming 부분을 참고하세요.

간단한 응용 프로그램의 경우 전역 클래스 이름을 사용하는 것이 쉽습니다. 보다 복잡한 응용 프로그램의 경우 유지 보수 및 재사용 성을 개선하기 위해 CSS를 구성하는 방법이 필요할 것입니다. 이 문제에 대한 다양한 솔루션을 제공하는 몇 가지 방법론 (예 : Object-Oriented CSS (OOCSS), Block Element
Modifier (BEM)
) 및 사전 처리기 (예 : SASS,
Stylus, LESS)가 있습니다.

CSS Modules는 모듈화에만 촛점을 맞춤으로써, 다른 툴이나 방법론과 잘 어울려 작동합니다. Enact 팀이 권장하는 방법입니다.

CSS Modules 소개

CSS Modules는 작성자가 여러 글로벌 스타일 시트를 사용할 때 발생할 수있는 이름 충돌을 걱정하지 않고 짧고 의미있는 클래스 이름을 사용하여 CSS (또는 SASS 또는 LESS 또는 …)를 작성할 수 있도록 도와줍니다.

CSS 모듈에 정의 된 모든 클래스는 기본적으로 로컬입니다. 실제로는, 클래스명이 컴파일시 고유한 문자열로 바뀝니다. 생성 된 클래스 이름을 사용하기 위하여 CSS모듈은 클래스 이름 - 생성 된 이름의 맵을 내보냅니다.
예를 들어, 아래의 CSS 모듈 :

.customClass {
 background: red;
 color: white;
}

은 다음과 같은 형태로 export 됩니다.

{
 customClass: '_13LGdX8RMStbBE9w-t0gZ1'
}

:global pseudo-selector를 사용하여 class를 전역으로 선언할 수 도 있습니다. 이렇게 하면 선언한 이름 그대로 export 됩니다.

:global .customClass {
 background: red;
 color: white;
}

다음과 같이 export 될 것입니다.

{
 customClass: 'customClass'
}

global 클래스는 가능하면 쓰지 않아야 합니다. 이것은 여러분의 컴포넌트와 CSS 소스간에 암묵적인 종속성(implicit dependency)을 생성합니다. 이 암묵적인 종속성은 빌드툴에 의해서 추적되지 못합니다. 또한 명시적으로 의존하는 리소스가 더 이상 사용되지 않으면 빠질 수 도 있습니다.

LESS 파일 만들기

스타일링 위한 파일 ./src/App/App.less를 생성합시다.

enact create가 만들어주는 webpack config에는 LESS를 지원하는 전처리기가 포함되어 있습니다. 따라서 본 과정에서는 간단한 기본 CSS문법만 사용하지만 LESS 확장자를 사용하도록 하겠습니다.

.app {
 font-size: 48px;
}

CSS Modules 사용하기

컴포넌트의 관점에서 CSS 모듈은 다른 모듈과 동일하게 취급됩니다. import할 수 있고, class name map에 대한 레퍼런스를 얻을 수 있습니다.

꼭 정해진 법은 아니지만, 일관성을 위하여 우리는 스타일 시트의 컴포넌트를 import 하여 css변수에 담습니다.

App.js 수정하기

우리의 App 모듈을 불러와서(./src/App/App.js), CSS모듈을 import 하고, 루트 엘리먼트에 .app 스타일을 적용합시다.

import React from 'react';

import css from './App.less'; //스타일 컴포넌트를 css에 담아둡니다.

const App = function () {
 return (
  <div className={css.app}> //루트 엘리먼트에 .app 스타일을 적용합니다.
   Hello Enact!
  </div>
 );
};

export default App;
export {App};

JSX 안에서 표현 하는 방법

위 샘플의 JSX가 표준 HTML과 다르다는 것을 발견하셨나요? 특히 CSS 변수 주위에 중괄호 ({})를 사용하는 것이 중요합니다.
여기에 "app"을 사용하게 되면 CSS모듈의 로컬 범위를 참조하는 것이 아니라 전역 CSS 클래스를 참조하게 되므로, "app"문자열을 사용할 수 없습니다. 대신에 우리는 JSX 표현식을 사용하여 유효한 자바스크립트 문장을 JSX 마크업에 포함합니다. 아래 문장은 css.app의 호출 결과값을 <div>className프라퍼티로 넘겨줍니다.

<div className={css.app}>

프라퍼티 값이나 전체 엘리먼트에 JSX 표현식을 사용할 수 있지만, 컴포넌트 이름이나 프라퍼티 이름에만 사용하는 것은 불가 합니다.

유효함

<div className={a ? b : c} />    // ✅ property value
 {a ? <span>A</span> : <span>!A</span>} // ✅ entire child of <div>
</div>

유효하지않음

 <{a ? 'div' : 'span'}>      // ❌ component name
 <span {a ? b : c}="value" />    // ❌ property name
 <span {a ? b="value" : c="value"}   // ❌ entire property

마치며

이번 시간에는 React 컴포넌트에 CSS Class를 적용하는 방법과, CSS 모듈 사용법을 알아 보았습니다. 그리고 JSX에서 동적으로 프라퍼티와 엘리먼트를 추가하는 방법에 대해 간략히 살펴 보았습니다.
다음 시간에는 Enact 에서 제공하는 React 컴포넌트에 약간의 문접적 도움을 추가한 kind()에 대해서 알아 보겠습니다.

링크

댓글

이 블로그의 인기 게시물

Enact 프레임워크를 오픈합니다.

Enact 개발환경 설정

Enact 컴포넌트의 호환