Alog 서비스는 풀이 작성 기능을 제공해야한다. 제목, 한 줄 요약, 언어, 풀이 4가지 항목을 입력할 수 있는데, 그 중 풀이를 작성할 때의 사용성을 개선해보고자했다.
구현을 위해 html의 textarea를 적용했는데, 고정적인 높이를 가진 textarea는 사용성이 떨어질 수 있겠다고 생각했던게 계기가 됐다.
높이를 짧게하면 콘텐츠가 긴 경우 스크롤이 많이 발생할 수 있다. 반면 높이를 길게하면 빈 영역이 넓어지고, 그에 따라 작성버튼이 불필요하게 먼 곳에 위치하는 문제가 있을 것이라고 생각했다.
그래서 동적인 높이를 가지는 textarea를 직접 구현해보기로했다.
개행문자의 수를 구한 후 동적으로 rows attribute 값을 변경해주었다.
하지만 일부 상황에서 문제가 발생한다. 문자들이 연속으로 입력되다가 다음줄로 넘어가야하는 상황을 상상해보자. 이때 높이를 늘려줘야하는 상황이지만, 이에 대해 처리가 되는 구현 방식은 아니기 때문에 리사이징이 제대로 동작하지 않는다.
rows를 활용한 방법에 문제가 있었고, 다른 사람들의 코드를 참고했다.
scrollHeight을 활용해 height을 재설정하는 코드들이 많았다.
The Element.scrollHeight read-only property is a measurement of the height of an element's content, including content not visible on the screen due to overflow.
즉, scrollheight는 overflow된 영역까지 포함한 특정 요소의 높이를 의미한다.
아래와 같이 적용하면된다.
const textarea = textareaRef.current;
textarea.style.height = 'auto';
textarea.style.height = `${textarea.scrollHeight}px`;
textarea.style.height = 'auto'
가 필요한 이유는, 행의 수가 줄어드는 경우에는 scrollHeight가 변하지 않기 때문이다.
height를 auto로 설정해줌으로써 overflow를 강제로 발생시킨다. 이로부터 원하는 textarea의 scrollHeight를 얻어내는 것이다.
정말 간단한 방법으로, 감쪽같이 height에 변경을 줄 수 있다. 직접 구현해서 사용해보니 높이가 잘 조정되는 것을 확인했다.
하지만 아래와 같이 내부 textarea의 높이 변경에 따라 외부 컨테이너의 스크롤의 위치가 최상단으로 이동하는 문제가 발생했다.
높이가 auto
로 설정되면 textarea가 줄어들고, 그에 따라 외부 컨테이너의 스크롤 위치가 최상단으로 이동하게된다.
하지만 이후 scrollHeight로 높이가 다시 설정되니, 스크롤이 다시 내려가야하는 것을 기대했지만 그렇게 동작하진 않았다. 따라서, 개선된 방법을 생각해야했다.
레이아웃은 되지만, 눈에 보이진 않는 textarea를 하나 더 두었다. 높이를 auto
로 설정해서 스크롤이 최상단으로 이동한게 문제이기 때문에, 실제 textarea의 높이를 auto
로 조정하지않고 가상 textarea에 조정을 한 후, 스크롤 높이를 구해야겠다고 생각했다.
방법 2와의 차이점은 hidden textarea에서 시뮬레이션을 한 후 알아낸 scroll height으로 진짜 textarea의 height을 설정한다는 것이다.
const textarea = textareaRef.current;
const hiddenTextarea = hiddenTextareaRef.current;
hiddenTextarea.value = value;
hiddenTextarea.style.height = 'auto';
textarea.style.height = `${hiddenTextarea.scrollHeight}px`;
이 방법은 방법 2와 달리 실제 textarea의 높이를 바로 scrollHeight 높이로 변경해버린다. 앞서 auto 설정으로인해 발생했던 이슈인 외부 스크롤 이동 문제를 해결할 수 있다.
저성능 환경에서 동작할 때 딜레이가 발생한다면 스크롤이 나타났다 사라지는 깜빡임이 있을 수 있다고 생각했다. 하지만 실제로 크롭 Performance를 통해 성능을 최대로 낮춘채로 테스트를해도, 이러한 버그를 발견하진 못했다. 따라서 실제 서비스에 적용하기에 충분한 결과물이라고 생각된다.
auto resizing 되는 textarea를 구현하고 실제 서비스에 적용한 모습이다!
덕분에 문제를 해결했습니다. 감사합니다~!😆