컨텐트 크기에 따라 가변적으로 설치할 수 있습니다.

개요


내용의 크기에 따라 가변textarea, 가능한 한 힘들이지 않고 지능적인 실현을 시도한다.
그리고 우리는 본 기기의 폼이 가지고 있는 장점을 충분히 이용하여 안정적이고 접근 가능한 디자인을 목표로 할 것이다.

표준 텍스트의 난점


HTML의 textarea 요소는 기본적으로 고도로 고정되어 사용하기에 불편하다.3줄 정도밖에 안 되는 분야인데 긴 문장은 어쨌든 고통 같은 것도 거칠다.
최근의 브라우저 구현에서 약간 영리할 수도 있습니다. 텍스트 영역의 영역을 드래그해서 확대하고 축소할 수 있습니다.

그냥 내 생각엔.또 귀찮아, 처음부터 입력한 텍스트의 양에 따라 자동으로 신축하면 돼.스크롤 바는 한 페이지에 하나면 충분하다.

구현 방법


어렵지 않지만 HTML과 CSS, JS가 조화롭게 작동합니다.

HTML

<label for="FlexTextarea">伸縮するテキストエリア</label>
<div class="FlexTextarea">
  <div class="FlexTextarea__dummy" aria-hidden="true"></div>
  <textarea id="FlexTextarea" class="FlexTextarea__textarea"></textarea>
</div>

CSS

.FlexTextarea {
  position: relative;
  font-size: 1rem;
  line-height: 1.8;
}

.FlexTextarea__dummy {
  overflow: hidden;
  visibility: hidden;
  box-sizing: border-box;
  padding: 5px 15px;
  min-height: 120px;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: break-word;
  border: 1px solid;
}

.FlexTextarea__textarea {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  overflow: hidden;
  box-sizing: border-box;
  padding: 5px 15px;
  width: 100%;
  height: 100%;
  background-color: transparent;
  border: 1px solid #b6c3c6;
  border-radius: 4px;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  resize: none;
}

.FlexTextarea__textarea:focus {
  box-shadow: 0 0 0 4px rgba(35, 167, 195, 0.3);
  outline: 0;
}

JavaScript

function flexTextarea(el) {
  const dummy = el.querySelector('.FlexTextarea__dummy')
  el.querySelector('.FlexTextarea__textarea').addEventListener('input', e => {
    dummy.textContent = e.target.value + '\u200b'
  })
}

document.querySelectorAll('.FlexTextarea').forEach(flexTextarea)
코드의 대부분은 CSS이고 JavaScript도 무엇을 하고 있습니까?이렇게 간단한 물건이야.하지만 행동을 잘 해야 한다.

동작 샘플


크기가 변경되는 textarea 작업 예(CodePen)

해설


코드야말로 간단한 것이지만 열거하고 설명하고 싶은 점이 많다.

작업 원리 개술


대충 설명하다.textarea 원소는 부모 원소의 크기에 따라 크기를 정한다.position: absolute에서 절대 배치를 하고 widthheight 은 부모 요소와 크기가 동일하도록 지정합니다.
.Textarea__textarea {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
그런 다음 입력한 텍스트를 직접 100% 에 삽입하여 부모 요소의 크기가 텍스트 양에 맞도록 합니다.
textarea.addEventListener('input', e => {
  dummy.textContent = e.target.value
})
따라서 지정된 높이.Textarea__dummy가 텍스트 양에 따라 자동으로 크기를 결정하지 않고 연동.Textarea__dummy의 크기도 이런 비율을 결정한다.

원리 설명용 3D 디스플레이 FlexTextarea
기본적으로 이 정도야.다음은 제가 디테일을 설명해 드릴게요.

최소, 최대 높이 지정


텍스트를 입력하지 않았을 때의 최소 높이와 많은 텍스트를 입력했을 때의 최대 높이를 설정할 수 있습니다.설정하지 않아도 됩니다. 지정하지 않으면 textarea 줄의 높이에 도달하고, 지정하지 않으면 min-height 내용에 따라 어디를 가든지 커집니다.저는 개인적으로 max-height만 지정하면 된다고 생각합니다.
.FlexTextarea__dummy {
  min-height: 120px;
  max-height: 480px;
}

입력한 줄 바꿈 문자를 줄 바꿈 문자로 표시


텍스트 영역의 값을 직접 입력 min-height 하면 줄 바꿈은 반각 공간으로 바뀝니다.DOM에서 줄 바꿈 문자가 흰색 공간으로 동일시되기 때문입니다.매우 유명하다면 HTML에서 줄을 바꾸려면 .Textarea__dummy 라벨을 사용해야 한다.
단, 줄 바꿈 문자를 줄 바꿈 문자로 반영하는 데 사용되는 CSS 속성이 있습니다.
.FlexTextarea__dummy {
  white-space: pre-wrap;
}
이렇게 하면 아래와 같은 간단한 텍스트 대입이라도 줄 바꾸기 문자가 줄 바꾸기로 표시됩니다.
textarea.addEventListener('input', e => {
  dummy.textContent = e.target.value
})
"줄 바꿈 문자를 <br> 문자열로 바꾸어 대입<br>"하는 방법은 보안 빈틈이 생기기 쉬우므로 절대 하지 마세요!!

끝 줄 바꿈 무시 피하기

innerHTML는 매우 편리한 속성이지만 함정이 하나 있다.텍스트 끝에 있는 줄 바꿈은 디스플레이에 나타나지 않습니다.예를 들어, 텍스트 영역에 "TEST < 줄 바꿈> < 줄 바꿈> < 줄 바꿈>"을 입력할 때 white-space: pre-wrap 원하는 높이는 4 줄이지만 3 줄만 높습니다.
따라서 끝에 0 너비 공간(U+200B)을 삽입함으로써 끝에 있는 줄 바꿈도 높이에 포함된다.0 너비는 텍스트 흐름에 영향을 주지 않습니다.
textarea.addEventListener('input', e => {
  dummy.textContent = e.target.value + '\u200b'
})

dummy와textarea의 미세한 행위를 통일하다


이곳이 가장 어려운 곳이다.
텍스트 영역의 크기는 dummy 표시에 따라 달라집니다.따라서'몇 글자로 줄을 바꾼다','줄 바뀔 때마다 얼마나 큰 변화가 있는가','금칙 처리 규칙'등을 동일하게 해야 한다.조건을 동일하게 하는 요소는 다음과 같다.
  • 글꼴
  • 문자 크기
  • 행 높이
  • 문자 간격
  • 격자선 너비
  • 충전 크기
  • 줄 바꿈할 수 없는 문자가 연속될 때의 처리
  • 이 문제들을 해결하기 위해서는 다음과 같은 코드가 필요하다.
    .FlexTextarea__dummy {
      box-sizing: border-box;
      padding: 5px 15px;
      white-space: pre-wrap;
      word-wrap: break-word;
      overflow-wrap: break-word;
      border: 1px solid;
    }
    
    .FlexTextarea__textarea {
      box-sizing: border-box;
      padding: 5px 15px;
      border: 1px solid #b6c3c6;
      font: inherit;
      letter-spacing: inherit;
    }
    
    텍스트 영역은 일반적으로 dummy 또는 border 을 설정해야 합니다.이와 함께 paddingdummy 도 같은 크기로 지정되었습니다.또한 상자의 크기를 통일하기 위해 계산하는 기준border도 필요하다.
    문자를 정렬하려면 padding, box-sizing: border-box 을 지정합니다.이렇게 하면 글씨체, 권중, 줄의 높이가 일치한다.font: inherit도 필요하다.
    'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaletter-spacing: inherit도 이에 상응하기 때문에 letter-spacing: inherit와 뒤로 호환되는 dummy 속성을 설정한다.

    수동 크기 조정 방지


    텍스트 영역이 자동으로 크기를 조정하기 때문에 오른쪽 아래에 표시되는 크기 조정 핸들이 필요하지 않습니다.
    .FlexTextarea__textarea {
      resize: none;
    }
    

    초점 고리 보이기


    신축 가능 여부와는 상관없지만 텍스트 영역에서 초점을 받았을 때 명확한 표시기를 잘 보여 주십시오.대부분 기본 overflow-wrap 이면 됩니다.여유가 있다면 자신의 지시기를 보여주면 멋있겠죠.
    .FlexTextarea__textarea:focus {
      box-shadow: 0 0 0 4px rgba(35, 167, 195, 0.3);
      outline: none; /* box-shadow を代わりに使っているから outline は不要 */
    }
    

    화면 판독기 등 지원 기술 고려

    word-wrap에는 텍스트 영역에 입력한 텍스트가 직접 입력됩니다.이 요소는 outline 속성을 설정했지만 신중을 기하기 위해 HTML도 .FlexTextarea__dummy 속성을 사용하여 이 요소가 내용과 무관하다는 것을 나타낸다.
    <div class="FlexTextarea__dummy" aria-hidden="true"></div>
    

    완성


    이렇게 완성된 FlexTextarea 구성 요소를 사용하십시오.맨 위에 적힌 것은 완성계의 코드다.

    좋은 웹페이지 즐겨찾기