
CSS-in-JS 는 말 그대로 JS파일에 CSS 스타일을 정의하는 기법이다. 기존에는 HTML, CSS, JS는 각자 별도의 파일로 관리하는 것이 일반적이었지만, 최근에는 컴포넌트를 기반으로한 웹 개발이 대세가 되면서 한 컴포넌트 안에 모든 것을 욱여넣는 방법이 트렌드가 되었다.
Vue의 경우 한 컴포넌트의 기본 구조가 script, template(HTML), style로 이미 정해져 있다. React는 JSX를 사용하여 JS가 HTML을 포함하고 있는 형태를 가지고 있으니, 여기에 CSS-in-JS 라이브러리를 사용하여 스타일도 JS에 집어넣으면 된다.
styled-components, tailwindCSS등의 방법이 있다.
Styled-componentsstyled-components를 사용하면 CSS도 JS 문법을 손쉽게 적용시킬 수 있다.
import React from "react";
import styled from "styled-components";
const StContainer = styled.div`
display: flex;
`;
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor};
margin: 20px;
`;
const boxList = ["red", "green", "blue"];
const getBoxName = (color) => {
switch (color) {
case "red":
return "빨간 박스";
case "green":
return "초록 박스";
case "blue":
return "파란 박스";
default:
return "검정 박스";
}
};
const App = () => {
return (
<StContainer>
{boxList.map((boxColor) => (
<StBox borderColor={boxColor}>{getBoxName(boxColor)}</StBox>
))}
</StContainer>
);
};
export default App;
createGlobalStyle 키워드를 통해 전역에 공통으로 필요한 스타일을 지정할 수 있다.
// GlobalStyle.jsx
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
`;
export default GlobalStyle;
// App.jsx
import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";
function App() {
const title = '전역 스타일링 제목';
const contents = '전역 스타일링 내용';
return (
<>
<GlobalStyle />
<BlogPost title={title} contents={contents} />
</>
);
}
export default App;
브라우저는 각각의 default style을 가진다. 그래서 같은 스타일링이라도 margin이나 글자의 크기 등 브라우저 간 차이가 생길 수 있다. CSS reset은 이런 크로스 브라우징 이슈를 해결하기 위한 기법이다. 방법은 여러가지가 있는데, 그 중 한 가지 방법은 아래 코드를 메인 HTML파일에 적용하는 것이다.
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}