見出し画像

入力に応じて伸びていくテキストエリア

テキストエリア(textarea)はそのサイズを超えるテキストを入力するとスクロールバーが現れ、全体を表示してくれません。テキストを入力するとその文字数に応じて勝手に縦に伸縮するtextareaが欲しいというケースは多く、サンプルも多数ありますが、貸し本棚で実装している方法を単純化して説明してみたいと思います。理屈はめちゃくちゃ単純です。

ダミーテキストで全体を拡張する

大枠のdivを用意してrelativeにします。その中にダミー用のdivを下に、テキスト入力するtextareを上に重ねて配置します。textareaでダミーdivが隠れるようにします。

入力テキストと同じ内容をtextareaの裏側のdivに書き出し、そのdivが全体のdivを押し拡げ、textareaも拡張する、という原理です。

上記サンプルでは

  • text-pane(div)

    • text-pane-dummy(div)

    • text-pane-editor(textarea)

という階層構造になっています。

text-paneが全体を囲む親divで、relativeです。わかりやすくするため、borderで囲ってあります。
text-pane-dummyがダミーテキストを表示します。これはtextareaが上に乗るので画面上は見えません。
text-pane-editorが実際にテキスト入力するtextareaです。このtextareaはtextというデータがmodelになっていて、text-pane-dummyにbindしてます。textareaに入力した文字列はそのままtext-pane-dummyに書き出されます。同一の内容が同一フォーマットのdivに出力されます。

こんなふうに重なっています

textareaはheight:100%なので、text-pane-dummyで親のtext-paneが押し拡げられると、そのサイズに応じて縦に拡がります。結果、入力した値に応じて拡がっていくtextareaが出来上がります。こんな感じで、原理はとてもシンプルです。シンプルすぎてちゃんと説明してくれないサンプルが多いですが。

原理が理解できれば縦書きにも応用できると思います。テキストを縦にするだけです。この仕組みをコンポネント分解できれば、色々なところで再利用できると思います。

0幅のスペース

\u200bという文字を付加していますが、これは幅0のスペースという奇妙なメタ文字です。

あまり深く考えずに付与してください。これが無いと正常に拡がりません。

なんでtextarea?

WYSIWYGエディタやcontenteditableの方が使いやすそうですが、小説は1話にかなり膨大なテキストを記述します。あまりパワーのない端末で大量のテキストを記述すると、WYSIWYGエディタでは入力速度が落ちる問題が起きやすくなります。contenteditableはペースト保全が完全にできなかったので見送っています(危険な値を埋め込まれる恐れ)。

長文編集において絶対に問題が起きないという保証が必要なため、ひとまず軽量なtextareaによって本文の記述を実装しています。

アイキャッチはUnsplashJohn Jenningsが撮影した写真


この記事が気に入ったらサポートをしてみませんか?