Skip to content

(PC 브라우저용) 메인화면 반응형 레이아웃 적용하기

HG.Seo edited this page Dec 4, 2022 · 12 revisions

왜 반응형 레이아웃(PC 브라우저용) 적용이 필요했나?

저희 서비스의 경우 프로필박스에서 코드를 보여주는 것이 중요하기에 사이즈가 무한정 늘어나거나 줄어들어 프로필박스의 코드를 알아보는데 지장을 주는 것은 저희 서비스에 올바를 방향이 아니었고 미관상으로도 좋지 않았습니다.

해결한 방법?

이에, 화면 사이즈에 맞게 width를 계산하도록 하였고 minWidth 값과 maxWidth값을 주어 해결하려고 했습니다.

여전히 남아있었던 문제점?

여전히 디자인 상 문제점이 남아있었습니다. 사이즈가 줄어들어서 프로필박스가 한 행에 2개씩 나오게 될 경우에 프로필박스의 개수가 홀수라면, 마지막 하나의 프로필 사이즈는 다른 프로필 사이즈와 다르게(넓어짐) 나타난다는 것이었습니다.

최종 해결방법?

가장 간단하게 해결할 수 있는 방법을 고민해보았습니다. 저희 메인화면에서 한 행에 표현될 수 있는 프로필박스 개수의 경우는 3개, 2개, 1개 이렇게 3가지가 있고 문제가 되는 경우는 2개인 경우입니다. 이에, 2개가 나오는 경우의 브라우저 사이즈를 측정하였고 window.addEventListener의 'resize'이벤트를 통해 한 행에 2개씩 표현이 되는 경우에는 빈 프로필 박스를 임의로 추가해줌으로써 간단히 추가적인 미관상 문제를 해결할 수 있었습니다.

/** @jsxImportSource @emotion/react */

import { useCallback, useEffect, useRef, useState } from 'react';

import Profile from './Profile';
import { singleProfileData } from './types';

import { emptyProfileBoxStyle, profileListStyle } from './styles';
import { COMMON_SIZE } from 'styles/sizes';

interface Props {
  profileData: Array<singleProfileData>;
}

const ProfileList = ({ profileData }: Props) => {
  const profileListRef = useRef<HTMLDivElement>(null);
  const [isOdd, setIsOdd] = useState<boolean>(false);
  const [isBlankNeeded, setIsBlankNeeded] = useState<boolean>(false);

  useEffect(() => {
    if (profileData.length % 2 !== 0) setIsOdd(true);
    else setIsOdd(false);
  }, []);

  const isWidthDouble = useCallback((targetWidth: number) => {
    return COMMON_SIZE.PROFILELIST_SINGLE_WIDTH < targetWidth && targetWidth < COMMON_SIZE.PROFILELIST_TRIPLE_WIDTH;
  }, []);

  const decideBlank = useCallback(() => {
    if (!profileListRef.current) return;
    if (isWidthDouble(profileListRef.current.clientWidth)) setIsBlankNeeded(true);
    else setIsBlankNeeded(false);
  }, [profileListRef.current]);

  useEffect(() => {
    window.addEventListener('resize', decideBlank);
    return () => {
      window.removeEventListener('resize', decideBlank);
    };
  }, []);

  return (
    <div css={profileListStyle} ref={profileListRef}>
      {profileData.map((data) => (
        <Profile key={`profile-${data.id}`} singleData={data} />
      ))}
      {isOdd && isBlankNeeded && <div css={emptyProfileBoxStyle} />}
    </div>
  );
};

export default ProfileList;

남아있는 과제

차후 사용자의 다양한 환경을 고려한 진정한 반응형 서비스를 제공하기 위해, 다양한 디바이스(모바일, 패드/탭 등)에 대한 반응형 레이아웃을 적용할 예정입니다.

얼리버드

프로젝트

개발일지

스프린트 계획

멘토링

데일리 스크럼

데일리 개인 회고

위클리 그룹 회고

스터디

Clone this wiki locally