16_리액트_컴포넌트스타일링
FrontEnd/React

16_리액트_컴포넌트스타일링

728x90

 

컴포넌트를 스타일링 하는 가장 기본적인 방법은 아래처럼 css를 import하여 사용하는 것이다.

 

import './App.css';

 

 

Sass(Syntactically awesome stylesheets)

 

이전에 배웠던 Sass와 Scss를 이용하여 간단한 프로젝트를 만들 것이다.

 

Sass보다 Scss가 훨씬 편리하기에 Scss를 사용해보도록 하겠다.

 

 

 

먼저 아래와 같은 파일구조를 만든다

 

 

//Button.js
import React from 'react';
import './Button.scss';

function Button({children}) {
    return (
        <button className = "Button">{children}</button>
    );
    
}


export default Button;
//App.js
import React from 'react';
import Button from './component/Button';
import './App.scss';

function App() {
  return (
    <div className ="App">
      <div className="buttons">
        <Button>BUTTON</Button>
      </div>
    </div>
  );
}

export default App;
//App.scss
.App {
  width : 512px;
  margin: 0 auto;
  margin-top: 4rem;
  border : 1px solid black;
  padding : 1rem;
}
//Button.scss
$blue : #228be6;


.Button {
    display : inline-flex;
    align-items: center;
    justify-content: center;

    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%);
    }
}

 

위 초기설정들을 해주고, 리액트를 실행시켜주면

 

버튼이 나온다 이 버튼을 가지고 여러 기능들을 추가해볼 것이다.

 

 

우선

yarn add classnames

터미널을 열어 위 classnames를 설치해준다.

 

classNames를 사용하면 보다 쉽게 문자열 조합을 만들 수 있다.

 

function Button({children, size}) {
    return (
        <button className = {['Button',size ].join(' ')}>{children}</button>
    );
    
}

즉, 위처럼 join을 이용하여 문자열을 조합해줄 수도 있지만

 

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

이렇게 간단하게 사용할 수 있게 해준다.

 

 

//Button.scss
padding-left: 1rem;
    padding-right: 1rem;
    &.large {
        height: 3rem;        
        font-size: 1.25rem;
    }

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

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

그 후, Button.scss에 위처럼 각각의 크기의 비율을 맞춰 준 후에 

 

//App.js
function App() {
  return (
    <div className ="App">
      <div className="buttons">
        <Button size='large'>BUTTON</Button>
        <Button>BUTTON</Button>
        <Button size='small'>BUTTON</Button>
      </div>
    </div>
  );
}

위처럼 버튼에 size를 담아서 보내주게 되면

 

사이즈별 버튼

위같은 사이즈별 버튼이 출력되게 된다.

 

 

 

 

이번에는 색상을 추가해 보겠다.

 

//Button.js
function Button({children,size,color}) {
    return (
        <button className = {classNames('Button',size,color)}>{children}</button>
    );
    
}
Button.defaultProps = {
    size : 'medium',
    color : 'blue'
};

같은 맥락으로 color를 추가해준 후에 이전에 배웠던 maxin을 이용한 sass 편집을 해볼 것이다.

 

//Button.scss
@mixin button-color($color){
    background: $color;
    &:hover{
        background: lighten($color,10%);
    }
    &:active {
        background: darken($color,10%);
    }  
} 



................


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

위처럼 들어오는 color에 따른 배경화면이 다르게 설정해준다.

 

 

function App() {
  return (
    <div className ="App">
      <div className="buttons">
        <Button size='large'>BUTTON</Button>
        <Button>BUTTON</Button>
        <Button size='small'>BUTTON</Button>
      </div>
      <div className="buttons">
        <Button color = "gray" size='large'>BUTTON</Button>
        <Button color = "gray">BUTTON</Button>
        <Button color = "gray" size='small'>BUTTON</Button>
      </div>
      <div className="buttons">
        <Button color = "pink" size='large'>BUTTON</Button>
        <Button color = "pink">BUTTON</Button>
        <Button color = "pink" size='small'>BUTTON</Button>
      </div>
    </div>
  );
}

 

최종

이러면 위같은 9개의 버튼을 얻을 수 있다.

 

상하 여백은 App.scss에 .buttons +.buttons 을 사용하여 만들었다. 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;
        }
    }
}

 

방금 만들었던 scss mixin안에 해당 outline요소를 더해준다.

 

 

//Button.js
function Button({children,size,color,outline,fullWidth}) {

    return (
        <button className = {classNames('Button',size,color,{
            outline,    //값이 true일때만 classNames로 들어가게 된다
            fullWidth   //값이 true일때만 classNames로 들어가게 된다
        })}>{children}</button>
    );
    
}
Button.defaultProps = {
    size : 'medium',
    color : 'blue'
};

그리고 button.js의 classnames안에 해당 부분들을 객체로 넣어줌으로써 값이 true일때만 전달되게 한다.

 

그 이후, App.js에서

 

  <div className="buttons">
        <Button size='large' outline>BUTTON</Button>
        <Button color = "gray" outline>BUTTON</Button>
        <Button color = "pink" size='small' outline ={true}>BUTTON</Button>
      </div>
      <div className="buttons">
        <Button size='large' fullWidth={true}>BUTTON</Button>
        <Button color = "gray" fullWidth={true}>BUTTON</Button>
        <Button color = "pink" size='small' fullWidth={true} >BUTTON</Button>
      </div>

해당 부분을 추가해주기만 하면

 

다음과 같이 결과물이 나오게 된다.

 

 

 

 

 

rest

 

<div className="buttons">
        <Button size='large' fullWidth={true}>BUTTON</Button>
        <Button color = "gray" fullWidth={true}>BUTTON</Button>
        <Button 
          color = "pink" 
          size='small' 
          fullWidth={true} 
          onClick={ () => {
          console.log('클릭!');
          }}
          onMouseMove = { () => {
            console.log('마우스무브!')
          }} 
        
        >BUTTON</Button>
      </div>

예를들어 다음과 같이 여러 기능을 계속 추가하는걸 생각해보자. 그때그때 파라미터를 추가해야하고 연결해줘야하는 불편함이 있을 것이다. 이를 rest를 사용하면 보다 편하게 사용할 수 있다.

 

//Button.js
import React from 'react';
import './Button.scss';
import classNames from 'classnames';


// size : large,medium,small
// color : blue,pink,gray
function Button({children,size,color,outline,fullWidth,className,...rest}) {  //rest를 넣어서 기능을 편하게

    return (
        <button className = {classNames('Button',size,color,{
            outline,    //값이 true일때만 classNames로 들어가게 된다
            fullWidth   //값이 true일때만 classNames로 들어가게 된다
        },
            className //className을 받아오면 나중에 따로 추가하지 않아도 자동으로 불러와 수정하기 용이하다
        )}
        
        {...rest} //onClick이나 Mousemove등이 자동으로 입력되게 된다.  

        >{children}</button>
    );
    
}
Button.defaultProps = {
    size : 'medium',
    color : 'blue'
};

export default Button;

다음처럼 rest를 사용하면 굳이 내가 onClick = {onClick} 등의 코드를 작성하지 않아도 괜찮다.

 

 

기능또한 잘 작동하는것을 알 수 있다.

 

 

 

 

728x90

'FrontEnd > React' 카테고리의 다른 글

18_styled-components  (0) 2021.12.27
17_리액트_CSS Module  (0) 2021.12.24
15_리액트_유용한 tool  (0) 2021.12.24
13_리액트_Context API,immer  (0) 2021.12.24
12_리액트_여러 Hook들  (0) 2021.12.23