CSS를 Javascirpt로 작성할 수 있는 장점 + 작업속도 향상을 위해 styled Components라는 것을 사용한다.
npm install styled-components;
우선 파일은 .js로 만든다
import styled from 'styled-components';
const Button = styled.button`
background-color : #123456;
padding : 16px;
`;
export default Button;
즉, styled를 import 해주고, 컴포넌트 이름을 만든 뒤, styled.tagname(tagname부분에는 스타일을 적용할 HTML태그 이름을 쓰면 된다.)을 해주고, 백틱 + 리터럴 문법으로 CSS코드를 적어준다.
그리고, 다른 컴포넌트에서 쓰려면
<Button>Hello styled!</Button>
이런식으로 <button>태그 대신 내가 만든 스타일이 씌어진 button컴포넌트를 쓸 수 있게 된다.
Nesting 문법이란 styled components에서 지원하는 문법이다.
Nesting은 CSS규칙안에서 CSS규칙을 만드는것을 말하고, Nesting을 활용하는 두가지 방법에는 &선택자와 컴포넌트 선택자가 있다.
import styled from 'styled-components';
const Button = styled.button`
background-color : #123456;
padding : 16px;
&:hover {
background-color : #654321;
}
`;
export default Button;
Nesting에서 &은 부모 선택자를 의미한다. 위 코드에서는 버튼 컴포넌트의 클래스를 뜻하는 것이다.
버튼안에 아이콘을 배치하는ㄴ 상황으로 예를 들어보면, 버튼 텍스트 왼쪽에 아이콘을 배치하고 그 사이에 마진을 4px를 주려고 하는 가정이다. 우선 styledComponents로 Icon과 styledButton 컴포넌트를 각각 만들고, StyledButton안에 Icon을 배치한다. 이때, StyledButton컴포넌트 안에서 Icon컴포넌트를 선택해서 별도로 margin-right : 4px라는 속성을 지정해보자.
import styled from 'styled-components';
import img from 'assets/img';
const Icon = styled.img`
width : 16px;
hegith : 16px;
`;
const StyledButton = styled.button`
background-color : #123456;
border : none;
padding : 16px;
&${Icon} {
margin-right : 4px;
}
&:hover {
background-color : #654321;
&{Icon} {
opacity : 0.2;
}
}
`;
function Button ({children}) {
return (
<StyledButton>
<Icon src={img} alt="Icon-image" />
{children}
</StyledButton>
)
}
이럴 경우, 컴포넌트를 선택자로 쓰고 싶을때 ${Icon}과 같이 컴포넌트 자체를 템플릿 리터럴 안에 넣어주면 된다.
자손 결합자로 쓴 &${Icon}과 &을 사용하는 경우에는 &을 생략할 수 있는데, 보통 간편하게 많이 쓰니까 자손 결합자로 Nesting할때는 생략하는것을 권장한다.
참고로 Nesting은 위 코드 처럼 여러겹으로 할수도 있다. Nesting된 규칙안에서 규칙을 만들 수 있다는것이다.
import styled from 'styled-components';
const SIZES = {
large : 24,
medium : 20,
small : 16,
};
const Button = styled.button`
background-color : #000000;
border-radius : ${({round}) => round ? `9999px` : `3px`};
font-size : ${({size}) => SIZES[size] ?? SIZES['medium']}px;
`;
export default Button;
//App.js
function App() {
return (
<Button round size="large">large Button</Button>
// Button컴포넌트에 round가 있고(9999px), size는 large니까 SIZES['large']
)
}
이렇게 자바스크립트 코드를 삽입할 수 있다. JSX에서 prop이나 state에 따라 HTML태그를 다르게 보여주는것과 비슷하다.
이렇게 사용할 때 size Prop에 값이 없거나 잘못된 값이면 styled Component는 undefined값을 빈 문자열로 처리해주기 때문에 font-size : px와 같이 잘못된 CSS코드가 된다. 그래서 널 병합연산자(??)라던가 삼항 연산자를 통해 Prop이 없을때의 경우를 정해주는것이 올바르다.
핵심 :
예시 :
const SubmitButton = styled(Button)`
background-color : #de117d;
&:hover {
background-color : #f5070f;
}
`;
예시 :
function TermsOfService({className}) {
return (
<div className={className}>/*내용*/</div>
)
}
// styled component
const TermsOfServiceStyle = styled(TermsOfService)`
background-color : #ededed;
border-radius : 8px;
padding : 16px;
`;
예시 :
const Button = styled.button`
font-size = ${({size}) => SIZES[size] ?? SIZES['medium']}px;
const Input = styled.input`
font-size : ${({size}) => SIZES[size] ?? SIZES['medium']}px;
`;
`;
이와 같이 중복된 코드가 생긴다면 유지보수에 귀찮아진다.
예시 :
const SIZES = {
large : 24,
medium : 20,
small : 16,
};
// 재사용 가능한 스타일 정의
const fontSize : css`
font-size : ${({size}) => SIZES[size] ?? SIZES['medium']}px;
`;
// 컴포넌트에서 이를 재사용
const Button = styled.button`
${fontSize}
`;
const Input = styled.input`
${fontSize}
`;
최상위 컴포넌트에 선언한다.
const GlobalStyled = createGlobalStyle`
* {
box-sizing : border-box;
margin : 0;
padding : 0;
}
body {
font-family : sans-serif;
}
`;
const App() {
return (
...
<GlobalStyled />
...
)
}
@keyframes bounce {
0% {
transform : translateY(0%);
}
50% {
transform : translateY(-100%);
}
100% {
transform : translateY(0%);
}
}
.ball {
animation : bounce 1s infinite;
}
이렇게 사용하는데, styled-components에선
1. keyframes라는 함수를 사용해 키프레임 애니메이션을 정의한다.
2. 이 함수는 javascript객체 형태로 키프레임 정보를 반환하며, styled-components내부에서 애니메이션으로 사용할 수 있다.
예 :
import styled, {keyframes} from 'styled-components';
// 1. keyframes함수로 애니메이션 정의
const bounce = keyframes`
0% {
transform : translateY(0%);
}
50% {
transform : translateY(-100%);
}
100% {
transform : translateY(0%);
}
`;
// 2. styled-components에 애니메이션 적용
const ball = styled.div`
width : 50px;
height : 50px;
background-color : red;
border-radius : 50%;
animation : ${bounce} 1s infinite;
`;
// 3. React 컴포넌트에서 사용
function App() {
return <Ball />
}
keyframs함수가 반환하는 값은 단순한 CSS문자열이 아닌, JS객체로 반환되며, CSS규칙과 관련된 여러 정보를 포함한다.
핵심 :
1. Styled-Components에서 반드시 keyframes함수를 사용
2. Template Literal 형태로 삽입
테마란?
styled-components에서는 ThemeProvider를 사용해 쉽게 테마를 설정하고 활용할 수 있다.
애니메이션
키프레임
1. 애니메이션의 기준점
#css
@keyframs bounce {
0% {
transform : translateY(0%);
}
50% {
transform : translateY(-100%);
}
100% {
transform : translateY(0%);
}
}
.ball {
animation : bounce 1s infinite;
}
styled-Components에서 키프레임 사용하기
1. Styled-Components에서는 keyframes라는 함수를 사용해 키프레임 애니메이션을 정의한다.
예:
import styled, {keyframes} from 'styled-components';
//1. keyframes함수로 애니메이션 정의
const bounce = keyframes 0% { transform : translateY(0%); } 50% { transform : translateY(-100%); } 100% { transform : translateY(0%); };
// 2. styled-components에 애니메이션 적용
const ball = styled.div width : 50px; height : 50px; background-color : red; border-radius : 50%; animation : ${bounce} 1s infinite;;
// 3. React 컴포넌트에서 사용
function App() {
return
}
Keyframes함수의 반환값
keyframes 함수가 반환하는 값은 단순한 CSS문자열이 아니다. JS객체로 반환되며, CSS규칙과 관련된 여러 정보를 포함한다.
핵심요약
1. Styled-Components에서 반드시 keyframes를 사용
테마와 ThemeProvider
테마란?
styled Components에서는 ThemeProvider를 사용해 쉽게 테마를 설정하고 활용할 수 있다.
애니메이션
키프레임
1. 애니메이션의 기준점
#css
@keyframs bounce {
0% {
transform : translateY(0%);
}
50% {
transform : translateY(-100%);
}
100% {
transform : translateY(0%);
}
}
.ball {
animation : bounce 1s infinite;
}
styled-Components에서 키프레임 사용하기
1. Styled-Components에서는 keyframes라는 함수를 사용해 키프레임 애니메이션을 정의한다.
예:
import styled, {keyframes} from 'styled-components';
//1. keyframes함수로 애니메이션 정의
const bounce = keyframes 0% { transform : translateY(0%); } 50% { transform : translateY(-100%); } 100% { transform : translateY(0%); };
// 2. styled-components에 애니메이션 적용
const ball = styled.div width : 50px; height : 50px; background-color : red; border-radius : 50%; animation : ${bounce} 1s infinite;;
// 3. React 컴포넌트에서 사용
function App() {
return
}
Keyframes함수의 반환값
keyframes 함수가 반환하는 값은 단순한 CSS문자열이 아니다. JS객체로 반환되며, CSS규칙과 관련된 여러 정보를 포함한다.
핵심요약
1. Styled-Components에서 반드시 keyframes를 사용
테마와 ThemeProvider
테마란?
styled Components에서는 ThemeProvider를 사용해 쉽게 테마를 설정하고 활용할 수 있다.
애니메이션
키프레임
1. 애니메이션의 기준점
#css
@keyframs bounce {
0% {
transform : translateY(0%);
}
50% {
transform : translateY(-100%);
}
100% {
transform : translateY(0%);
}
}
.ball {
animation : bounce 1s infinite;
}
styled-Components에서 키프레임 사용하기
1. Styled-Components에서는 keyframes라는 함수를 사용해 키프레임 애니메이션을 정의한다.
예:
import styled, {keyframes} from 'styled-components';
//1. keyframes함수로 애니메이션 정의
const bounce = keyframes 0% { transform : translateY(0%); } 50% { transform : translateY(-100%); } 100% { transform : translateY(0%); };
// 2. styled-components에 애니메이션 적용
const ball = styled.div width : 50px; height : 50px; background-color : red; border-radius : 50%; animation : ${bounce} 1s infinite;;
// 3. React 컴포넌트에서 사용
function App() {
return
}
Keyframes함수의 반환값
keyframes 함수가 반환하는 값은 단순한 CSS문자열이 아니다. JS객체로 반환되며, CSS규칙과 관련된 여러 정보를 포함한다.
핵심요약
1. Styled-Components에서 반드시 keyframes를 사용
테마와 ThemeProvider
테마란?
styled Components에서는 ThemeProvider를 사용해 쉽게 테마를 설정하고 활용할 수 있다.
1. 기본 테마 설정
ThemeProvider를 사용해 테마 값 설정하기
예시 : 단일 테마 사용
import {ThemeProvider} from 'styled-components';
import Button from './Button';
function App() {
const theme = {
primaryColor : '#1da1f2'; // 테마의 주요 색상 설정
}
return (
<ThemeProvider theme={theme}>
<Button>확인</Button>
</ThemeProvider>
)
}
// Button컴포넌트
const Button = styled.button`
background-color : ${({theme}) => theme.primaryColor};
color : white;
border : none;
cursor : pointer;
`;
function App() {
const [theme, setTheme] = useState({
primaryColor : '#1da1f2', // 초기 테마 색상
});
const handleColorChange = (e) => {
setTheme({
...theme,
primaryColor : e.target.value, // 사용자가 선택한 색상으로 업데이트
});
}
return (
<ThemeProvider theme={theme}>
<select value={theme.primaryColor} onChange={handleColorChange}>
<option value="#1da1f2">blue</option>
<option value="#ffa800">yellow</option>
<option value="#f5005c">red</option>
</select>
<br />
<br />
<Button>확인</Button>
</ThemeProvider>
)
}
import {useContext} from 'react';
import {ThemeContext} from 'styled-components';
function SettingPage() {
const theme = useContext(ThemeContext);
return (
<div>
<h2>현재 테마 색상</h2>
<p>Primary Color : {theme.primaryColor}</p>
</div>
)
}
정리
1. ThemeProvider :
<button>과 <a>태그 모두 스타일이 동일해야 한다면해결 : as Prop사용
예제 :
import styled from 'styled-components';
const Button = styled.button`
background-color : #123456;
cursor : pointer;
`;
// button태그 대신 a태그로 사용하기
function App() {
return (
<>
<Button>Submit</Button>
<Button as="a" href="path">Go to Link</Button>
</>
)
}
결과 :
1. Submit 버튼은 기본 버튼 기능을 수행
2. Go to Link는 a태그처럼 동작하지만 모양은 버튼 모양이 됨