Sass (Syntactically Awesome Style)
- CSS pre-processor(전처리)로 복잡한 작업, 재활용성, 가독성, 유지보수 효율 상승.
- 확장자는
.scss
와 .sass
를 지원하지만 .scss
문법이 더 많이 사용됨.
- 공식 가이드는 여기로
- Sass를 CSS로 변환하기 위한 node-sass 라이브러리 설치. (
$ npm i node-sass
)
컴포넌트 꾸미기
import React from 'react';
import './Button.scss';
function Button({ children }) {
return <button className="Button">{children}</button>;
}
export default Button;
- 변수를 다룰 때는 앞에
$
(달러) 표시 이용.
&
(앤드)는 현재 위치한 요소를 의미.
$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%);
}
&:active {
background: darken($blue, 10%);
}
}
동적인 클래스 이름
className={['Button', size].join(' ')}
,
className={`Button ${size}`}
- 또는 classnames 라이브러리를 이용하면 구현 가능.
large
, medium
, samll
사이즈 구할 때,
size
를 전달 받아 클래스(className
)로 적용하도록 설정.
import React from 'react';
import './Button.scss';
function Button({ children, size }) {
return <button className={`Button ${size}`}>{children}</button>;
}
Button.defaultProps = {
size: 'medium'
};
export default Button;
- 클래스에 따라 스타일 지정.
.Button
클래스 스타일 속성 안에 존재하는 &.large
는 .Button.large
의미.
- 자식 또는 자손 선택자와 다르게 띄어쓰기(스페이스)가 존재하지 않음 주의.
$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%);
}
&:active {
background: darken($blue, 10%);
}
}
여러개 일때
import React from 'react';
import classNames from 'classnames';
import './Button.scss';
function Button({ children, size, color }) {
return (
<button className={`Button ${size} ${color}`}>{children}</button>
);
}
Button.defaultProps = {
size: 'medium',
color: 'blue'
};
export default Button;
$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%);
}
&:active {
background: darken($blue, 10%);
}
}
&.gray {
background: $gray;
&:hover {
background: lighten($gray, 10%);
}
&:active {
background: darken($gray, 10%);
}
}
&.pink {
background: $pink;
&:hover {
background: lighten($pink, 10%);
}
&:active {
background: darken($pink, 10%);
}
}
}
요소 사이의 여백
& + &
또는 .클래스명 + .클래스명
를 설정해 요소 사이의 여백 설정 가능.
- 버튼 여러개가 존재할 때 여백 설정.
$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%);
}
&:active {
background: darken($blue, 10%);
}
& + & {
margin-left: 1rem;
}
}
@mixin
@mixin
을 이용해 반복을 줄일 수 있음.
@mixin
으로 선언한 스타일은 @include
으로 이용 가능.
&.blue {
background: $blue;
&:hover {
background: lighten($blue, 10%);
}
&:active {
background: darken($blue, 10%);
}
}
&.gray {
background: $gray;
&:hover {
background: lighten($gray, 10%);
}
&:active {
background: darken($gray, 10%);
}
}
&.pink {
background: $pink;
&:hover {
background: lighten($pink, 10%);
}
&:active {
background: darken($pink, 10%);
}
}
$blue: #228be6;
$gray: #495057;
$pink: #f06595;
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 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;
}
}
classnames
- classnames 라이브러리를 이용해 클래스 유뮤에 따른 스타일 적용가능.
import React from 'react';
import classNames from 'classnames';
import './Button.scss';
function Button({ children, size, color, outline }) {
return (
<button className={classNames('Button', size, color, { outline })}>
{children}
</button>
);
}
Button.defaultProps = {
size: 'medium',
color: 'blue'
};
export default Button;
@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;
}
}
}
...rest props
- 이벤트를 부여 할 때.
...rest
를 이용하면, 이벤트 부여가 가능함.
import React from 'react';
import classNames from 'classnames';
import './Button.scss';
function Button({ children, size, color, outline, fullWidth, ...rest }) {
return (
<button
className={classNames('Button', size, color, { outline, fullWidth })}
{...rest}
>
{children}
</button>
);
}
Button.defaultProps = {
size: 'medium',
color: 'blue'
};
export default Button;