デフォルトでは、<input>、<textarea>、<select> などのフォーム コントロールのサイズは固定されています。ユーザーが入力または選択したコンテンツの量に関係なく、サイズは一定です。
これらのコントロールがコンテンツ(プレースホルダを含む)に合わせて自動的に縮小または拡大されるようにするには、field-sizing: content CSS プロパティを使用します。
フォーム コントロールの自動サイズ設定
入力、選択、テキストエリアに field-sizing: content を設定すると、ユーザーがオプションを入力または選択したときに、動的にサイズを変更できます。ただし、堅牢なユーザー エクスペリエンスを実現するには、継承されたスタイル設定、レイアウトのデフォルト、最小 / 最大の制約を考慮する必要があります。
レイアウトの問題を防ぐため、テキスト入力では field-sizing: content とともに min-inline-size(または min-width)と max-inline-size(または max-width)の両方を設定することをおすすめします。最小サイズを設定すると、入力が空のときに幅がゼロに縮小してクリックできなくなるのを防ぐことができます。最大サイズを設定すると、入力が無限に拡大してページ レイアウトが崩れるのを防ぐことができます。
textarea で水平方向の自動サイズ変更を許可すると、UX が不快になる可能性があります(たとえば、長いプレースホルダを含む textarea は、ユーザーが 1 文字入力すると水平方向に急に縮小します)。これを防ぐには、textarea に明示的な幅(width: 100% など)を適用します。これにより、テキストエリアの水平方向の幅が安定し、コンテンツの折り返しに合わせて垂直方向に自動サイズ調整されます。
field-sizing: content を使用して <select> 要素に max-inline-size(または max-width)を設定することをおすすめします。これにより、選択したオプションが非常に長い場合でも、ページ レイアウトが崩れることがなくなります。
/* Applies horizontal auto-sizing to inputs */
input {
/* Instructs the element to size itself to fit its content */
field-sizing: content;
/* Reset explicit width if inherited from global styles */
width: auto;
/* Prevents the input from collapsing and disappearing when empty */
min-inline-size: 15ch;
/* Prevents infinite horizontal growth */
max-inline-size: 50ch;
}
textarea {
/* Instructs the element to size itself to fit its content */
field-sizing: content;
/* Reset explicit height if inherited from global styles */
height: auto;
/* Use a fixed width to prevent jarring horizontal shifts when replacing a long placeholder */
width: 50ch; /* or 100% depending on your layout */
/* Sets a reasonable minimum height (e.g., 3 lines) for empty textareas */
min-block-size: 3lh;
/* Prevents infinite vertical growth. Once a textarea hits this */
/* height, it will stop growing and show a vertical scrollbar. */
max-block-size: 10lh;
}
select {
/* Sizes the select element to fit the active option only */
field-sizing: content;
/* Prevents the dropdown from expanding infinitely and breaking the layout */
max-inline-size: 50ch;
}
重要: 明示的な width プロパティと height プロパティは、すべてのフォーム コントロールで field-sizing: content をオーバーライドします。プロジェクトのグローバル CSS で入力、選択、テキストエリアが width: 100% に設定されている場合は、field-sizing: content を使用して要素で明示的に width: auto(または width: fit-content)にリセットする必要があります。逆に、以前に固定の高さをグローバルに設定していた場合は、textarea に height: auto を明示的に設定する必要があります。
重要: グリッド レイアウトと Flexbox レイアウトでは、多くの場合、利用可能なスペースを埋めるように子が暗黙的に引き伸ばされます。field-sizing: content を使用しているフォーム コントロールが縮小しない場合は、コンテナの配置プロパティを確認し、フォーム コントロールに align-self: start または justify-self: start を適用して、引き伸ばしをオーバーライドします。
代替戦略
field-sizing はプログレッシブ エンハンスメントとして扱う必要があります。このプロパティをサポートしていないブラウザでは、フォーム コントロールはデフォルトの固定サイズ設定動作に適切にグレースフル デグラデーションされます。固定サイズの入力要素やテキストエリア内でコンテンツがはみ出した場合、ユーザーは標準のスクロール操作を行うだけで済みます。
古いブラウザで動的に拡大するフィールドがどうしても必要な場合は、機能検出と複雑な回避策を使用する必要があります。textarea の最も堅牢なフォールバックは、CSS グリッドのトリックを使用します。このトリックでは、非表示の疑似要素がユーザーの入力をリアルタイムでミラーリングし、グリッド コンテナ(とその中の textarea)を強制的に拡張します。
<!-- The textarea is wrapped in a container that will mirror its value -->
<div class="growable-textarea" data-replicated-value="">
<textarea></textarea>
</div>
// Only attach the fallback event listeners if field-sizing is unsupported
if (!CSS.supports('field-sizing', 'content')) {
document.querySelectorAll('.growable-textarea > textarea').forEach(textarea => {
textarea.addEventListener('input', () => {
textarea.parentNode.dataset.replicatedValue = textarea.value;
});
});
}
/* Only apply the fallback if field-sizing is NOT supported */
@supports not (field-sizing: content) {
.growable-textarea {
display: grid;
}
/* The pseudo-element and textarea must share the exact same cell, font, and padding */
.growable-textarea::after,
.growable-textarea > textarea {
grid-area: 1 / 1 / 2 / 2;
font: inherit;
padding: 0.5rem;
border: 1px solid #999;
}
/* The pseudo-element renders the copied text invisibly to stretch the grid */
.growable-textarea::after {
/* The space is necessary for trailing empty lines to be rendered */
content: attr(data-replicated-value) " ";
white-space: pre-wrap;
visibility: hidden;
}
.growable-textarea > textarea {
resize: none;
overflow: hidden;
}
}
すべてのフォーム コントロールで DOM ノード間でスタイルを複製し、状態を同期する複雑さを考えると、動的なサイズ変更がユーザー エクスペリエンスに不可欠でない限り、固定入力のデフォルトのフォールバック動作に依存することが、ほとんどのアプリケーションで推奨されるアプローチです。