[Next.js] 포트폴리오 웹 페이지 제작기 - 7. Anchor Link

olwooz·2023년 2월 17일
0

헤더 navbar에서 메뉴 버튼을 클릭하면 해당 위치로 이동하는 anchor link 기능을 구현했다.
아주 간단하다.

scroll-behavior: smooth

가장 먼저 html 태그에 scroll-behavior: smooth 라는 CSS 속성을 부여해야 한다.

/* styles/globals.css */

html {
  scroll-behavior: smooth;
}

이 속성을 부여하면 유저가 직접 스크롤하는 경우가 아니라 navigation (e.g. a 태그) 또는 스크롤 API 호출로 인한 스크롤 동작이 부드러워진다.

scroll={false}

a 태그로 링크를 걸었다면 문제 없이 동작하지만,
Next.js의 Link 컴포넌트를 사용했다면 scroll={false}를 추가해야 한다.

// components/Header/HeaderButton.tsx

import Link from 'next/link';

interface Props {
  name: string;
}

const HeaderButton = ({ name }: Props) => {
  return (
    <Link href={`#${name}`} scroll={false}>
      <button className="px-4 capitalize">{name}</button>
    </Link>
  );
};

export default HeaderButton;

이렇게 해야 하는 이유는 Link의 특성 때문이다.
페이지 이동 시 스크롤을 맨 위로 올리는 게 Link 컴포넌트의 default scroll behavior이기 때문에,
scroll={false}를 통해 이 default scroll behavior를 override하겠다는 의사를 밝혀야 한다.

링크 버튼에 보여지는 이름은 text-transform: capitalize 속성을 통해 capitalize했다.

id

Link와 목적지 div를 연결해주는 값은 id이다.
예를 들어, Linkhref 속성에 #123이라는 값을 넣어주면,
123이라는 id를 가진 div와 해당 Link가 연결된다.

현재 모든 섹션이 ContentWrapper 컴포넌트 단위로 나뉘어지기 때문에,
Propsid를 추가해주고 섹션마다 id값을 다르게 전달해주면 된다.

// components/Contents/ContentWrapper.tsx

interface Props {
  id: string;
  children: React.ReactNode;
  style?: string;
}

const ContentWrapper = ({ id, children, style }: Props) => {
  return (
    <div id={id} className={`min-h-screen px-[200px] py-[200px] ${style}`}>
      {children}
    </div>
  );
};

export default ContentWrapper;
// components/Contents/Main/Main.tsx

/* ... */

const Main = () => {
  return (
    <ContentWrapper id="main" style="flex items-center">
      <div className="w-full">
        <h3 className="mb-6 text-2xl font-light">안녕하세요.</h3>
        <SlotMachine textData={textData} />
        <h3 className="mt-4 text-4xl font-black">누구누구입니다.</h3>
      </div>
    </ContentWrapper>
  );
};

export default Main;

결과

사실 scroll-behavior: smooth도, text-transform: capitalize도 오늘 처음 알게 된 CSS 속성이다.
JS로 직접 어렵게 구현할 필요 없이 이런 꿀같은 CSS를 활용한다면 시간도 절약되고 성능 면에서도 더 좋을 거라고 생각한다. (내가 만든 기능 vs 전세계의 석학들이 모여 전세계 개발자들을 위해 만든 기능)

아무리 단순한 기능이라도, 이미 구현 방법을 알고 있는 기능이라도 몇 분만 더 투자해서 조금만 더 깊이 검색해본다면 더 좋은 방법, 각 방법의 장단점, 차이점 등 추가로 배울 점이 항상 있다고 생각한다.

다음은 다크 모드 기능을 구현할 것이다.

0개의 댓글