히치키치

프로젝트 세팅 : 스타일 및 레이아웃 관련 본문

Cognisle

프로젝트 세팅 : 스타일 및 레이아웃 관련

히치키치 2024. 4. 26. 01:19

 

1. 폴더 단위 작업 내용

1-1. styles 폴더 

colors.ts : 필요한 컬러 정의 및 변수명 설정

globalStyles.ts : 스타일 리셋 및 각종 스타일 변수명 적용

 

1-2. public/fonts 폴더

YdestreetB.woff : 사용하는 커스텀 폰트 파일

YdestreetL.woff : 사용하는 커스텀 폰트 파일

style.css : font-face 정의

 

1-3. src/pages/_app.tsx 파일

해당 파일에 폰트 적용 및 전역 스타일 적용

 

2. 세부 파일 작성 내용

2-1. styles/colors.ts : 컬러 정의

import { css } from '@emotion/react'

export const colorPalette = css`
  :root {
    --color-yellow-100: rgba(255, 249, 188, 1);
    --color-yellow-200: rgba(255, 249, 189, 1);

    --color-orange-100: rgba(255, 195, 97, 1);
    --color-orange-200: rgba(254, 195, 97, 1);
    --color-orange-300: rgba(255, 107, 87, 1);

    --color-pink-100: rgba(249, 140, 189, 1);

    --color-blue-100: rgba(105, 191, 255, 1);
    --color-blue-200: rgba(43, 114, 216, 1);
    --color-blue-300: rgba(36, 97, 186, 1);
    --color-blue-400: rgba(18, 49, 93, 1);

    --color-grey-100: #cecece;

    --color-green-100: rgba(195, 235, 164, 1);
    --color-green-200: rgba(174, 216, 147, 1);
    --color-green-300: rgba(115, 216, 156, 1);
    --color-green-400: rgba(3, 107, 87, 1);

    --shadow-orange-100: rgba(255, 174, 39, 1);

    --shadow-pink-100: rgba(247, 169, 160, 1);
    --shadow-pink-200: rgba(242, 104, 166, 1);

    --shadow-blue-100: rgba(28, 103, 211, 1);

    --gradient-yellow-100: rgba(115, 216, 156, 0);
  }
`

export const colors = {
  yellow100: 'var( --color-yellow-100)',
  yellow200: 'var( --color-yellow-200)',
  orange100: 'var( --color-orange-100)',
  orange200: 'var( --color-orange-200)',
  orange300: 'var( --color-orange-300)',

  pink100: 'var( --color-pink-100)',

  green100: 'var( --color-green-100)',
  green200: 'var( --color-green-200)',
  green300: 'var( --color-green-300)',
  green400: 'var( --color-green-400)',

  blue100: 'var(--color-blue-100)',
  blue200: 'var(--color-blue-200)',
  blue300: 'var(--color-blue-300)',
  blue400: 'var(--color-blue-400)',

  grey100: 'var(--color-grey-100)',
}

const shadows = {
  orange100: 'var( --shadow-orange-100)',
  pink100: 'var( --shadow-pink-100)',
  pink200: 'var( --shadow-pink-200)',
  blue100: 'var( --shadow-blue-100)',
}

const gradients = {
  yellow100: 'var(--gradient-yellow-100)',
}

export type Colors = keyof typeof colors

export type Shadows = keyof typeof shadows

export type Gradients = keyof typeof gradients

 

 

2-2. public/fonts/style.css

@font-face {
    font-family: "Ydestreet";
    font-style: normal;
    font-weight: large;
    font-display: swap; /*로딩 되지 않았을 때 시스템 폰트*/ 
    src: url('YdestreetL.woff') format('woff');
     /* unicode-range:U+AC00-D7A3,U+0030-0039;;	/* 한글과 숫자 => 현재 전체 텍스트 폰트로 적용*/
}

@font-face {
    font-family: "Ydestreet";
    font-style: normal;
    font-weight: bold;
    font-display: swap; /*로딩 되지 않았을 때 시스템 폰트*/ 
    src: url('YdestreetB.woff') format('woff');
    /* unicode-range:U+AC00-D7A3,U+0030-0039;;	/* 한글과 숫자 => 현재 전체 텍스트 폰트로 적용*/
}

 

2-3. styles/globalStyles.ts : 전역 스타일 작성

컬러와 폰트 적용

1rem이 10px 되도록 font-size: 62.5% 

import { colorPalette } from '@/styles/colors'
import { css } from '@emotion/react'
export default css`
  ${colorPalette}
  :root {
    --dimmed-zindex: 10;
    --alert-zindex: 11;
    font-size: 62.5%;
  }

  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;
    font-family: 'Ydestreet', 'Noto Sans', sans-serif;
  }
  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;
  }
  button {
    border: none;
    margin: 0;
    padding: 0;
    width: auto;
    overflow: visible;
    background: transparent;
    color: inherit;
    font: inherit;
    line-height: normal;
  }
  a {
    color: inherit;
    text-decoration: inherit;
  }
`

 

2-4. src/pages/_app.tsx

전역 스타일 코드 적용 : emotion의 Global에 styles props로 styles 폴더 내 작성한 전역 스타일 CSS 부여

폰트 불러와 적용 : public에서 작성한 font-face 담긴 코드 import

import type { AppProps } from 'next/app'
import { Global } from '@emotion/react'
import globalStyles from '@/styles/globalStyles'
import 'public/fonts/style.css'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Global styles={globalStyles} />
      <Component {...pageProps} />
    </>
  )
}

 

 

Routing: Custom App | Next.js

Control page initialization and add a layout that persists for all pages by overriding the default App component used by Next.js.

nextjs.org

 

3. 페이지 레이아웃 및 각종 메타태그 정리

_app.tsx 란?

 

Routing: Custom App | Next.js

Control page initialization and add a layout that persists for all pages by overriding the default App component used by Next.js.

nextjs.org

_document.tsx란?

 

Routing: Custom App | Next.js

Control page initialization and add a layout that persists for all pages by overriding the default App component used by Next.js.

nextjs.org

 

 

4. 공용 Layout 컴포넌트와 SEO 컴포넌트

components/Layout.tsx

import SEO from '@/components/common/SEO'
import Head from 'next/head'

interface LayoutProps {
  children: React.ReactNode
}

function Layout({ children }: LayoutProps) {
  return (
    <>
      <SEO title="Cognisle" description="지혜의 숲" image="" />
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      {children}
    </>
  )
}

export default Layout

 

 

components/SEO.tsx

import Head from 'next/head'

interface SEOProps {
  title: string
  description: string
  image: string
}

function SEO({ title, description, image }: SEOProps) {
  return (
    <Head>
      <title>{title}</title>
      <meta name="description" content={description} />
      <meta property="og:type" content="website" />
      <meta property="og:title" content={title} />
      <meta property="og:image" content={image} />
      <meta property="og:image:width" content="260" />
      <meta property="og:image:height" content="260" />
      <meta property="og:description" content={description} />
      <meta property="og:locale" content="ko_KR" />
    </Head>
  )
}

export default SEO

 

5. _app.tsx에 Layout 컴포넌트 전체 적용되도록 추가

import type { AppProps } from 'next/app'
import { Global } from '@emotion/react'
import globalStyles from '@/styles/globalStyles'
import 'public/fonts/style.css'
import Layout from '@/components/common/Layout'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Layout>
      <Global styles={globalStyles} />
      <Component {...pageProps} />
    </Layout>
  )
}
Comments