[React를 다루는 기술] 9장 - 컴포넌트 스타이링
🎉 Component Styling
😉 CSS
🐱🐉 이름 짓는 규칙
- 컴포넌트를 스타일링하는 가장 기본적인 방식
- class name은 “컴포넌트 이름-클래스” 형태로 지어야 충돌이 나지 않는다
🐱🐉 CSS selector 활용
- 특정 클래스 내부에 있는 경우에만 스타일 적용하기
- .App .logo 처럼 .App 클래스 내부에 .logo만 적용하게 만들기
😉 Sass 사용하기
- Syntactically Awesome Style Sheets
- 자주 사용되는 CSS 전처리기 중 하나로 확장된 CSS 문법을 사용하여 CSS 코드를 더욱 쉽게 작성할 수 있도록 해준다.
- .scss와 .sass의 두 가지 확장자 지원
// .sass
$font-stack: Helvetica, sans-serif
$primary-color: #333
body
font: 100% $font-stack
color: $primary-folor // 변수 사용
//.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-folor;
}
-
CSS selector 편리하게 사용
- 클래스{} 안에 클래스 적용하면 동일한 기능.
- SassComponet 클래스 안에 있는 .box 클래스 사용
.SassComponent{
.box{
...
}
}
// box 이면서 red 일때 ex)
.SassComponent{
.box{
&.red
}
}
-
mixin : 재사용되는 스타일 블록을 함수처럼 사용가능
- @mixin 함수이름($파라미터){ css 속성 }
@mixin square($size) {
$calculation: 32px * $size;
width: $calculation;
height: $calculation;
}
// 적용하기
&.red {
@include square(1);
}
- 스타일 적용하는 JS에 import ‘./SassComponent.scss’
😉 CSS Module
- 스타일을 작성할 때 CSS 클래스가 다른 CSS 클래스의 이름과 절대 충돌하지 않도록 파일마다 고유한 이름을 자동으로 생성해 주는 옵션
- [파일 이름]_[클래스 이름]__[해시값] 형태
- .module.css 확장자로 파일을 저장하면 자동으로 CSS Module이 적용됨
import React from "react";
import styles from "./CSSModule.module.css"; // scss 도 가능
// 1. css파일로 module 만들기
/* CSSModule.module.css -> CSSModule_wrapper__1dasg 이런 식으로 고유하게 생성됨
.wrapper{
...
}
:global .something{
...
}*/
/*
CSS Module이 아닌데 쓰는 방법
일반 파일 확장자 ( Module.css, Module.scss를 안쓴)
클래스 앞에 :local 붙이기
*/
// 2. classnames로 css 클래스 조건부 설정하기
// import classNames from "classnames";
// 3. CSS 모듈과 같이 사용 : bind 함수를 사용하여 CSS Module의 styles.[클래스 이름]에서 styles.를 제거
// const cx = classNames.bind(styles)
export default function CSSModule() {
// export default function CSSModule({highligted, theme) {
return (
<div className={`${styles.wrapper} ${styles.inverted}`}>
{/*classnemes('one', {two: false})*/} // 결과값 one
{/* <div className={classNames("MyComponent", { highlighted }, theme)}> */}
{/* 이 경우 highlight가 props라면 true, false에 의해 보여짐 theme은 문자열이라 하면 내용 그대로 쓰면 적용됨 */}
{/* <div className={`MyComponent ${theme} ${highlighted ? 'highlighted' : ''}`}> */}{" "}
// class name을 안 쓸 경우
{/* <div className={[styles.wrapper, styles.inverted].join(' ')}> */} //
클래스 2개 이상 넣어야 할 떄
{/* <div className={`${styles.wrapper} ${styles.inverted}`}> */} // 클래스
2개 이상 넣어야 할 떄 Hi <span className="something">CSS Module</span> //
global로 선언된 전역 스타일 그냥 문자열로 넣는다
{/* bind 함수 이용 */}
{/* <div className={cx("wrapper", "inverted")}></div> */}
</div>
);
}
😉 Styled-components
- 자바스크립트 파일 안에 스타일 선언하기 ( CSS-in-JS 방식 )
- 컴포넌트 기반 개발 방법이 주류 각 컴포넌트에 HTML, CSS, JavaScript를 몽땅 때려 박는 패턴이 많이 사용
- Tagged Template Literals(ES6)을 사용해서 스타일 정의
- 백틱(`) 을 사용하여 문자열과 변수를 함께 사용할 수 있어 문자열 처리에 유용한 기능, 함수 형태로도 사용 가능
import styled from "styled-components";
import Button from "./Button";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
const StyledButton = styled.button`
// 고정 스타일링
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
background: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
const media = Object.keys(sizes).reduce((acc, label) => {
acc[label] = (...args) => css`
@media (max-width: ${sizes[label] / 16}em) {
${css(...args)};
}
`;
return acc;
}, {});
const StyledButton = styled.button`
// 가변 스타일링
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
${media.desktop`width: 768px`}
${media.tablet`width:100%`}
`;
/* @media (max-width: 1024px) {
width: 768px;
}
@media (max-width: 768px) {
width: 100%;
} */
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
);
}
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
// 가변 스타일링 2 바꾸고 싶은 속성이 여러개 일 경우
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
/* & 문자를 사용하여 Sass처럼 자기 자신 선택 가능 */
&:hover {
background: rgba(255, 255, 255, 0.9);
}
/* 다음 코드는 primary 값이 존재하는 경우 특정 스타일을 부여해 줍니다 */
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
/* 반응형 디자인 설정 */
@media (max-width: 1024px) {
width: 768px;
}
`;
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
Leave a comment