PageSourceSearch

https://pyjun01.github.io/component---src-pages-v-mdx-parent-file-…-blog-css-in-js-mdx-0265d7109475e87f2632.js

js pyjun01.github.io collected 2026-10-03 09:48:04 UTC 24,751 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkpyjun01_blog=self.webpackChunkpyjun01_blog||[]).push([[268],{6869:function(e,n,t){t.r(n),t.d(n,{default:function(){return te}});var l=t(6540),r=t(8453);function a(e,n){return n||(n=e.slice(0)),e.raw=n,e}var s=t(1510);const c="undefined"!=typeof window;var o=t(4848);const m=s.default.div.withConfig({displayName:"Result__ResultWrapper",componentId:"sc-1jvsvol-0"})(["margin:1.5rem 0;border:1px solid #cdcdcd;> p{margin:0;padding:0.5rem 1rem;border-bottom:1px solid #cdcdcd;}> div{padding:1rem;max-height:370px;overflow-y:scroll;*{margin:0;padding:0;}}"]);var i=function(e){let{children:n}=e;return(0,o.jsxs)(m,{children:[(0,o.jsx)("p",{children:"Demo"}),(0,o.jsx)("div",{children:c&&n})]})};function u(e,n){if(null==e)return{};var t={};for(var l in e)if({}.hasOwnProperty.call(e,l)){if(n.includes(l))continue;t[l]=e[l]}return t}const d=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"],p=["children"],E=function(e){const n=[e[0]];for(let t=0,l=arguments.length<=1?0:arguments.length-1;t<l;t++)n.push(t+1<1||arguments.length<=t+1?void 0:arguments[t+1],e[t+1]);return n.join("")};function h(e){return function(n){for(var t=arguments.length,l=new Array(t>1?t-1:0),r=1;r<t;r++)l[r-1]=arguments[r];const a=E.apply(void 0,[n].concat(l));return function(n){let{children:t}=n,l=u(n,p);return(0,o.jsxs)(e,Object.assign({},l,{children:[(0,o.jsxs)("p",{children:["style: ",a]}),t]}))}}}d.forEach((e=>{h[e]=h(e)}));var g,y,f=h;const x=f.div(g||(g=a(["\n  display: flex;\n  justify-content: space-between;\n  color: ",";\n"])),"#f00"),j=f.span(y||(y=a(["\n  color: #000;\n  font-weight: bold;\n"])));var S=function(){return(0,o.jsx)(i,{children:(0,o.jsxs)(x,{children:["Hello,",(0,o.jsx)(j,{children:"World!"})]})})};let b=function(){function e(){c&&document.head.appendChild(this.tag=document.createElement("style"))}return e.get=function(){return e.item||(e.item=new e),c&&!e.item.tag&&document.head.appendChild(e.item.tag=document.createElement("style")),e.item},e.prototype.generateClassName=function(e){if(!c)return"";const n="hash"+e.split("").reduce(((e,n)=>0|(e<<5)-e+n.charCodeAt(0)),0);const t="."+n+" { "+e+" }";return!this.tag.innerText.includes(t)&&this.tag.appendChild(document.createTextNode(t)),n},e}();var v=()=>b.get();const C=["children"],N=function(e){const n=[e[0]];for(let t=0,l=arguments.length<=1?0:arguments.length-1;t<l;t++)n.push(t+1<1||arguments.length<=t+1?void 0:arguments[t+1],e[t+1]);return n.join("")};function w(e){return function(n){for(var t=arguments.length,l=new Array(t>1?t-1:0),r=1;r<t;r++)l[r-1]=arguments[r];const a=N.apply(void 0,[n].concat(l)),s=v().generateClassName(a);return function(n){let{children:t}=n,l=u(n,C);return(0,o.jsx)(e,Object.assign({},l,{className:s.concat(l.className?" "+l.className:""),children:t}))}}}d.forEach((e=>{w[e]=w(e)}));var T,A,k=w;const L=k.div(T||(T=a(["\n  display: flex;\n  justify-content: space-between;\n  width: 100%;\n  color: ",";\n"])),"#f00"),$=k.span(A||(A=a(["\n  color: #000;\n  font-weight: bold;\n"])));var W=function(){return(0,o.jsx)(i,{children:(0,o.jsxs)(L,{children:["Hello,",(0,o.jsx)($,{children:"World!"})]})})};const H=["children"],J=function(e){const n=[e[0]];for(let t=0,l=arguments.length<=1?0:arguments.length-1;t<l;t++)n.push(t+1<1||arguments.length<=t+1?void 0:arguments[t+1],e[t+1]);return n.join("")};function O(e){return function(n){for(var t=arguments.length,l=new Array(t>1?t-1:0),r=1;r<t;r++)l[r-1]=arguments[r];const a=J.apply(void 0,[n].concat(l)),s=v().generateClassName(a);return function(n){let{children:t}=n,l=u(n,H);return(0,o.jsx)(e,Object.assign({},l,{className:s.concat(l.className?" "+l.className:""),children:t}))}}}
1d.forEach((e=>{O[e]=O(e)}));var _,R,F,P=O;const z=P.div(_||(_=a(["\n  display: flex;\n  justify-content: space-between;\n  width: 100%;\n  color: ",";\n"])),"#f00"),V=P.span(R||(R=a(["\n  color: #000;\n  font-weight: bold;\n"]))),D=P(z)(F||(F=a(["\n  justify-content: center;\n  color: #666;\n"])));var G=function(){return(0,o.jsx)(i,{children:(0,o.jsxs)(D,{children:["Hello,",(0,o.jsx)(V,{children:"World!"})]})})};function I(e){const n=Object.assign({p:"p",h1:"h1",code:"code",a:"a",pre:"pre",ul:"ul",li:"li",ol:"ol",strong:"strong",hr:"hr"},(0,r.RP)(),e.components),{TableOfContents:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("TableOfContents",!0),l.createElement(l.Fragment,null,l.createElement(t),"\n",l.createElement(n.p,null,"이 포스트는 styled-components를 리버스 엔지니어링 하면서 얻은 지식을 이용해 간단한 CSS-in-JS 시스템을 만들어보는 내용이다."),"\n",l.createElement(n.h1,null,"1. CSS-in-JS?"),"\n",l.createElement(n.p,null,"CSS-in-JS란 스타일링에 ",l.createElement(n.code,null,"Javascript"),"를 사용하는 ",l.createElement(n.code,null,"CSS")," 방법론이다. 그렇다면 ",l.createElement(n.code,null,"CSS"),"만 사용해도 잘만 스타일링이 될텐데 왜 스타일링에 ",l.createElement(n.code,null,"Javascript"),"를 사용할까?"),"\n",l.createElement(n.p,null,"웹 문서의 삼위일체인 ",l.createElement(n.code,null,"HTML"),", ",l.createElement(n.code,null,"CSS"),", ",l.createElement(n.code,null,"Javascript"),"는 깔끔한 관심사 분리를 제공한다.",l.createElement("br"),l.createElement(n.code,null,"HTML"),"은 웹 문서의 구조를 만들고 ",l.createElement(n.code,null,"CSS"),"는 UI 스타일링을 담당하고 ",l.createElement(n.code,null,"Javascript"),"는 동적인 기능들을 담당했다. 과거 콘텐츠의 대부분은 정적이였기 때문에 별다른 어려움 없이 스타일링 작업을 할 수 있었다."),"\n",l.createElement(n.p,null,"그러나 시간이 지남에 따라 ",l.createElement(n.code,null,"Javascript"),"가 엄청난 속도로 발전하면서 완전히 새로운 개발 생태계(SPA)가 도래했다."),"\n",l.createElement("figure",null,l.createElement("img",{src:"/css-in-js/spa.jpeg",alt:"SPA EVERYWHERE"})),"\n",l.createElement(n.p,null,"SPA에서는 더욱 복잡하고 동적인 콘텐츠, 기능, 구조들이 추가됐다.",l.createElement("br"),"점점 웹의 규모가 커지고 컴포넌트화 되면서 CSS 작업에 ",l.createElement(n.a,{href:"https://speakerdeck.com/vjeux/react-css-in-js?slide=2"},"여러가지 문제들"),"이 발생했고, 해결법으로 CSS-in-JS가 등장한 것이다."),"\n",l.createElement("figure",null,l.createElement("img",{src:"/css-in-js/css-problem.png"}),l.createElement("figcaption",null,"React: CSS in JS, vjeux (November 08, 2014)")),"\n",l.createElement(n.p,null,"이제 직접 React CSS-in-JS 시스템을 만들어 보자."),"\n",l.createElement(n.h1,null,"2. Tagged templates"),"\n",l.createElement(n.p,null,"만들 시스템은 styled-components를 기반으로 하므로 먼저 Tagged templates에 대해 이해가 필요하다."),"\n",l.createElement(n.p,null,"템플릿 리터럴(`)의 기능중 하나인 Tagged templates는 템플릿 리터럴을 파싱하여 함수의 인자로 넘길 수 있게 해준다."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-javascript"},"fn`some string here` === fn(['some string here']); // 🟢 true\n")),"\n",l.createElement(n.p,null,"첫번째 인자로 문자열 배열, 나머지 인자들로 삽입된 표현식을 받으며, 인자로 템플릿 리터럴을 직접 넘기는 것과 달리 표현식 값들의 타입을 유지한채 인자로 받을 수 있다는 장점이 있다."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-javascript"},"const aVar = 'good';\n\nfn`this is a ${aVar} day` === fn(['this is a ', ' day'], aVar); // 🟢 true\n\nfn`${true} === \"true\"` === fn([' === \"true\"'], true); // 🔴 false\nfn`${true} === \"true\"` === fn(['', ' === \"true\"'], true); // 🟢 true\n\nfn`${true} === ${false}` === fn(['', ' === ', ''], true, false); // 🟢 true\n")),"\n",l.createElement(n.p,null,"Tagged templates로 받은 인자를 다시 원래 string 형태로 변경하는 함수를 만들어 보자."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-javascript"},"const getStyle = (styleStringArray, ...interpolations) =>
1 {\n  const result = [styleStringArray[0]];\n\n  for (let i = 0, len = interpolations.length; i < len; i ++) {\n    result.push(interpolations[i], styleStringArray[i + 1]);\n  }\n\n  return result.join('');\n}\n\n\nconst color = '#f00';\n\ngetStyle`\n  display: flex;\n  color: ${color};\n` === `\n  display: flex;\n  color: ${color};\n` // 🟢 true\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L5: 배열에 [문자열, 표현식, 문자열, 표현식...] 순서로 값을 정렬해준다."),"\n",l.createElement(n.li,null,"L8: 정렬된 배열을 string으로 합치면 원본 템플릿 리터럴 값이 나온다."),"\n"),"\n",l.createElement(n.p,null,"위 코드는 styled 함수에서 사용될 예정이다."),"\n",l.createElement(n.h1,null,"3. styled"),"\n",l.createElement(n.p,null,"Tagged templates를 기반으로 ",l.createElement(n.code,null,"styled")," 함수를 만들어 보자. 함수는 아래 순서로 작동할 것이다."),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"타겟 태그 or 컴포넌트를 받는다."),"\n",l.createElement(n.li,null,"Tagged templates로 css를 받는다."),"\n",l.createElement(n.li,null,"css style이 적용된 컴포넌트를 return 한다."),"\n"),"\n",l.createElement(n.p,null,"먼저 style을 적용하지 않고 컴포넌트를 return 하는 부분까지 코드를 구성해보자."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"function styled(Tag) {\n  // Tagged templates로 style을 받는 함수를 return 한다\n}\n\nconst domElements = ['a', 'abbr', 'address', 'area', ...]; // 전체 태그 리스트\n\ndomElements.forEach(domElement => {\n  styled[domElement] = styled(domElement); // styled.div 형식 대응\n});\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L2: ",l.createElement(n.code,null,"styled")," 함수는 Tagged templates로 style을 받는 함수를 return 해야 한다."),"\n",l.createElement(n.li,null,"L8: HTML 태그의 경우 ",l.createElement(n.code,null,"styled('div')"),"가 아니라 ",l.createElement(n.code,null,"styled.div")," 형식을 주로 사용하므로, 전체 태그들을 속성으로 실행할 수 있도록 추가해준다."),"\n"),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"function styled(Tag) {\n  return function templateFunction(styleStringArray, ...interpolations) {\n    // Tagged templates를 설명할때 만든 getStyle을 그대로 사용한다.\n    const style = getStyle(styleStringArray, ...interpolations);\n\n    // 컴포넌트를 return 한다\n  }\n}\n\nconst domElements = ['a', 'abbr', 'address', 'area', ...];\n\ndomElements.forEach(domElement => {\n  styled[domElement] = styled(domElement);\n});\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L4: Tagged templates로 받은 파라미터는 ",l.createElement(n.code,null,"getStyle")," 함수로 실제 style과 동일하게 변경시켜 준다."),"\n",l.createElement(n.li,null,"L6: ",l.createElement(n.code,null,"templateFunction")," 에서 컴포넌트를 return 해주면 기본적인 ",l.createElement(n.code,null,"styled")," 함수는 마무리 된다."),"\n"),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"function styled(Tag) {\n  return function templateFunction(styleStringArray, ...interpolations) {\n    const style = getStyle(styleStringArray, ...interpolations);\n\n    return function WrappedStyledComponent({ children, ...props }) {\n      return (\n        <Tag {...props}>\n          <p>style: {style}</p>\n          {children}\n        </Tag>\n      );\n    }\n  }\n}\n\nconst domElements = ['a', 'abbr', 'address', 'area', ...]; // 전체 태그 리스트\n\ndomElements.forEach(domElement => {\n  styled[domElement] = styled(domElement); // styled.div 형식 대응\n});\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L7: 컴포넌트의 props들은 타겟 컴포넌트에 그대로 넘겨준다."),"\n",l.createElement(n.li,null,"L8: style은 적용하지는 않고 일단 화면에 표시하도록 한다."),"\n"),"\n",l.createElement(n.p,null,"전체 코드는 아래와 같다."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"styled.jsx")),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"const getStyle = (styleStringArray, ...interpolations) =>
1 {\n  const result = [styleStringArray[0]];\n\n  for (let i = 0, len = interpolations.length; i < len; i++) {\n    result.push(interpolations[i], styleStringArray[i + 1]);\n  }\n\n  return result.join('');\n};\n\nfunction styled(Tag) {\n  return function templateFunction(styleStringArray, ...interpolations) {\n    const style = getStyle(styleStringArray, ...interpolations);\n\n    return function WrappedStyledComponent({ children, ...props }) {\n      return (\n        <Tag {...props}>\n          <p>style: {style}</p>\n          {children}\n        </Tag>\n      );\n    }\n  }\n}\n\nconst domElements = ['a', 'abbr', 'address', 'area', ...]; // 전체 태그 리스트\n\ndomElements.forEach(domElement => {\n  styled[domElement] = styled(domElement);\n});\n\nexport default styled;\n")),"\n",l.createElement(n.p,null,"이제 실제 App에 적용하고 결과를 확인해보자."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"App.jsx")),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"import styled from './styled';\n\nconst color = '#f00';\n\nconst Container = styled.div`\n  display: flex;\n  justify-content: space-between;\n  color: ${color};\n`;\n\nconst World = styled.span`\n  color: #000;\n  font-weight: bold;\n`;\n\nfunction App() {\n  return (\n    <Container>\n      Hello,\n      <World>World!</World>\n    </Container>\n  );\n}\n\nexport default App;\n")),"\n",l.createElement(S),"\n",l.createElement(n.p,null,'"Hello, World!" 텍스트와 함께 적용할 style이 잘 표시되는걸 볼 수 있다.'),"\n",l.createElement(n.hr),"\n",l.createElement(n.p,null,"이제 style을 컴포넌트에 직접 적용을 해보자. 적용을 하려면 css style을 추가할 ",l.createElement(n.code,null,"<style>")," Element와 style이 적용될 className이 필요하다."),"\n",l.createElement(n.p,null,"style을 관리할 ",l.createElement(n.code,null,"Sheet class"),"를 만들어 보자."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-js"},"class Sheet {\n  constructor() {\n    document.head.appendChild(this.ele = document.createElement('style'));\n  }\n\n  // className을 생성하는 함수가 필요하다.\n}\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L3: 생성자 내에서 head에 ",l.createElement(n.code,null,"<style>")," Element를 생성해준다."),"\n",l.createElement(n.li,null,"L3: 생성한 ",l.createElement(n.code,null,"<style>")," Element는 ",l.createElement(n.code,null,"ele")," 속성으로 저장한다."),"\n"),"\n",l.createElement(n.p,null,"className은 style에 따라 유니크하게 생성해야 하므로 hash 함수를 만들어준다."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-js"},"const hash = (s) =>\n  `hash${s.split('').reduce((num, t) => {\n    num = (num << 5) - num + t.charCodeAt(0);\n\n    return num & num;\n  }, 0)}`;\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"hash 함수로 스타일을 넘기면 ",l.createElement(n.code,null,"hash${hashedStyle}")," 형식의 문자열을 return 한다. ",l.createElement(n.a,{href:"https://stackoverflow.com/a/15710692"},"(참조한 stackoverflow)")),"\n"),"\n",l.createElement(n.p,null,"이제 hash 함수와 ",l.createElement(n.code,null,"<style>")," Element를 이용해 className 생성 함수를 만들어준다."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-js"},"const hash = (s) =>\n  `hash${s.split('').reduce((num, t) => {\n    num = (num << 5) - num + t.charCodeAt(0);\n\n    return num & num;\n  }, 0)}`;\n\nclass Sheet {\n  constructor() {\n    document.head.appendChild(this.ele = document.createElement('style'));\n  }\n\n  generateClassName(style) {\n    const styledClassName = hash(style);\n\n    const rule = `.${styledClassName} { ${style} }`;\n\n    if (!this.ele.innerText.includes(rule)) {\n      this.ele.appendChild(document.createTextNode(rule));\n    }\n\n    return styledClassName;\n  }\n}\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L14: hash로 className을 생성한다."),"\n",l.createElement(n.li,null,"L16: ",l.createElement(n.code,null,"selector { style }")," 형식의 css code를 생성한다."),"\n",l.createElement(n.li,null,"L18: 이미 style이 존재하는지 체크하고 없는 rule이라면 추가해준다."),"\n",l.createElement(n.li,null,"L22: class명을 return한다."),"\n"),"\n",l.createElement(n.p,null,"전체 Sheet 코드는 다음과 같다."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"sheet.js")),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-js"},"const hash = (s) =>\n  `hash${s.split('').reduce((num, t) => {\n    num = (num << 5) - num + t.charCodeAt(0);\n\n    return num & num;\n  }, 0)}`;\n\nclass Sheet {\n  constructor() {\n    document.head.appendChild(this.ele = document.createElement('style'));\n  }\n\n  generateClassName(style) {\n    const styledClassName = hash(style);\n\n    const rule = `.${styledClassName} { ${style} }`;\n\n    !this.ele.innerText.includes(rule) && this.ele.appendChild(document.createTextNode(rule));\n\n    return styledClassName;
1\n  }\n}\n\nexport default Sheet;\n")),"\n",l.createElement(n.p,null,"완성된 class를 ",l.createElement(n.code,null,"styled")," 함수에 적용해보자."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"styled.jsx")),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"import Sheet from './sheet';\n\nconst sheet = new Sheet();\n\n// getStyle function...\n\nfunction styled(Tag) {\n  return function templateFunction(styleStringArray, ...interpolations) {\n    const style = getStyle(styleStringArray, ...interpolations);\n\n    const styledClassName = sheet.generateClassName(style);\n\n    return function WrappedStyledComponent({ children, ...props }) {\n      return (\n        <Tag {...props} className={styledClassName.concat(props.className ? ` ${props.className}` : '')}>\n          {children}\n        </Tag>\n      );\n    };\n  };\n}\n\nconst domElements = ['a', 'abbr', 'address', 'area', ...];\n\ndomElements.forEach((domElement) => {\n  styled[domElement] = styled(domElement);\n});\n\nexport default styled;\n")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L11: style을 이용해 className을 생성해준다."),"\n",l.createElement(n.li,null,"L15: className을 Tag에 추가해주고, 기존에 화면에 표시하던 style은 제거한다."),"\n"),"\n",l.createElement(n.p,null,"className을 넘긴후 Demo를 확인해보면 style이 적용된걸 확인할 수 있다."),"\n",l.createElement(W),"\n",l.createElement(n.hr),"\n",l.createElement(n.p,null,"마지막으로 다른 컴포넌트를 extend 해서 새로운 컴포넌트를 만들어 보자."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"App.jsx")),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"// ...\n\nconst Container = styled.div`\n  display: flex;\n  justify-content: space-between;\n  color: ${color};\n`;\n\nconst Container2 = styled(Container)`\n  justify-content: center;\n  color: #666;\n`;\n\n// const World...\n\nfunction App() {\n  return (\n    <Container2>\n      Hello,\n      <World>World!</World>\n    </Container2>\n  );\n}\n\nexport default App;\n")),"\n",l.createElement(G),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"L9: ",l.createElement(n.code,null,"Container"),"를 ",l.createElement(n.code,null,"styled()"),"로 감싸 ",l.createElement(n.code,null,"Container2"),"를 만들었다."),"\n",l.createElement(n.li,null,"L10 ~ 11: 기존의 ",l.createElement(n.code,null,"justify-content"),", ",l.createElement(n.code,null,"color")," style을 override 했다."),"\n"),"\n",l.createElement(n.p,null,"Demo를 통해 ",l.createElement(n.code,null,"justify-content"),", ",l.createElement(n.code,null,"color")," 속성이 잘 override 된걸 확인할 수 있다."),"\n",l.createElement(n.h1,null,"4. 마무리"),"\n",l.createElement(n.p,null,"간단한 CSS-in-JS 시스템을 만들어 보았다. 포스트를 재밌게 봤다면 템플릿 리터럴로 넘긴 function에 대한 처리 부분을 직접 구현해봐도 좋을 것 같다."),"\n",l.createElement(n.pre,null,l.createElement(n.code,{className:"language-jsx"},"const Container = styled.div`\n  display: flex;\n  justify-content: space-between;\n  color:  ${props => props.primary ? 'white' : 'palevioletred'};\n`;\n")),"\n",l.createElement(n.p,null,"포스트에는 안나온 실제 라이브러리들의 기능과 최적화에 대해 궁금하다면 ",l.createElement(n.a,{href:"https://styled-components.com/docs"},"공식 문서"),"와 ",l.createElement(n.a,{href:"https://github.com/styled-components/styled-components"},"github 오픈 소스"),"를 참고하자."),"\n",l.createElement(n.p,null,"이 포스트에서 사용된 코드는 ",l.createElement(n.a,{href:"https://github.com/pyjun01/css-in-js"},"여기"),"서 확인해볼 수 있다."),"\n",l.createElement(n.h1,null,"참고"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"https://levelup.gitconnected.com/a-brief-history-of-css-in-js-how-we-got-here-and-where-were-going-ea6261c19f04"),"\n",l.createElement(n.li,null,"https://speakerdeck.com/vjeux/react-css-in-js?
1slide=2"),"\n",l.createElement(n.li,null,"https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Template_literals"),"\n"))}var M=function(e){void 0===e&&(e={});const{wrapper:n}=Object.assign({},(0,r.RP)(),e.components);return n?l.createElement(n,e,l.createElement(I,e)):I(e)};var q=t(7717),U=t(6089),Y=t(1042),B=t(5242),K=t(7271),Q=t(5109),X=t(1869);const Z={Tweet:q.Yk,CodeSandbox:q.dH},ee=s.default.div.withConfig({displayName:"mdxparent__File__name__Container",componentId:"sc-15llss4-0"})(["padding:32px 0;> h2{margin:0;font-size:3rem;line-height:3.75rem;letter-spacing:-0.0625rem;font-weight:100;font-family:Georgia,Times,serif;}> .date{margin:32px 0 56px;text-align:right;}img{max-width:100%;}figure{margin:1.5rem 0;img{display:block;margin:0 auto;}figcaption{font-size:0.875rem;color:#757575;text-align:center;}}@media (max-width:680px){> .date{font-size:1.3rem;}> .content{font-size:1.5rem;line-height:2.25rem;}}"]);function ne(e){let{data:n,children:t}=e;return l.createElement(U.A,{pageTitle:n.mdx.frontmatter.title},l.createElement(Y.A,{title:n.mdx.frontmatter.title,description:n.mdx.frontmatter.preview,slug:n.mdx.frontmatter.slug}),l.createElement(ee,null,l.createElement("h2",null,n.mdx.frontmatter.title),l.createElement("p",{className:"date"},n.mdx.frontmatter.date),l.createElement("div",{className:"content"},l.createElement(r.xA,{components:Object.assign({pre:B.A,a:Q.A,h1:K.H1,h2:K.H2,h3:K.H3,h4:K.H4,h5:K.H5,h6:K.H6,TableOfContents:e=>l.createElement(X.A,Object.assign({},e,{headings:n.mdx.headings}))},Z)},t))))}function te(e){return l.createElement(ne,e,l.createElement(M,e))}}}]);
2//# sourceMappingURL=component---src-pages-v-mdx-parent-file-name-tsx-content-file-path-src-blog-css-in-js-mdx-0265d7109475e87f2632.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.