배경이 따라오는 메모장을 만들기 위해 contentEditable을 사용해보자

2025. 4. 19. 16:00·Intern

사용자가 글을 입력할 수 있는 컴포넌트를 만들려면 보통 input이나 textarea를 활용한다.

 

디자이너님께서 새로 메모장 디자인을 전달해주셨는데,

글이 한 줄일 때는 뒤의 회색 배경이 글자와 딱 맞게 입력해야할 때마다 따라와야 하지만,

두 줄 이상일 때부터는 배경이 메모장의 최대 width로 유지되면서 줄 수 만큼 height가 늘어나야했다.

 

한 줄일 때는 뒤의 배경이 따라온다
여러 줄일 때는 최대 width를 유지한채 height가 늘어난다

 

처음에는 textarea를 활용해보았는데, 뒤의 회색 배경이 글자를 따라오게 만드는데 실패했다 (fit-content 속성을 주었음에도 불구하고)

 

그 다음에는 input을 활용해보았는데, 뒤의 회색 배경이 글자를 따라오긴 하였지만, 글이 두 줄일 때 뒤의 회색 배경이 다음 줄로 넘어가지 않았다.

 

그래서 div에 contentEditable 속성을 주어 원하는 동작을 구현할 수 있었다. 그렇다면 어떻게 배경이 따라오는 메모장을 만들었는지 살펴보자.


<MemoContainer className="memo-container" onClick={handleMemoClick}>
    <img src={이미지 주소} alt="메모" />
    {isWriteMemo ? (
        <span className="memo-text editing">
            <EditableDiv
                className={!memo ? "empty" : ""}
                ref={editableDivRef}
                contentEditable
                onBlur={handleMemoBlur}
                onKeyDown={handleKeyDown}
                onInput={handleInput}
                suppressContentEditableWarning={true}
            ></EditableDiv>
        </span>
    ) : (
        <span className="memo-text">{memo || "메모작성"}</span>
    )}
</MemoContainer>

MemoContainer는 메모 컨테이너 전체의 레이아웃이고, EditableDiv는 실제 편집 가능한 텍스트 영역의 스타일이다.

 

EditableDiv의 속성 중에 suppressContentEditableWarning = {true}가 있는데, 이 속성이 없으면 콘솔에 수정이 가능한 요소 내에 react에서 관리하는 children도 포함되어 있기에 조심해달라는 warning이 뜨게 된다.

(자세한 내용은 이 링크를 참고하자 https://guiyomi.tistory.com/147 )

 

 

.memo-text {
    width: auto;
    max-width: 282px;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: break-word;
    min-height: 21px;
    display: inline-block;

    &.editing {
      background: transparent;
      color: #202020;
      position: relative;
      z-index: 1;
      padding-left: 6px;

      // 배경 확장을 위한 가상 요소
      &::before {
        content: "";
        position: absolute;
        top: -4px;
        left: 0;
        right: -6px;
        bottom: -4px;
        background: #f0f0f0;
        border-radius: 6px;
        z-index: -1;
      }
    }
}

memo-text의 width는 auto이므로 글씨가 써질 때마다 늘어난다.

 

그 뒤의 회색 배경은 before로 만들었는데, editing의 position이 relative이므로 부모인 memo-text의 width를 따라간다. (가상 요소의 z-index는 -1를 줘서 뒤로 가게 만들었다)

 

또한 편집 모드로 들어갈 때 ‘메모를 입력하세요’ placeholder를 위치시키기 위해 가상 요소를 활용했다.

&:empty:before,
&.empty:empty:before {
    content: "메모를 작성하세요";
    color: #c4c4c4;
    (...)
}
  1. &:empty:before - div가 완전히 비어있을 때
  2. &.empty:empty:before - div가 비어있고 empty 클래스가 있을 때

이렇게 두가지 방식을 처리했다.

저작자표시 비영리 변경금지 (새창열림)

'Intern' 카테고리의 다른 글

useRef를 활용하여 stale closure를 해결해보자  (0) 2025.05.17
모노레포에서 다른 프로젝트로 파일을 옮길 때 조심해야 할 점  (0) 2025.04.19
네이버 지도 api 사용 시 마커가 많을 때 최적화 후기  (1) 2025.03.15
'Intern' 카테고리의 다른 글
  • useRef를 활용하여 stale closure를 해결해보자
  • 모노레포에서 다른 프로젝트로 파일을 옮길 때 조심해야 할 점
  • 네이버 지도 api 사용 시 마커가 많을 때 최적화 후기
퀵차분
퀵차분
Web Developer 🥐
  • 퀵차분
    QC's Devlog
    퀵차분
  • 전체
    오늘
    어제
    • 분류 전체보기 (172) N
      • Frontend (28)
        • HTML, CSS (7)
        • Javascript (3)
        • React (11)
        • Typescript (2)
        • Next.js (4)
      • Node.js (3)
      • Fedify (4)
      • Study (42) N
        • NestJS (2) N
        • Modern JS Deep Dive (13)
        • SQL (1)
        • Network (1)
        • 프롬프트 엔지니어링 (4)
        • 인공지능 (9)
        • 시스템프로그래밍 (11)
        • 선형대수학 (1)
      • Intern (4)
      • KUIT (21)
      • Algorithm (48)
        • Baekjoon(C++) (26)
        • Programmers(JavaScript) (22)
      • 우아한테크코스(프리코스) (4)
      • Project (7)
        • PROlog (4)
        • Nomadcoder (2)
      • 생각 (4)
      • Event (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    티스토리챌린지
    리액트
    알고리즘
    typescript
    타입스크립트
    프로그래머스 자바스크립트
    javascript
    오블완
    프로그래머스
    HTML
    자바스크립트
    fedify
    백준
    시스템프로그래밍
    인공지능
    프론트엔드
    next.js
    음악추천
    KUIT
    react
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
퀵차분
배경이 따라오는 메모장을 만들기 위해 contentEditable을 사용해보자

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.