7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

入力にあわせて高さが自動で伸縮する textarea を、Blazor で作る

Last updated at Posted at 2024-12-03

お題

下図のような、入力したテキストにあわせて、高さが自動で伸縮される textarea を、Blazor で作ってみたいと思います。

movie-001.gif

実装例

以下のように Razor コンポーネントを実装してみました。

<div class="container">

    <div class="behind-textarea">@_text
        &nbsp;</div>

    <textarea @bind="_text" @bind:event="oninput"></textarea>

</div>

@code {
    private string _text = "";
}

textarea 要素に、string 型のフィールド変数 _text を双方向バインドし、バインドを発火するイベントに "oninput" を指定しています。つまり、textarea に対する何かしら入力が発生すると即時に、 フィールド変数 _text にその入力内容が反映されます。

そうしてリアルタイムに入力が反映されるフィールド変数 _text の内容を、div 要素内のコンテンツとして表示用に単方向バインドしています。

このように実装することで、フィールド変数 _text を媒介に、textarea に対する入力内容が、兄弟要素の div 要素のテキストコンテンツとして、リアルタイムで反映されるようになります。

そこでさらに、以下のように CSS スタイルを定義します。

.container {
    display: inline-block;

    /* コンテナ要素の幅は何か適当な値に設定しておく */
    width: 200px;

    /* このコンテナ要素が position: absolute の座標の基準となるようにする */
    position: relative;
}

/*
コンテナ要素内の、textarea 要素と div 要素の両者が、
ピクセルレベルでまったく同じテキスト描画となるよう、
フォントや枠線、パディング、折り返しなどを、
両者に同じく適用する
*/
.behind-textarea, textarea {
    font-family: monospace;
    font-size: 13.3px;
    padding: 2px;
    border-width: 1px;
    border-style: solid;
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}

/* コンテナ要素内の div 要素は、見た目上は非表示にする */
.behind-textarea {
    visibility: hidden;
}

/* textarea 要素が、コンテナ要素内めいっぱいに貼り付くようにする */
textarea {
    position: absolute;
    inset: 0;
}

この CSS は何をしているかというと、まず、フィールド変数 _text の内容を表示する div 要素と textarea 要素とで、テキストの表示上のピクセルが完全に一致するように、フォントやパディング、枠線、折り返し表示を両要素に適用しています。

その上で、textarea 要素を、この div 要素とまったく同じサイズ・同じ位置になるよう絶対座標配置したのです。

image.png

この div 要素は、そのテキストコンテンツは textarea とまったく同じようにテキストを折り返し表示しつつ、高さ方向に自動で伸縮しますよね。textarea 要素を、この div 要素と同じサイズ・同じ位置で表示されるように、CSS の position: absolute; を使って重ね合うようにレイアウトすることで、入力にあわせて高さが自動で伸縮する textarea を実現しました。

こんな感じで、CSS だけはちょっと凝った感じになりましたけれども、それ以外の Razor コンポーネント上の実装は、フィールド変数へのバインドがあるだけのシンプルな実装で、高さ自動伸縮の複数行テキスト入力が実装できました。

出典

このような、テキストコンテンツとサイズを揃えて textarea 要素を重ね合わせ配置する技法は、当然のことながら (?) 私のオリジナルの発案ではなく、どこかで見聞きしたもので、それを今回、Blazor で実践してみた次第です。StackOverflow の質問と答えで見たような記憶があるのですが、正確な出所は確認していません。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?