Secara default, kontrol formulir seperti <input>, <textarea>, dan <select> memiliki dimensi tetap. Ukurannya tetap konstan, terlepas dari jumlah konten yang dimasukkan atau dipilih pengguna.
Untuk mengizinkan kontrol ini menyusut atau membesar secara otomatis agar sesuai dengan kontennya (termasuk placeholder), gunakan properti CSS field-sizing: content.
Kontrol formulir pengubahan ukuran otomatis
Menetapkan field-sizing: content pada input, pilihan, atau textarea memungkinkan elemen tersebut diubah ukurannya secara dinamis saat pengguna mengetik atau memilih opsi. Namun, Anda harus memperhitungkan gaya turunan, default tata letak, dan batasan minimum/maksimum untuk memastikan pengalaman pengguna yang andal.
Untuk mencegah masalah tata letak, sebaiknya tetapkan min-inline-size (atau min-width) dan max-inline-size (atau max-width) bersama dengan field-sizing: content pada input teks. Ukuran minimum mencegah input diciutkan menjadi lebar nol saat kosong (sehingga tidak dapat diklik), dan ukuran maksimum memastikan input tidak diperluas tanpa batas dan merusak tata letak halaman.
Untuk textarea, mengizinkan pengubahan ukuran otomatis horizontal dapat menyebabkan UX yang mengganggu (misalnya, textarea dengan placeholder panjang akan tiba-tiba menyusut secara horizontal saat pengguna mengetik satu karakter). Untuk mencegahnya, terapkan lebar eksplisit (seperti width: 100%) ke textarea. Hal ini memaksa textarea untuk mempertahankan lebar horizontal yang stabil sambil tetap mengubah ukuran secara vertikal secara otomatis saat konten digabungkan.
Sebaiknya tetapkan max-inline-size (atau max-width) pada elemen <select> menggunakan field-sizing: content untuk memastikan bahwa opsi yang dipilih yang sangat panjang tidak merusak tata letak halaman.
/* 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;
}
PENTING: Properti width dan height eksplisit menggantikan field-sizing: content di semua kontrol formulir. Jika CSS global project Anda menetapkan input, pilihan, atau textarea ke width: 100%, Anda harus meresetnya secara eksplisit ke width: auto (atau width: fit-content) pada elemen menggunakan field-sizing: content agar pengubahan ukuran otomatis berfungsi. Sebaliknya, Anda harus menetapkan height: auto secara eksplisit pada textarea jika tinggi tetap sebelumnya ditetapkan secara global.
PENTING: Tata letak Grid dan Flexbox sering kali secara implisit meregangkan turunannya untuk mengisi ruang yang tersedia. Jika ada kontrol formulir yang menggunakan field-sizing: content dan tidak dapat menyusut, periksa properti perataan penampungnya dan terapkan align-self: start atau justify-self: start ke kontrol formulir untuk mengganti peregangan.
Strategi penggantian
field-sizing harus diperlakukan sebagai progressive enhancement. Di browser yang tidak mendukung properti ini, kontrol formulir akan mengalami degradasi halus kembali ke perilaku ukuran tetap defaultnya. Pengguna hanya akan mengalami scroll standar untuk konten yang meluap di dalam input dan textarea berukuran tetap.
Jika kolom yang berkembang secara dinamis benar-benar diperlukan untuk browser lama, Anda harus menggunakan deteksi fitur dan solusi yang kompleks. Penggantian yang paling andal untuk textarea menggunakan trik petak CSS, yaitu elemen semu tersembunyi mencerminkan input pengguna secara real-time, sehingga memaksa penampung petak (dan textarea di dalamnya) untuk meluas.
<!-- 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;
}
}
Mengingat kompleksitas penduplikasian gaya dan sinkronisasi status di seluruh node DOM untuk setiap kontrol formulir, mengandalkan perilaku penggantian default input tetap adalah pendekatan yang direkomendasikan untuk sebagian besar aplikasi, kecuali jika ukuran dinamis sangat penting untuk pengalaman pengguna.