[sass/scss] react-scss 사용법

김진평·2023년 2월 20일
5

CSS

목록 보기
5/5
post-thumbnail

sass란?

우리는 HTML에 스타일을 주기 위해 css를 사용한다.
그러나 수많은 id, class, 선택자 등을 사용하게 되면 css 파일이 굉장히 보기 어려워진다.
sass는 css 코드를 HTML과 유사한 구조로 작성할 수 있는 전처리기이다.
덕분에 css 코드를 분석하는데 아주 유용하다.

scss는 sass에서 나온 문법이며 코드를 작성하는 규칙이 보다 익숙해 sass보다 scss를 사용하는 것을 권장한다.

sass/scss 차이

=> sass는 중괄호 및 세미콜론이 없지만 scss는 있다.
=> 따라서 scss가 한 눈에 구조를 파악하는데 더욱 익숙하다고 할 수 있다.

sass

.list
  width: 100px
  float: left
  li
    color: red
    background: url("./image.jpg")
    &:last-child
      margin-right: -10px

scss

.list {
  width: 100px;
  float: left;
  li {
    color: red;
    background: url("./image.jpg");
    &:last-child {
      margin-right: -10px;
    }
  }
}

scss 적용하기

설치 명령어

$npm i sass

1. Nesting

앞서 말했듯이 HTML 구조와 유사한 구조로 스타일 시트를 작성하는 것을 말한다.

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    display: inline-block;
  }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

2. 변수

[$변수명 : 값] 형태로 변수를 지정하여 사용할 수 있다.


$primary-color: #333;

body {
  border: 1px solid black;
  color: $primary-color;
}

.inverse {
  background-color: $primary-color;
  color: white;
}

3. & 선택자

Nesting 내부에서 & 선택자는 부모 선택자로 치환된다.
아래 예시처럼 button { &:hover }를 사용하면 button:hover와 같은 의미가 된다.

button {
  width: 200px;
  height: 50px;

  &:hover {
    width: 400px;
    height: 100px;
  }
}

/* Compile to CSS */

button {
  width: 200px;
  height: 50px;
}

button:hover {
  width: 400px;
  height: 100px;
}

4. mixin

mixin은 함수라고 생각하면 편하다.
mixin 블록 안에 css 코드를 작성하면 해당 mixin을 호출하는 순간 블록 내부 스타일이 적용된다.

@mixin flexCenter {
  display: flex;
  justify-content: center;
  align-items: center;
}

.info {
  @include flexCenter;
}

함수와 마찬가지로 매개변수를 넣을 수 있다.
인자로 null을 보내면 값 설정을 하지 않을 수도 있다.

@mixin flexSort($justify, $alignItems) {
  display: flex;
  justify-content: $justify;
  align-items: $alignItems;
}

.info {
  @include flexSort('space-between', 'center');
}

.feed {
  @include flexSort('space-around', 'center');
}

실습

이번엔 벨로퍼트님 게시글을 참고하여 버튼 만들기 실습을 해볼 예정이다.
참조 : https://react.vlpt.us/styling/01-sass.html

먼저 trusy 한 값의 이름을 className으로 그대로 들어가게 하고 falsy 값의 이름은 들어가지 않게 하는
classnames << 라이브러리를 먼저 설치한다.

npm i classnames

사용법은 대강 아래와 같다.

import classNames from "classnames";
classNames("one", { two: true, three: false, four: true }); // one two four

자 다시 본론으로 돌아와서,,
버튼에 이것 저것 props와 해당 props를 이용한 스타일링을 진행할 예정이다.

App.js

import "./App.css";
import Button from "./components/Button";

function App() {
  return (
    <>
      <Button size="small" color="blue">
        Button
      </Button>
      <Button size="large" color="red">
        Button
      </Button>
      <Button outline>Button</Button>
    </>
  );
}

export default App;

/components/Button.js

import classNames from "classnames";
import React from "react";
import "./Button.scss";

const Button = ({ children, size, color, outline }) => {
  return (
    <button className={classNames("Button", size, color, { outline })}>
      Button
    </button>
  );
};

Button.defaultProps = {
  size: "medium",
  color: "black",
};
export default Button;

/components/Button.scss

$blue: rgb(63, 149, 241);
$red: rgb(245, 71, 19);
$black: rgb(46, 44, 44);

@mixin button-color($color) {
  background: $color;
  &:hover {
    background: lighten($color, 10%);
  }
  &:active {
    background: darken($color, 10%);
  }
  &.outline {
    color: $color;
    background: none;
    border: 1px solid $color;
    &:hover {
      background: $color;
      color: white;
    }
  }
}

.Button {
  display: inline-flex;
  color: white;
  font-weight: bold;
  outline: none;
  border-radius: 4px;
  border: none;
  cursor: pointer;

  height: 2.25rem;
  padding-left: 1rem;
  padding-right: 1rem;
  font-size: 1rem;

  &.large {
    height: 3rem;
    font-size: 1.25rem;
  }

  &.medium {
    height: 2.25rem;
    font-size: 1rem;
  }

  &.small {
    height: 1.75rem;
    font-size: 0.875rem;
  }

  &.blue {
    @include button-color($blue);
  }

  &.black {
    @include button-color($black);
  }

  &.red {
    @include button-color($red);
  }
}

먼저 App.js에서 size="small", color="blue" 속성을 가진 버튼 컴포넌트를 생성했다.

Button.js를 보면 classnames 라이브러리를 사용해 "Button" 클래스명과 인자로 전달 받은 size, color 항목을 가지고 css 스타일링을 진행한다.

마지막으로 Button.scss에서는 [$blue, $red, $black] 각각 color가 지정된 세 변수를 정의하고
@mixin을 통해 전달 받은 색상으로 버튼을 스타일링한다.

color 뿐만 아니라 Button 하위에 있는 [&.large, &.medium, &.small]을 설정하여 각 사이즈에 대응하는 버튼을 스탕일링 하였다.

마지막으로 outline이라는 속성을 통해 테두리만 존재하는 버튼이 생성되었다.
이 때 Button.js에서 인자로 전달하는 {outline}의 값은 trusy, falsy를 판단하여
trusy 값일 경우 "outline" 이라는 텍스트 값을 scss에 전달한다.

(참고 : &.large는 Button.large와 같다.)

결과

0개의 댓글