본문 바로가기
프론트엔드/React

Sass

by alswlfl 2022. 12. 6.

⭐️ css 전처리기(Pre-Processor)

: 모듈별로 특별한 Syntax를 가지고 있고 여기에 mixin, nesting selector, 상속 등 프로그래머적인 요소를 접목해 방대해지는 CSS 문서의 양을 효율적으로 처리하고 관리해주는 통합적인 언어

→ CSS 전처리기 자체만으로는 웹 서버가 인식 못하므로, 각 CSS전처리기에 맞는 컴파일러를 사용하여 CSS문서로 변환해야함

장점

  1. 재사용성: 공통 요소 또는 반복적인 항목을 변수 또는 함수로 대체
  2. 시간적 비용 감소: 임의 함수 및 Built-in 함수로 인해 개발 시간적 비용 절약
  3. 유지관리: 중첩, 상속과 같은 요소로 인해 구조화된 코드로 유지 및 관리 용이

https://kdydesign.github.io/2019/05/12/css-preprocessor/

 

CSS 전처리기(Pre-Processor) 배우기!

이번 포스트에서는 Sass, Less, Stylus와 같은 CSS 전처리기(CSS Pre-Processor)에 대해 알아보자. CSS 전처리기(CSS Preprocessor)는 CSS 작성 모듈별로 특별한 Syntax를 가지고 있고 여기에 믹스인(mixin), 중첩 셀렉

kdydesign.github.io


Sass (Syntactically Awesome Style Sheets): 문법적으로 멋진 스타일시트

CSS Pre-Processor

  1. 복잡한 작업 쉽게 할 수 있게 해줌
  2. 코드의 재활용성 높여줌
  3. 코드의 가독성 높여주어 유지보수 쉽게 해결

Sass에서는 .scss 와 .sass 두 가지의 확장자를 지원함 → 문법이 다름

ex) 마지막에 콜론(;)을 붙이느냐 안붙이느냐, 괄호로 감싸느냐에 대한 여부

 

sass

$font-stack: Helvetica, san-serif
$primary-color: #333

body
	font: 100% $font-stack
    	color: $primary-color

scss

$font-stack: Helvetica, san-serif;
$primary-color: #333;

body{
	font: 100% $font-stack
    	color: $primary-color
}

라이브러리 설치

$ cd styling-with-sass
$ yarn add node-sass

Sass를 CSS로 변환해주는 역할

ex)

$blue: #228be6; // 주석 선언

.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;

  background: $blue; // 주석 사용
  &:hover {
    background: lighten($blue, 10%); // 색상 10% 밝게
  }

  &:active {
    background: darken($blue, 10%); // 색상 10% 어둡게
  }
}
  • 스타일 파일에서 사용할 수 없는 변수 선언 → $blue: #228be6
  • 색상을 더 밝게하거나 어둡게 해주는 함수 → lighten() 또는 darken()

버튼 사이즈 조정

버튼 크기에 large, medium, small 설정할 수 있도록 구현

  • className에 CSS 클래스 이름을 동적으로 넣어주는 방법 
    1. className={['Button',size].join(' ')}
    2. className={`Button ${size}`}
    3. classnames 라이브러리 사용(가장 편함) → 조건부 스타일링 시, 함수의 인자에 문자열, 배열, 객체를 전달하여 손쉽게 문자열 조합 가능
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
classNames(['foo', 'bar']); // => 'foo bar'

// 동시에 여러개의 타입으로 받아올 수 도 있습니다.
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// false, null, 0, undefined 는 무시됩니다.
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

classname라이브러리 설치

yarn add classnames
$blue: #228be6; // 주석 선언

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

  //사이즈 관리
  &.large {
    height: 3rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1.25rem;
  }
  &.medium {
    height: 2.25rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1rem;
  }

  &.small {
    height: 1.75rem;
    font-size: 0.875rem;
    padding-left: 1rem;
    padding-right: 1rem;
  }

  background: $blue; // 주석 사용
  &:hover {
    background: lighten($blue, 10%); // 색상 10% 밝게
  }

  &:active {
    background: darken($blue, 10%); // 색상 10% 어둡게
  }
}

⭐️ &의 의미는 상위에 스타일 적용

.Button {
	&. large {
    
    }
}
/*가 의미하는 것은*/
.Button.large {
}

⭐️ 여백 설정: & + &

  & + & {
    margin-left: 1rem;
  }

버튼 색상 설정

https://yeun.github.io/open-color/

 

Open Color

Color scheme for UI design

yeun.github.io

$blue: #228be6; // 주석 선언
$gray: #495057;
$pink: #f06595;

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

  //사이즈 관리
  &.large {
    height: 3rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1.25rem;
  }
  &.medium {
    height: 2.25rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1rem;
  }

  &.small {
    height: 1.75rem;
    font-size: 0.875rem;
    padding-left: 1rem;
    padding-right: 1rem;
  }

  //색상 관리
  &.blue {
    background: $blue;
    &:hover {
      background: lighten($blue, 10%); // 색상 10% 밝게
    }
    &:active {
      background: darken($blue, 10%); // 색상 10% 어둡게
    }
  }
  &.gray {
    background: $gray;
    &:hover {
      background: lighten($gray, 10%); // 색상 10% 밝게
    }
    &:active {
      background: darken($gray, 10%); // 색상 10% 어둡게
    }
  }
  &.pink {
    background: $pink;
    &:hover {
      background: lighten($pink, 10%); // 색상 10% 밝게
    }
    &:active {
      background: darken($pink, 10%); // 색상 10% 어둡게
    }
  }

  & + & {
    margin-left: 1rem;
  }
}

⭐️ 반복되는 코드는 mixin 기능 사용하여 재사용

$blue: #228be6; // 주석 선언
$gray: #495057;
$pink: #f06595;

@mixin button-color($color) {
  background: $color;
  &:hover {
    background: lighten($color, 10%); // 색상 10% 밝게
  }
  &:active {
    background: darken($color, 10%); // 색상 10% 어둡게
  }
}
.Button {
  display: inline-flex;
  color: white;
  font-weight: bold;
  outline: none;
  border-radius: 4px;
  border: none;
  cursor: pointer;

  //사이즈 관리
  &.large {
    height: 3rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1.25rem;
  }
  &.medium {
    height: 2.25rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 1rem;
  }

  &.small {
    height: 1.75rem;
    font-size: 0.875rem;
    padding-left: 1rem;
    padding-right: 1rem;
  }

  //색상 관리
  &.blue {
    @include button-color($blue);
  }
  &.gray {
    @include button-color($gray);
  }
  &.pink {
    @include button-color($pink);
  }

  & + & {
    margin-left: 1rem;
  }
}

outline 옵션 만들기

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

props로 받아와 객체 안에 집어 넣은 다음 classNames()에 포함 시켜주면, outline값이 true일 때만, button에 css적용

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

전체 너비 차지하는 옵션: fullWidth

  &.fullWidth {
    width: 100%;
    justify-content: center;
    & + & {
      margin-left: 0;
      margin-top: 1rem;
    }
  }
function Button({ children, size, color, outline, fullWidth }) {
  return (
    <button
      className={classNames("Button", size, color, { outline, fullWidth })}
    >
      {children}
    </button>
  );
}

...rest props 전달

→ 컴포넌트에 onClick 설정하거나 onMouseMove 등 이벤트 관리 시 사용

spread 와 rest 사용

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

...rest 사용하여 지정한 props 제외한 값들은 rest 객체에 모아주고, {...rest} 해주면 rest안에 있는 객체 안에 있는 값들을 모두 태그에 설정 해줌

 


❗️ px vs em vs rem

px: 고정된 절댓값 단위

em, rem: 환경에 따라 변하는 단위 → 가변단위로서 브라우저 환경에서 px로 변환됨

 

em: 같은 엘리먼트에서 지정된 값 기준으로 px로 바뀌어 화면에 표시됨 

→ 같은 엘리먼트에 설정된 크기 값이 없을 경우, 상위 요소의 사이즈가 기준이 됨

rem: 최상위 엘리먼트에서 지정된 값 기준으로 변환됨(보통 HTML tag에서 지정된 사이즈 기준)

→ 별도의 사이즈 설정을 안한 경우 각 브라우저에서 기본적으로 설정된 값을 상속 받음

 

즉, rem은 기준이 되는 크기 하나로 고정되어 있고, em은 같은 엘리먼트는 어디서라도 기준이 변경될 수 있어 크기 예측 어려움

em과 rem

https://monkeydeveloper.tistory.com/entry/CSS-px-em-rem-%EC%B0%A8%EC%9D%B4%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90

 

[CSS] px | em | rem 차이를 알아보자

px | em | rem 차이를 알아보자 px은 고정된 절대값의 단위며, em과 rem환경에 따라 변하는 단위입니다. 고정된 px과 달리, 환경에 따라 변하는 em과 rem의 장점은 무엇이며, 어떤 경우에 각각의 단위를

monkeydeveloper.tistory.com

 

'프론트엔드 > React' 카테고리의 다른 글

styled-components  (0) 2022.12.08
CSS Module  (0) 2022.12.08
리액트 개발 시 사용하면 편리한 도구  (0) 2022.12.02
LifeCycle Method  (0) 2022.12.02
클래스형 컴포넌트  (0) 2022.12.02