O hirunewani blog

Q. textareaに掛けたfield-sizing: content; width: 100%;が効かない

Created at

textareaにfield-sizing: content; width: 100%;などを指定しても親要素の幅を超えてしまうという相談を受けたので、その原因と対応についてまとめた。

状況

display:grid が付けられたform要素の直下ではないtextareaでwidth: 100%max-width: 100%などを付けても、form要素をはみ出てしまう。

<style>
  form {
    display: grid;
    max-width: 400px;
  }
  textarea {
    field-sizing: content;
    width: 100%;
  }
</style>
<form>
  <textarea>入力文字列がform要素の幅を超えると自動的に改行される</textarea>
  <div>
    <textarea>ここは入力文字列の長さに応じて、はみ出る</textarea>
  </div>
</form>

次の状況では、発生しない。

  • Gridコンテナ直下のtextareaである。
  • Form要素がGridではなくFlexboxまたは、ただのブロックコンテナである。

考察

  • aspect-ratioが付いた要素や、スタイルをリセットしていないForm関連要素が、Gridコンテナ内ではみ出てしまうケースと同様だと思われる。
  • 実際に、textareaの親であるdiv要素にmin-width: 0pxを付けると、この問題は解消する。

よって、次のような状態であると推測できる。

  • grid-template-columnsが指定されていないため、grid-template-columns: 1frと同じ。
  • 1frはminmax(auto, 1fr)として解釈されるため、grid-template-columns: minmax(auto, 1fr)を指定している状態と同じ。
  • autoが解釈する大きさが、1frを超えているため、Gridコンテナから要素がはみ出てしまう。

解決策

次のいずれかで解消する。

実験:https://stackblitz.com/edit/js-xczysq?file=style.css

grid-template-columns: minmax(0px, 1fr);を使う

より本質的な修正。

form {
  display: grid;
  grid-template-columns: minmax(0px, 1fr);
  max-width: 400px;
}

GridではなくFlexboxを利用する

別にFlexboxでも問題なければ、これで良いが、理由はちゃんと書いておかないとワークアラウンドとしてGridが避けられていることが伝わらないと思うので注意。

form {
  display: flex;
  flex-direction: columns;
  max-width: 400px;
}

min-width: 0pxをGridアイテムに付ける

動機が分かりにくく、問題の箇所とも距離があるので、おすすめはしない。

form > div {
  min-width: 0px;
}