#1. React에서 CSS 사용하기

※ 추가 패키지 설치

- react-router-dom : SPA앱을 만들 때 사용, URL에 따라 실행할 자바스크립트를 분기한다.

- sass : sass와 scss 컴파일 기능을 제공한다.

- styled-components : styled component를 지원한다.

yarn add react-router-dom sass styled-components
  • 띄어쓰기로 구분해서 사용하면 한번에 여러개의 패키지를 설치할 수 있다.

 

※ NavLink

  • 이전까지는 Router를 사용할 때 <Link>를 사용했지만, CSS 적용이 수월하지 않다는 단점이 있다.
  • 하지만 <NavLink>는 비교적 수월하여 앞으로 <NavLink>를 사용한다.
  • 기본 <Link>의 컴포넌트 기능에 className, activeClassName 속성이 추가된 객체이다.
    • className : 기본적으로 적용될 CSS 클래스 이름
    • active : 현재 브라우저가 위치하는 URL과 동일한 주소를 갖는 링크에게 active 클래스가 자동으로 적용된다.
// Link 대신 NavLink 사용
import { NavLink, Routes, Route } from "react-router-dom";

 

1. Inline 방식으로 사용하기

1) 변수로 정의된 CSS 참조

  • CSS 구조를 JSON  형태로 작성한다.
    • 단위가 포함된 수치값의 경우 문자열로 표기, 한쌍의 속성-값 뒤에는 세미콜론이 아닌 콤마를 사용해야한다.(JSON 형태)
  • CSS 속성 이름은 자바스크립트의 프로퍼티 이름으로 지정해야 한다. (카멜표기법. ex_fontSize)
  • inline 방식을 너무 많이 사용하면 좋지 않다.

- App.js

import React from "react";

function App() {
  
  // JSON 형태로 작성
  const myStyle = {
    fontWeight : "bold",
    color: "#22b8cf",
    textDecoration: "none",
    marginRight: "10px",
  };

  return (
    <div>
      <h1 style={myStyle}>EXAMPLE</h1>
    </div>
  );
}

export default App;

 

2) 변수를 사용하지 않고 직접 코딩

- App.js

import React from "react";

function App() {

  return (
    <div>
      <h1 
        style={{
    	  fontWeight : "bold",
    	  color: "#22b8cf",
    	  textDecoration: "none",
    	  marginRight: "10px",
        }}>EXAMPLE
      </h1>
    </div>
  );
}

export default App;
  • 중괄호 안에 중괄호를 중첩해서 사용에 유의해야한다. {{ ... }}
  • 추천하는 방법은 아님..

※ 출력결과

두가지 Inline 방식으로 출력한 내용

 

※ 이미지 사용하기

  • 소스파일을 기준으로 하는 상대경로로 지정해야한다.
    • 실행 시 react에 의해 다른 경로로 복사된다.
import sample from "../assets/img/sample.png";
  • 이미지 사용시 alt 속성을 지정 안하면 경고 메세지가 출력된다.
<img src={sample} width="240" height="240" alt="샘플이미지" />
  • public 폴더에 있는 파일들은 단순 절대경로로 참조 가능하다
    • public 폴더 하위에 임의의 폴더 생성 가능
<img src="/logo192.png" width="240" height="240" alt="리액트 로고" />

 

2. CSS 파일을 import 해서 사용 (className 활용)

1) CSS 파일 작성

- menu.css (예시)

/* 메뉴에 기본 적용될 클래스 */
nav {
  margin-bottom: 10px;
}

.normalLink {
  font-size: 20px;
  text-decoration: none;
  cursor: pointer;
  color: #222;
  margin: 0 20px;
}

.normalLink:hover {
  color: #22b8cf;
}

/* 현재 페이지를 의미하는 메뉴에 적용될 클래스 */
.active {
  border-bottom: 2px solid #22b8cf;
  color: #22b8cf;
}

 

2) CSS 파일 참조

  • 외부에 있는 CSS 파일을 참조할 때는 참조변수 이름을 지정하지 않는다.
  • 경로는 상대경로 형식으로 지정한다.
import "./assets/css/menu.css";
  • <NavLink>에 선언된 className 을 통해 참조한 CSS를 적용한다.

- App.js

import React from "react";
import { NavLink, Routes, Route } from "react-router-dom";

import InlineCss from "./pages/InlineCss";
import CssClass from "./pages/CssClass";
import CssModule from "./pages/CssModule";
import Scss from "./pages/Scss";
import ScssModule from "./pages/ScssModule";
import StyledComponent from "./pages/StyledComponent";

// CSS파일 import
import "./assets/css/menu.css";

function App() {
  return (
    <div>
    
      <nav>
        <NavLink className="normalLink" to="/inline_css">InlineCSS</NavLink>
        <NavLink className="normalLink" to="/css_class">css_class</NavLink>
        <NavLink className="normalLink" to="/css_module">css_module</NavLink>
        <NavLink className="normalLink" to="/scss">scss</NavLink>
        <NavLink className="normalLink" to="/scss_module">scss_module</NavLink>
        <NavLink className="normalLink" to="/styled_component">styled_component</NavLink>
      </nav>

      <Routes>
        <Route path="/inline_css" element={<InlineCss />} />
        <Route path="/css_class" element={<CssClass />} />
        <Route path="/css_module" element={<CssModule />} />
        <Route path="/scss" element={<Scss />} />
        <Route path="/scss_module" element={<ScssModule />} />
        <Route path="/styled_component" element={<StyledComponent />} />
      </Routes>
      
    </div>
  );
};

export default App;

※ 출력결과

 

3. CSS Module

1) CSS Module이란?

  • CSS를 사용할 때 클래스 이름을 고유한 값으로 자동 변환해서 컴포넌트 스타일 클래스 이름이 중첩되는 현상을 방지해준다.
    • 클래스명이 충돌하는 단점을 극복할 수 있다.
    • 컴포넌트 단위로 스타일을 적용할 때 유용하다.

 

2) CSS 파일 작성

  • 파일명은 보통 *.module.css 형식으로 만든다. (ex_ myStyle.module.css)

  • 모든 클래스 이름이 자바스크립트 변수화 되기 때문에 클래스 이름을 카멜표기법으로 지정해야한다. (권장)
    • 스네이크표기법도 가능은 하지만, 스네이크표기법은 [ ] 를 사용해서 호출해야하기 때문에 가급적 카멜표기법으로 쓰는게 좋다.
  • id 속성에 의한 접근은 사용할 수 없다.

- myStyle.module.css (예시)

nav {
  margin-bottom: 5px;
}

.content {
  position: relative;
  width: 100%;
  margin: auto;
}

.notionWrap {
  position: relative;
  text-align: center;
  background-color: #ffebcc;
  padding: 30px 0;
}

.notion {
  font-size: 30px;
  color: #5f9ea0;
}

.description {
  font-size: 20px;
  font-weight: bold;
  color: #666;
}

.fontWeight600 {
  font-weight: 600;
}

 

3) CSS Module 사용

  • 외부에 있는 CSS 파일을 참조할 때는 참조변수를 지정하지 않지만, 모듈을 참조할 때는 참조변수를 지정한다.
// CSS 모듈 참조 -> 참조변수 이름을 지정한다.
import myStyleModule from "../assets/css/myStyle.module.css";

 

  • 클래스에 적용시킬 때는 변수를 호출하는 것 처럼 CSS Module 클래스명을 호출하면 된다.
// className={참조변수.클래스}
<div className={myStyleModule.content}></div>

 

  • 여러개의 클래스를 적용할 때는 백틱(``)을 사용하거나 배열로 구성한 후 join 함수로 결합한다.
// 백틱 사용
<div className={`${myStyleModule.notion} ${myStyleModule.fontWeight600}`}></div>


// 배열 사용
<div className={[myStyleModule.notion, myStyleModule.fontWeight600].join(" ")}></div>

 

- CssModule.js (예시)

import React from "react";

// CSS 모듈 참조 -> 참조변수 이름을 지정한다.
import myStyleModule from "../assets/css/myStyle.module.css"

const CssModule = () => {
  return (
    <div>

      <div className={myStyleModule.content}>
        <div className={myStyleModule.notionWrap}>
          <h3 className={`${myStyleModule.notion} ${myStyleModule.fontWeight600}`}>
            CSS-Module이란?
          </h3>
          <p className={myStyleModule.description}>
            CSS를 사용할 때 클래스 이름을 고유한 값으로 자동 변환해서 컴포넌트 스타일 클래스 이름이 중접되는 현상을 방지해주는 기술이다.
          </p>
        </div>
      </div>

    </div>
  );
};

export default CssModule;

※ 출력결과

 

※ 개발자도구에서 확인

  • 개발자도구(크롬)에서 확인해보면, 클래스 이름에 고유 값이 자동으로 적용된 모습을 볼 수 있다.
  • 따라서 클래스명이 같더라도 중첩되는 현상을 방지할 수 있다.

 

4. SCSS 사용하기

  • React에서 SCSS 사용방법은 CSS와 크게 다르지 않다. (문법은 다르다!)
    • module 사용 방법도 동일하다. (문법만 CSS에서 SCSS로 바꾼 것과 동일)
  • 하지만, Sass와 Scss를 컴파일 해주는 패키지를 추가로 설치해줘야 한다. (맨위에 소개된 패키지와 동일)
yarn add sass

 

※ SCSS를 활용한 간단한 예제

- common.module.scss

// 색상값을 변수로 지정
$red: #f00;
$green: #0f0;
$blue: #00f;
$orange: #f60;
$yellow: #ff0;
$pink: #f0f;

// 여기저기서 반복적으로 등장해야 하는 구문들에 대한 묶음 => Mixin == JS의 함수
// 필요하다면 파라미터 정의 가능함
// 간단한 사칙 연산, 조건분기도 수행 가능함

@mixin myMixin($size) {
  // 변수값 지정 (대입 연산자가 콜론으로 사용됨)
  $calc: 100px;

  // 파라미터 $size에 따른 조건분기
  @if $size % 2 == 0 {
    $calc: $calc + 50px;
  } @else if $size % 3 == 0 {
    $calc: $calc + 100px;
  } @else {
    $calc : $calc;
  }

  width: $calc;      // 변수값을 활용한 CSS 속성 명시
  height: 32px * 2;  // 연산자를 활용한 CSS 속성 명시
  transition: all .3s ease-in;  // 일반 CSS 속성 명시

  // 가상클래스는 &기호를 사용해서 적용
  &:hover {
    transform: scale(1.2, 1.2);
  }
}

 

- style.module.scss

/* scss 파일을 참조할 때는 참조변수를 지정하지 않는다. */
@import "./common.module.scss";

.myScss {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;

  .myScssBox {
    cursor: pointer;

    // .red 클래스가 .box와 함께 사용되었을 때
    // -> .myScss .myScssBox.red
    &.red { background-color: $red; @include myMixin(1); }
    &.green { background-color: $green; @include myMixin(2); }
    &.blue { background-color: $blue; @include myMixin(3); }
    &.orange { background-color: $orange; @include myMixin(4); }
    &.yellow { background-color: $yellow; @include myMixin(5); }
    &.pink { background-color: $pink; @include myMixin(6); }
  }
}

 

- ScssModule.js

import React from 'react';

// scss 모듈 참조 -> 참조변수 이름을 지정한다. 모듈을 사용하지 않을 때는 참조변수x
import myScssModule from "../assets/scss/style.module.scss";

const ScssMoudle = () => {
  return (
    <div>
      <h2>ScssMoudle</h2>
      <div className={myScssModule.myScss}>
      
      	// 클래스 다중 사용
        <div className={`${myScssModule.myScssBox} ${myScssModule.red}`} />
        <div className={`${myScssModule.myScssBox} ${myScssModule.green}`} />
        <div className={`${myScssModule.myScssBox} ${myScssModule.blue}`} />
        <div className={`${myScssModule.myScssBox} ${myScssModule.orange}`} />
        <div className={`${myScssModule.myScssBox} ${myScssModule.yellow}`} />
        <div className={`${myScssModule.myScssBox} ${myScssModule.pink}`} />
      </div>
    </div>
  );
};

export default ScssMoudle;

※ 출력결과

마우스 올리면 사이즈가 커진다

 

5. Styled Components

1) styled Components의 개념

  • 컴포넌트 코드 안에서 CSS(SCSS) 문법을 적용한 컴포넌트를 직접 정의하는 것이다.
  • 즉, 자바스크립트 안에서 CSS를 사용할 수 있도록 도와주는 프레임워크이다. (CSS-in-JS)
  • React 컴포넌트에 특정 스타일링을 할 수 있기 때문에 재사용성을 높일 수 있고, 자바스크립트에 영향을 받는 스타일링을 간편하게 구현할 수 있다.
  • styled components는 현존하는 CSS-in-JS 라이브러리 중에 가장 널리 사용되고 있는 라이브러리이다.

 

2) 기본 설정

  • Styled Component는 styled-components 라는 패키지명을 가지고 있다. (맨 위에 언급한 패키지와 동일)
yarn add styled-components
  • VScode에서 styled components 지원을 위한 확장프로그램 

  • 기능을 사용을 위한 참조
import styled, { css } from "styled-components";

 

3) 사용 방법

- 기존 CSS 방식

  const myStyle = {
    fontWeight: "bold",
    color: "#22b8cf",
    textDecoration: "none",
    marginRight: "10px",
  };

  return (
    <div>
      <h1 style={myStyle}>EXAMPLE</h1>
    </div>
  );
  • JSON 형태로 CSS를 작성하여 변수에 대입하고, style 속성에 객체를 전달하거나 className을 설정하고 별도의 CSS 파일을 import하는 방식.

 

- styled-components 방식

  const myStyle = styled.h1`
    fontWeight: "bold";
    color: "#22b8cf";
    textDecoration: "none";
    marginRight: "10px";
  `;

  return (
    <div>
      <myStyle>EXAMPLE</myStyle>  // 객체를 태그처럼 사용
    </div>
  );
  • styled-components는 style이 적용 된 Component를 직접 생성한다.
  • styled.태그이름 `..css..`; 형태로 사용한다. (백틱 사용에 주의)
  • 코드 사용량이 줄어드는 효과가 있고, 기존 CSS 방식처럼 Json(key:value) 형식이 아닌, CSS 문법 그대로 사용하기 때문에 가독성이 높아진다는 장점이 있다.
    • 속성이 끝나면 콤마가 아닌 기존 방식대로 세미콜론 사용.

 

4) props 사용하기

  const myStyle = styled.h1`
    fontWeight: "bold";
    color: "#22b8cf";
    textDecoration: "none";
    marginRight: "10px";
    
    width: ${props => props.width};  // prop로 전달 받은 값을 넓이값으로 지정
  `;

  return (
    <div>
      <myStyle width="100px">EXAMPLE</myStyle> 
    </div>
  );
  • styled-components는 컴포넌트의 props를 전달받아 사용하는 것이 가능하다.
  • JSX로 부터 전달받은 변수들은 props라는 이름의 객체 형태로 주입받는 콜백함수를 정의한다.
    • 이 콜백함수에서 리턴하는 값이 바로 적용된다.
  • ${ } 는 자바스크립트 형식인지 인지해주는 역할을 한다.
    • styled-components 사용 시, 이 안에서 콜백함수를 정의한다.

 

5) styled-components로 간단한 예제 만들기

import React from "react";
import styled, { css } from "styled-components";

// === ul 태그로 구성된 컴포넌트 정의 === //
const MyGridContainer = styled.ul`
  display: flex;
  padding: 0;
  margin: 0;
  width: 1000px;
  flex-direction: row;
  flex-wrap: wrap;
  border: 5px solid #50b8cf;
  list-style: none;
`;

// === li 태그로 구성된 컴포넌트 정의 === // props 사용
const MyGridItem = styled.li`
  width: ${(props) => props.width};
`;

// === div 태그로 구성된 컴포넌트 정의 === //
const MyBox = styled.div`
  border: 2px dashed #999;
  background-color: #eee;
  height: 100px;
  text-align: center;
  font-size: 20px;
  line-height: 100px;
  cursor: pointer;
  transition: all .1s ease-in;

  /* 색상값이 전달된 경우 해당값 사용, 그렇지 않은 경우 "black"을 기본값으로 사용 */
  color: ${(props) => props.color || "black" };

  /* 마우스를 올렸을 때 이벤트 처리 */
  &:hover {
    transform: scale(1.05, 1.05) rotate(-10deg);
    background-color: ${(props) => props.color || "#eee"};
    color: #fff;
  }

  /* props 값에 대한 조건절 처리 -> 짝수인 값에 CSS 적용(0부터 시작) */
  ${props => props.number % 2 === 0 && css`
    font-weight: bold;
    font-style: italic;
    text-decoration: underline;
  `}
`;

const StyledComponent = () => {

  // 색상 이름이나 색상 코드에 대한 배열
  const myColors = ["red", "green", "blue", "purple", "orange", "yellow", "pink"];

  // 배열 전체를 100으로 봤을 때 하나당 몇 %인지 계산
  const myWidth = 100 / myColors.length + "%";

  return (
    <div>
      <h2>StyledComponent</h2>
      <h3>배열 원소를 활용한 컴포넌트 사용</h3>
      
      <MyGridContainer>
        {myColors.map((v,i) => {
          return (
          
            // styledComponent에게 HTML 속성처럼 전달하는 값들은 변수로서 작용한다.
            // 속성 이름은 특별히 정해진 것은 없다.
            <MyGridItem key={i} width={myWidth}>
              <MyBox color={v} number={i}>{v}</MyBox>
            </MyGridItem>
            
          );
        })}
      </MyGridContainer>
    </div>
  );
};

export default StyledComponent;

※ 출력결과

마우스를 올리면 해당 이벤트 발생

 

'국비수업 > React' 카테고리의 다른 글

[React] Axios 사용하기  (0) 2022.05.15
[React] Hooks  (0) 2022.04.29
[React] Props (Properties)  (0) 2022.04.25
[React] JSX (JavaScript eXtension)  (0) 2022.04.23
[React] SPA (Single Page Application)  (0) 2022.04.22

+ Recent posts