◾ 일반 CSS
◾ Sass - CSS전처리기
◾ CSS Module
◾ styled-components
9️⃣.1️⃣ 일반 CSS, 가장 흔한 방식
CSS클래스를 중복 되지 않게 만드는 것이 중요하다.
1) 이름 짓는 규칙 : ( 컴포넌트 이름 - 클래스 )의 형태로 작성한다.
2) CSS Selector 사용 : .App .logo 처럼 특정 클래스 내부에 있는 경우만 적용한다.
9️⃣.2️⃣ Sass 사용하기
Sass는 CSS 전처리기 이며 작업을 편리하게 해주고, 코드의 재사용 증가, 코드의 가독성을 높여 유지보수를 쉽게 만든다
9️⃣.2️⃣.1️⃣ utils 함수 분리하기
여러 파일에서 사용될 수 없는 Sass 변수 및 믹스인은 다른 파일로 따로 분리하여 작성한 뒤
필요한 곳에서 쉽게 불러와 사용 가능하다.
다른 scss 파일을 가져올 때는 @import './...'; 의 형태로 불러온다
예시 코드⬇⬇⬇⬇
@import '~include-media/dist/include-media'; // 반응형 디자인을 쉽게 만들어주는 라이브러리
@import '~open-color/open-color'; // 편리한 색상 팔래트 라이프러리
// 변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;
// 믹스인 만들기
@mixin square($size) {
$calculated: 32px * $size;
width: $calculated;
height: $calculated;
}
9️⃣.2️⃣.2️⃣ sass-loader 설정 커스터마이징
npm eject
...
react-script eject
...
y
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
},
}).concat({
loader: require.resolve("sass-loader"),
options: {
sassOptions: {
includePaths: [paths.appSrc + "/styles"],
},
},
}),
// 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,
},
위 코드를 터미널에 작성해 준다.
파일을 불러올 때 현재 수정하고 있는 scss 파일 경로가 어디에 위치하더라도
디렉터리 기준 절대 경로를 사용해 불러올 수 있다.
9️⃣.2️⃣.3️⃣ node_modules에서 라이브러리 불러오기
Sass의 장점중 한개는 라이브러리를 쉽게 불러와 사용할 수 있다는 점이다.
파일이 깊은 디렉터리에 있는 경우 @import '~library/styles'; 의 ~을 사용하면 자동으로
node_modules에서 라이브러리 디렉터리를 탐지하여 불러온다.
( Sass라이브러리를 불러올 경우 node_modules 내부 라이브러리 경로 안에 들어있는 scss파일을 불러와야 한다 )
9️⃣.3️⃣ CSS Module
CSS를 불러와 사용 시 [파일명]_[클래스명]_[해시값] 형태로 자동으로 만들어
컴포넌트 스타일 클래스 이름이 중복되는 현상을 방지한다.
.module.css 확장자로 저장하면 CSS Module이 적용된다.
:globar를 앞에 입력하면 글로벌 CSS 명시가 가능하다.
// CSSModule.module.css
/* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용 가능 */
.wrapper{
background: black;
padding: 1rem;
color: white;
font-size: 2rem;
} /*사용시 className={styles.wrapper}의 형식으로 사용*/
.inverted{
color: black;
background: white;
border: 1px solid black;
}
/*글로벌 CSS 작성시 */
:global .something{
font-weight: 800;
color: aqua;
} /*사용시 className="something"의 형식으로 사용*/
두개 이상의 클래스를 적용할 경우 백틱을 이용해 ` ${...} ${...} ` 형식으로 사용한다.
9️⃣.3️⃣.1️⃣ classnames (라이브러리)
CSS 클래스를 조건부로 설정할 때 유용한 라이브러리이다.
import classNames from 'classnames';
...
const MyComponent = ({highlighted, theme}) => (
<div className={`MyComponent ${theme} ${highlighted ? `highlighted` : ``}`>
안녕
</div>
);
classnames 내장 함수인 bind를 사용해 styles.[이름]의 형태를 cx('이름', '이름') 형식으로 사용 가능하다.
import classNames from 'classnames/bind';
...
const cx = classNames.bind(styles); //미리 styles에서 클래스를 받아오게 설정
...
<div className={cx('wrapper', 'inverted'}>
...
조건부 혹은 여러개를 설정할 때 bind의 효율이 좋아진다.
9️⃣.3️⃣.2️⃣ Sass와 함께 사용
Sass를 사용할 때도 .module.scss확장자를 사용해주면 CSS Module을 사용할 수 있다.
9️⃣.3️⃣.3️⃣ CSS Module이 아닌 파일에서 CSS Module 사용하기
CSS Module에서 글로벌 클래스 정의시 :global을 사용했던 것 처럼,
일반 .css / .scss 파일에서도 :local을 사용하여 CSS Module을 사용할 수 있다.
9️⃣.4️⃣ styled-components ( 라이브러리 )
JS파일 안에서 스타일을 선언하는 방식이다. CSS-in-JS라고 부른다.
styled-component를 사용하면 .css 또는 .scss 파일을 따로 만들지 않아도 된다.
예시코드⬇⬇⬇⬇
import styled, { css } from 'styled-components';
// 단순 변수의 형태가 아니라 여러 줄의 스타일 구문을 조건부로 설정하려면 css를 불러와야 한다.
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`
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
/* 기본적으로 가로 1024px에 가운데 정렬하고 가로 크기가 작아질 수록 크기를 줄이고 768px미만이 되면 꼭 채워줌 */
width: 1024px;
margin: 0 auto;
/* media 쿼리 함수 사용 */
${media.desktop`width: 768px;`}
${media.tablet`width: 100%;`}
/* media 쿼리 함수 미사용 */
/* @media(max-width: 1024px){
width: 768px;
}
@media(max-width: 768px){
width: 100%;
} */
`;
/* & 문자를 사용해 Sass처럼 자기 자신을 선택 가능하다 */
const Button = styled.button`
background: white;
color: black;
border-radius: 4px;
padding: 0.5rem;
display; flex;
align-item: center;
justify-content: center;
box-sizing: border-box;
font-size: 1rem;
font-weight: 600;
&:hover{
background: rgba(255, 255, 255, 0.9);
}
${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;
9️⃣.4️⃣.1️⃣ Tagged 템플릿 리터럴
백틱을 이용해 문자열에 스타일 정보를 넣어준다.
CSS Module의 일반 탬플릿 리터럴과 다른 점은 탬플릿 안에 JS 객체나 함수를 전달할 때 온전히 추출할 수 있다
`hello ${{ foo: bar }} ${() => 'world'!}`
// "hello [object Object] () => 'world'!"
탬플릿에 객체나 함수를 넣으면 형태를 잃는다.
이런 특징을 이용해 styled-components로 만든 컴포넌트의 props를 스타일 쪽에서 쉽게 조회할 수 있도록 해준다.
9️⃣.4️⃣.2️⃣ 스타일링된 엘리먼트 만들기
컴포넌트 파일의 상단에서 styled를 불러오고, styled.태그명 을 사용해 구현한다.
기본 형태)
import stlyed from 'styled-components';
const MyComponent = styled.div`
font-size: 2rem;
`;
태그명이 유동적이거나 특정 컴포넌트 자체 스타일링이 필요한 경우는 아래의 코드처럼 이용하자
cost MyInput = styled('import')`
backgroun: black;
`
const StyledLink = styled(Link)`
color: blue;
`
9️⃣.4️⃣.3️⃣스타일에서 props 조회하기
styled-components를 사용하면 스타일 쪽에서 컴포넌트에게 전달된 props값을 참조 가능하다.
const Box = styled.div`
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
`;
9️⃣.4️⃣.4️⃣ props에 따른 조건부 스타일링
styled-components에서는 조건부 스타일링을 props로 간단하게 처리가 가능하다.
import styled, { css } from 'styled-components';
// 단순 변수의 형태가 아니라 여러 줄의 스타일 구문을 조건부로 설정하려면 css를 불러와야 한다.
(...)
${props =>
props.inverted &&
css`
background:none;
border: 2px solid white;
(...)
&:hover{
background: white;
color: black;
}
`};
css를 넣지 않고 바로 문자열을 넣어도 작동이 되지만 Tagged 템플릿 리터럴이 아니기 때문에
함수를 받아 사용하지 못해 해당 부분에서는 props값을 사용하지 못한다.
9️⃣.4️⃣.5️⃣ 반응형 디자인
media 쿼리를 사용하면 된다.
const Box = styled.div`
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
/* 기본적으로 가로 1024px에 가운데 정렬하고 가로 크기가 작아질 수록 크기를 줄이고 768px미만이 되면 꼭 채워줌 */
width: 1024px;
margin: 0 auto;
/* media 쿼리 함수 사용 */
${media.desktop`width: 768px;`}
${media.tablet`width: 100%;`}
/* media 쿼리 함수 미사용 */
/* @media(max-width: 1024px){
width: 768px;
}
@media(max-width: 768px){
width: 100%;
} */
`;
작업을 함수화 하여 간단하게 사용 가능하다.
'React' 카테고리의 다른 글
React) 11장 컴포넌트 최적화 (0) | 2022.04.19 |
---|---|
React) 10장 TodoList 프로젝트 (0) | 2022.04.17 |
React) 8장 Hooks (0) | 2022.04.12 |
React) 6장 컴포넌트 반복 (0) | 2022.04.12 |
React) 5장 ref:DOM에 이름 달기 (0) | 2022.04.12 |