input의 길이를 내부 값에 따라 동적으로 조절해보자

유키미아우·2023년 12월 5일
3

input의 길이가 값에 따라 동적으로 예쁘게 조절되도록 코드를 개선했다. 개인적으로 해결법이 흥미로웠기에 그 과정을 기록해본다.

배경

동영상에 원하는 글귀를 넣어 꾸미는 피쳐를 계획하였다. 그 하위항목에는 배경색 변경 기능도 있었다.
input의 길이가 곧 배경의 길이가 되기 때문에 길이가 글귀가 얼마나 긴지에 따라 동적으로 조절되어야 했다.

프로젝트 스프린트를 했을 당시 급하게 떠올린 아이디어는 문자의 개수당 너비를 곱해주어 동적으로 width에 할당해주는 방식이었다. onChange가 일어날 때마다 {글자 개수 * 너비}fontWidth state에 할당해주고 이를 inputstyle에 연결해주는 식이다.

...
style={{
	width: {fontWidth}
}}
...

문제

그러나 위 로직이 정확히 동작하는 것은 "한가지 폰트"의 "한글"만 input값으로 받을 때 뿐이다. 한글은 같은 크기의 사각형이 나열되는 형식이기 때문이다.

내 앱과 같이 여러 폰트 옵션이 주어지면서 영어가 주언어로 사용되는 경우에는 철자가 늘어남에 따라 증가하는 input 길이가 부정확한 문제점이 있었다.

  • 알파벳은 "H", "l" 등 철자에 따라 너비가 제각각이다.

철자들 사이의 평균적인 너비값을 정해서 매직넘버로 사용해주었으나, 점점 오차가 쌓이면서 철자가 많은 경우 좌우로 여백이 남는 문제가 발생하였다. 큰 어색함은 없지만, 눈에 거슬리는 현상이었다.

  • 폰트디자인에 따라 철자의 가로길이는 천차만별로 달라진다.

따라서 철자의 너비가 짧아서 홀쭉한 디자인의 폰트가 적용될 경우 좌우 여백이 다른 폰트에 비해 더 많이 남는 문제가 있었다.

해결

input에 들어갈 값을 똑같이 가진 쌍둥이 형제👯를 만들고, 그 너비를 input의 width에 적용하면 되지않을까?

위 해결 방법의 구체적 레시피는 아래와 같다.

  1. <span>을 별도로 만든다. 텍스트 크기 등 CSS 디테일은 input과 동일해야한다.

  2. useRef를 통하여 span태그의 크기 정보를 습득하자.
    나는 useEffect 구문의 내부에 아래 코드를 삽입해주었다. spanRef.current.getBoundingClientRect().width;

  3. span의 크기를 어떤 타이밍에 갱신해줄지 판단해본다.

    (1) 값이 바뀔 때, (2) 폰트가 바뀔 때.

    따라서 값과 폰트 정보가 담긴 두 변수를 dependency로 주어 해당 변경이 가해지면 useEffect가 다시 작동되도록 하였다.

  4. inputwidthfontWidth 변수를 할당해주자 아래같이 잘 작동되기 시작한다.

  1. 마지막으로 쌍둥이 형제인 span태그의 opacity를 0%로 변경하여 가려주도록 한다.

  2. 개선이 완료되었다!

profile
능동적인 마음

4개의 댓글

comment-user-thumbnail
2024년 4월 2일

안녕하세요! 비슷한 기능 구현중인데 입력시에 input 안의 텍스트가 흔들리는 오류가 생기네요ㅠ그런 오류는 없으셨나요?

1개의 답글
comment-user-thumbnail
2024년 4월 3일

인스타그램 스토리올릴 때 같네요. 잘 보고 갑니다~

1개의 답글