반응형 레이아웃 만들기 + 배포하기

비얌·2023년 2월 28일
3
post-thumbnail

🧹 개요

인생 처음으로 배포를 해보기로 했다! Porkbun에서 도메인을 사고 CloudFlare Pages로 배포할 것이다😆

그리고 배포했을 때 스마트폰으로도 편하게 투두리스트를 사용할 수 있도록 반응형 레이아웃을 만들어보기로 했다.



✨ 결과 미리보기

https://todo.hamzik.dev 에 배포했다.

데스크탑모바일


🎇 반응형 레이아웃 만들기

기존의 투두리스트는 아래처럼 화면을 축소해도 레이아웃이 변경되지 않고 또 화면의 크기대로 짤렸다. 스마트폰으로도 모든 요소를 볼 수 있고 더 편안하게 볼 수 있도록 반응형 레이아웃을 만들어보자.

px을 %으로 바꾸기

보통 웹사이트를 들어가보면 화면을 축소했을 때 각 요소도 화면의 크기에 맞게 작아지던데, 내가 만든 투두리스트는 전혀 그러지 않았다! 그래서 flex에 grow나 shrink 등의 속성을 줘야하나? 생각하다가 잘 모르겠어서 질문을 했고, px을 %로 바꾸라는 조언을 들었다.

그래서 대부분의 px을 %로 바꾸는 작업에 들어갔다😂 %로 바꾸니 화면을 축소했을 때 요소의 크기도 의도대로 줄어들었다!

미디어쿼리 사용하기

미디어 쿼리는 반응형 웹 디자인의 핵심 부분으로, 뷰포트의 크기에 따라 서로 다른 레이아웃을 생성할 수 있다. 여기서 뷰포트란 현재 보고 있는 컴퓨터 화면의 영역이다. 특히 데스크탑 화면에서는 창의 크기를 늘이고 줄이며 뷰포트의 크기를 조정할 수 있다.

데스크탑, 랩탑, 태블릿, 스마트폰의 뷰포트는 모두 다르다. 그래서 분기점을 여러개 두어 각 장비에 최적화된 레이아웃을 만들면 좋겠지만, 일단 태블릿의 너비만 분기점으로 두어 화면의 너비가 태블릿 정도로 줄어들면 레이아웃이 변화하게 했다.

App 컴포넌트에서 flex-direction 바꿔주기

데스크탑 사이즈에서는 flex-direction을 row로 주어 Goal이 왼쪽, Todo가 오른쪽에 위치하게 했다. 하지만 태블릿이나 스마트폰에서는 Goal이 위에, Todo가 아래에 위치하는 것이 좋을 것 같아 flex-direction을 column으로 바꿔주었다.

/* App.module.css */
@media screen and (max-width: 768px) {
  .box {
    display: flex;
    flex-direction: column;
  }
}

Goal와 Todo의 비율을 1:3에서 1:1로 바꿔주기

데스크탑 사이즈에서는 화면에서 Goal이 1, Todo가 3을 차지했었는데, 화면이 작아져 Todo가 Goal의 아래로 내려오게 되면 둘의 비율을 1:1로 변경해주었다. 동시에 Goal과 Todo를 나누는 선의 위치를 border-right에서 border-top로 바꿔주었다.

/* Todo.mudle.css */
@media screen and (max-width: 768px) {
  .title {
    font-size: 2.5rem;
    width: 350px;
    margin-top: 5%;
    margin-bottom: 2%;
  }

  .container {
    flex: 1;
    border-top: 2px solid rgb(225, 224, 224);
    border-left: none;
  }
}

여러 요소 사이즈 줄여주기

아래는 TodoItem 컴포넌트에 적용되는 css이다. 화면의 너비가 768px 아래로 줄어들면 폰트 사이즈, 아이콘, 패딩, 마진 등을 줄였다.

/* TodoItem.module.css */
@media screen and (max-width: 768px) {
  .container {
    margin-bottom: 10px;
    font-size: 1.2rem;
    padding: 2% 3%;
  }

  .deleteIcon, .submitIcon, .cancelIcon, .editIcon {
    height: 30px;
    width: 30px;
  }

  .editIcon, .submitIcon {
    margin-right: 4px;
  }

  input.text {
    font-size: 1.2rem;
  }

  label div {
    width: 30px;
    height: 30px;
  }
}


🛫 배포하기

도메인 구매하기

Porkbun(https://porkbun.com)에서 도메인을 구매했다.

구매하고 싶은 도메인을 검색하면 구매할 수 있는지, 혹은 누군가가 이미 구매한 도메인인지 알 수 있다.

hamzik.dev라는 도메인을 1년간 사용하기 위해 약 10달러를 지불했다!

CloudFlare Pages로 배포하기

배포는 CloudFlare Pages(https://pages.cloudflare.com)에서 했다.



🔨 피드백 반영하기

배포 후 개발 커뮤니티에 올렸고, 여러 피드백을 받을 수 있었다.

  1. 목표를 정한다는 뜻에서 Goal 입력창의 placeholder가 'Add Goal'이 아니라 'Set Goal'이면 좋겠다.
    👉 목표를 입력하는 부분에 Add Goal이라고 썼을 때 뜻이 잘 전달되지 않는 것 같아 아쉬움이 남았었다. 하지만 어떤 분이 목표를 정한다는 뜻에서 Add Goal보다는 Set Goal이 좋을 것 같다고 말씀해주셨고, 나도 이 표현이 맞는 것 같아 수정하였다.
  1. 기존에는 투두를 수정할 때 모든 투두의 placeholder가 'Edit Todo'였는데, 대신 기존 투두 내용이 들어가면 좋겠다.
    👉 전에는 어떤 투두를 수정하여도 모두 'Edit Todo'가 placeholder에 표시됐었다. placeholder에 'Edit Todo'가 하드코딩되는 것보다 기존 투두의 내용이 표시되는 것이 좋을 것 같다는 피드백을 받아 그렇게 수정하였다.
  1. 아이콘 간격이 일정치 않아서 수정/삭제 버튼의 간격과 확인/취소 버튼의 간격이 동일했으면 좋겠다.
    👉 기존에는 확인/취소 버튼 사이의 간격이 수정/삭제 버튼 사이의 간격과 달랐다. 이를 수정하고자 각 아이콘에 padding이나 margin이 있나 살펴봤는데, 별다른 설정은 없었다. 하지만 개발자도구로 살펴보면 padding이 적용되어 있었기 때문에 padding: 0을 주어 자동으로 설정된 padding을 없애주었다. 그랬더니 간격이 동일하게 설정되었다!
  1. 공백 문자열이 입력 불가능했으면 좋겠다.
    👉 빈 문자열은 입력이 불가능하도록 설정했는데, 공백으로 이루어진 문자열은 따로 처리하지 않았었다. 그래서 입력값을 검증하는 부분에 공백을 제거하는 함수 .trim()을 써서 공백으로 이루어진 문자열도 검증할 수 있도록 했다.

    // TodoInput.js
    const submitHandler = (e) => {
      e.preventDefault();
      if (enteredGoal.trim() === '') {
        setIsValid(false);
        setEnteredGoal('');
        return;
      }

  1. 글자 단위가 아니라 단어 단위로 줄바꿈이 되면 좋겠다.
    👉 기존에는 화면의 크기가 줄어들 때 글자 단위로 줄바꿈이 되었다. 예를 들면 투두리스트 만들기를 입력했을 때, 한글자만큼 화면의 크기가 줄어들면 투두리스트 만들에서 줄바꿈이 되어 다음 줄에 가 내려가는 식이었다. 하지만 단어 단위로 줄바꿈이 된다면 투두리스트에서 줄바꿈이 되어 다음 줄에 만들기가 내려가게 된다. 이렇게 하기 위해서는 css에서 word-break: break-allword-break: keep-all로 변경해주면 된다.
    💥 하지만 전에도 단어 단위로 줄바꿈을 하고 싶어서 시도해보았는데, 오류가 발생하여 적용하지 못했다. 단어가 아주 길어지면 중간에 줄바꿈이 되지 않아 Goal 부분의 너비가 커져서 2:3으로 나눠놨던 화면 비율이 아래와 같이 변경되는 오류가 발생한다.
    🔑 텍스트의 상위 요소인 container에 width: 100%를 주고 text에 overflow-wrap: anywhere를 주어 해결했다! overflow-wrap: anywhere는 한 줄에 너무 긴 단어가 와서 줄바꿈을 할 수 있는 break points가 없는 경우 하나의 문자열을 잘라 줄바꿈을 한다.


✨ 결과

결과는 https://todo.hamzik.dev 에서 확인할 수 있다!

데스크탑에서 작성할 때

모바일에서 작성할 때

수정 버튼을 눌렀을 때

삭제 버튼을 눌렀을 때

빈 문자열 혹은 공백으로 이루어진 문자열을 입력했을 때



🔮 개선하고 싶은 부분

  1. 로컬 스토리지
    로컬 스토리지는 브라우저 상에 데이터를 저장할 수 있는 기술이다. 현재는 페이지를 새로고침하면 작성한 모든 내용이 초기화된다. 브라우저 상에 데이터가 저장하여 페이지를 새로고침해도 데이터가 날아가지 않도록 만들고 싶다.

  2. 드래그앤드롭
    작성한 투두를 드래그앤드롭하여 순서를 바꿀 수 있게 만들고 싶다.

  3. useRef로 focus 주기
    수정 버튼을 누르면 focus가 해당 투두의 input창에 잡히도록 만들고 싶다.

  4. 투두들만 스크롤되게 하고 나머지 부분은 고정하기
    추가한 투두가 많아져 한 화면에 모든 투두를 표시할 수 없을 때, 스크롤을 하면 작성한 투두를 모두 확인할 수 있다. 이때 투두리스트 위에 있는 제목과 입력창은 화면에 고정하여 스크롤을 내려도 움직이지 않도록 하고 싶다.



🐹 회고

생전 처음으로 배포를 해보았다!! 정말 유익하고 즐거운 경험이었다😊

2주 전에 리액트 강의를 듣다가 투두리스트가 나왔고, 그걸 똑같이 만들어보고 싶어져서 하루 종일 만든 것이 이것이었다.

css도 없고 투두 추가 외의 기능도 없어서 못생기고 초라했던 나의 투두😂 그래서 css를 추가하고 더 많은 기능을 넣어서 예쁜 투두리스트를 만들어보겠다는 다짐을 하게 되었다.

목표는 두 가지였는데, 첫번째는 crud 구현이었고 두 번째는 디자인 예쁘게 만들기였다.

crud 구현은 기존에 블로그에 썼던 내용과 여러 강의, 구글링, ChatGPT의 도움을 받았다. 그리고 디자인을 모르는 상태에서 투두리스트를 예쁘게 만들기 위해서는 예쁜 예시를 많이 알아야겠다는 생각이 들어 구글링을 많이 했다. 여러 투두리스트의 데모와 깃허브 주소를 모아둔 사이트(https://reactjsexample.com/tag/todo)와 버튼 css 예시를 모아둔 사이트(https://getcssscan.com/css-checkboxes-examples)에서 큰 도움을 받았다.

2주간 열심히 만들었고, 시행착오를 포함한 모든 과정을 블로그에 최대한 상세하게 기록하려고 했다. 그 과정에서 많은 것들을 알아갈 수 있었다!

  1. 컴포넌트를 나누고, 데이터를 끌어올리고 내리는 것에 좀 더 익숙해졌다.
  2. flexbox를 사용하여 레이아웃을 만드는 것에 좀 더 익숙해졌다.
  3. 오류를 접하고 해결하며 새로운 지식을 얻어갈 수 있었다.

앞으로는 그동안 중단했던 강의를 이어서 듣다가 지식이 더 쌓였을 때 다시 이 투두리스트를 개선해보자😊

profile
🐹강화하고 싶은 기억을 기록하고 공유하자🐹

0개의 댓글