티스토리 뷰

책/리다기

리다기 정리3(css)

안양사람 2021. 1. 20. 00:32
728x90
SMALL

컴포넌트 스타일링

1. CSS selector

ex) .app .logo{~~}

2. Sass

yarn add node-sass

 

$으로 변수, @mixin으로 함수, @include로 함수사용, &.으로 함께 사용 됐을 때

 

utils.scss

//변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;
//믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있음)
@mixin square($size) {
  $calculated: 32px * $size;
  width: $calculated;
  height: $calculated;
}

 

SassComponent.scss

// @import "./styles/utils";
.SassComponent {
  display: flex;
  .box {
    // 일반 CSS 에선 .SassComponent .box 와 마찬가지
    background: red;
    cursor: pointer;
    transition: all 0.3s ease-in;
    &.red {
      // .red 클래스가 .box 와 함께 사용 됐을 때
      background: $red;
      @include square(1);
    }
    &.orange {
      background: $orange;
      @include square(2);
    }
    &.yellow {
      background: $yellow;
      @include square(3);
    }
    &.green {
      background: $green;
      @include square(4);
    }
    &.blue {
      background: $blue;
      @include square(5);
    }
    &.indigo {
      background: $indigo;
      @include square(6);
    }
    &.violet {
      background: $violet;
      @include square(7);
    }
    &:hover {
      // .box 에 마우스 올렸을 때
      background: black;
    }
  }
}

 

SassComponent.js

import React from "react";
import "./SassComponent.scss";

const SassComponent = () => {
  return (
    <div className="SassComponent">
      <div className="box red" />
      <div className="box orange" />
      <div className="box yellow" />
      <div className="box green" />
      <div className="box blue" />
      <div className="box indigo" />
      <div className="box violet" />
    </div>
  );
};

export default SassComponent;

 

yarn eject하고(그전에 git add . git commit -m "eject")

webpack.config.js --sassRegex 찾기

'sass-loader'지우고 concat을 통해 커스터마이징된 sass-loader 설정을 넣어

그러면 절대경로 @import 'utils.scss';

이것도 귀찮으면 prependData: `@import 'utils';` 붙여

sass파일을 불러올 때마다 코드의 맨 윗부분에 특정 코드를 포함시켜 준다.

            {
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders({
                importLoaders: 3,
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
              }).concat({
                loader: require.resolve("sass-loader"),
                options: {
                  sassOptions: {
                    includePaths: [paths.appSrc + "/styles"],
                  },
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  prependData: `@import 'utils';`,
                },
              }),
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },

 

node_modules에서 라이브러리 불러오기

yarn add open-color include-media

 

@import "~include-media/dist/include-media";

@import "~open-color/open-color";

 

.SassComponent {

  display: flex;

  background: $oc-gray-2;

  @include media("<768px") {

    background: $oc-gray-9;

  }

 

3. CSS Module

~~.module.css 확장자로 파일을 저장하면 CSS Module이 적용

:globlal을 붙이면 다른 컴포넌트에서도 .something이 적용(원래 react css는 이래)

/* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용가능*/

.wrapper {
  background: black;
  padding: 1rem;
  color: white;
  font-size: 2rem;
}

/* 글로벌 CSS 를 작성하고 싶다면 */
:global .something {
  font-weight: 800;
  color: aqua;
}

 

스타일이 1개일때와 2개일때

템플릿 리터럴이 싫으면 calssName={[styles.wrapper, styles.inverted].join(' ')}으로 할 수도 있어

    <div className={styles.wrapper}>
      안녕하세요, 저는 <span className="something">CSS Module!</span>
    </div>
    
    <div className={`${styles.wrapper} ${styles.inverted}`}>
      안녕하세요, 저는 <span className="something">CSS Module!</span>
    </div>

 

 

yarn add classnames

 

간략 사용법

import classNames from 'classnames';

classNames('one, 'two');
classNames('one', {two:true});  //'one two'
classNames('one', {two:false}); //'one'

 

CSS Module과 함께 사용하면 CSS Module 사용이 훨씬 쉬워진다. classnames에 내장되어 있는 bind함수 사용

import React from "react";
import classNames from "classnames/bind";
import styles from "./CSSModule.module.css";

const cx = classNames.bind(styles);
const CSSModule = () => {
  return (
    <div className={cx("wrapper", "inverted")}>
      안녕하세요, 저는 <span className="something">CSS Module!</span>
    </div>
  );
};

export default CSSModule;

 

sass와 함께 사용

/* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용가능*/

.wrapper {
  background: black;
  padding: 1rem;
  color: white;
  font-size: 2rem;
  &.inverted {
    color: black;
    background: white;
    border: 1px solid black;
  }
}

/* 글로벌 CSS 를 작성하고 싶다면 */
:global {
  .something {
    font-weight: 800;
    color: aqua;
  }
}

 

4. styled-components

자바스크립트 파일 안에 스타일을 선언하는 방식 'CSS-in-JS'

styled-components와 emotion이 유명

 

vscode-styled-components Extension

 

Tagged 템플릿 리터럴 -- 일반 템플릿 리터럴과 다른 점은 템플릿 안에 자바스크립트 객체나 함수를 전달 할 때 온전히 추출할 수 있다는 점

function tagged(...args){
    console.log(args);
}
tagged`hello ${{foo:'bar'}} ${()=>'world'}!`

(3) [Array(3), {…}, ƒ]
0: (3) ["hello ", " ", "!", raw: Array(3)]
1: {foo: "bar"}
2: ()=>'world'

 

ex

reduce가 여기서도 나와버리네... 코드는 어렵지 않은데 적응할려면 시간이 필요할듯

vscode-styled-compoenets 설치하면 ``사이 색상 정상적으로 나옴

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

const sizes = {
  desktop: 1024,
  tablet: 768
};

// 위에있는 size 객체에 따라 자동으로 media 쿼리 함수를 만들어줍니다.
// 참고: https://www.styled-components.com/docs/advanced#media-templates
const media = Object.keys(sizes).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media (max-width: ${sizes[label] / 16}em) {
      ${css(...args)};
    }
  `;

  return acc;
}, {});

const Box = styled.div`
  /* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
  background: ${props => props.color || 'blue'};
  padding: 1rem;
  display: flex;
  width: 1024px;
  margin: 0 auto;
  ${media.desktop`width: 768px;`}
  ${media.tablet`width: 100%;`};
`;

const Button = styled.button`
  background: white;
  color: black;
  border-radius: 4px;
  padding: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-size: 1rem;
  font-weight: 600;

  /* & 문자를 사용하여 Sass 처럼 자기 자신 선택 가능 */
  &:hover {
    background: rgba(255, 255, 255, 0.9);
  }

  /* 다음 코드는 inverted 값이 true 일 때 특정 스타일을 부여해줍니다. */
  ${props =>
    props.inverted &&
    css`
      background: none;
      border: 2px solid white;
      color: white;
      &:hover {
        background: white;
        color: black;
      }
    `};
  & + button {
    margin-left: 1rem;
  }
`;

const StyledComponent = () => (
  <Box color="black">
    <Button>안녕하세요</Button>
    <Button inverted={true}>테두리만</Button>
  </Box>
);

export default StyledComponent;

 

728x90
LIST

' > 리다기' 카테고리의 다른 글

리다기 정리6(뉴스뷰어 만들기)  (0) 2021.01.22
리다기 정리5(immer, SPA)  (0) 2021.01.22
리다기 정리4(아이콘, 최적화)  (0) 2021.01.21
리다기 정리2(hook)  (0) 2021.01.19
리다기 정리1  (0) 2021.01.18
댓글
공지사항