โดยค่าเริ่มต้น ตัวควบคุมแบบฟอร์ม เช่น <input>, <textarea> และ <select> จะมีขนาดคงที่ ขนาดของช่องจะคงที่ ไม่ว่าผู้ใช้จะป้อนหรือเลือกเนื้อหามากน้อยเพียงใดก็ตาม
หากต้องการอนุญาตให้ตัวควบคุมเหล่านี้ย่อหรือขยายโดยอัตโนมัติเพื่อให้พอดีกับเนื้อหา (รวมถึงตัวยึดตำแหน่ง) ให้ใช้พร็อพเพอร์ตี้ CSS field-sizing: content
การควบคุมแบบฟอร์มการปรับขนาดอัตโนมัติ
การตั้งค่า field-sizing: content ในอินพุต, ตัวเลือก หรือพื้นที่ข้อความช่วยให้ปรับขนาดแบบไดนามิกได้เมื่อผู้ใช้พิมพ์หรือเลือกตัวเลือก อย่างไรก็ตาม คุณต้องพิจารณาการจัดรูปแบบที่รับค่ามา ค่าเริ่มต้นของเลย์เอาต์ และการจำกัดขั้นต่ำ/สูงสุดเพื่อให้ผู้ใช้ได้รับประสบการณ์ของผู้ใช้ที่มีประสิทธิภาพ
เพื่อป้องกันปัญหาเกี่ยวกับเลย์เอาต์ เราขอแนะนำให้ตั้งค่าทั้ง min-inline-size (หรือ min-width) และ max-inline-size (หรือ max-width) ควบคู่ไปกับ field-sizing: content ในการป้อนข้อความ ขนาดขั้นต่ำจะป้องกันไม่ให้ช่องป้อนข้อมูลยุบลงจนมีความกว้างเป็น 0 เมื่อว่างเปล่า (ทำให้คลิกไม่ได้) และขนาดสูงสุดจะช่วยให้มั่นใจได้ว่าช่องป้อนข้อมูลจะไม่ขยายออกไปเรื่อยๆ จนทำให้เลย์เอาต์ของหน้าเสีย
สำหรับ textarea การอนุญาตให้ปรับขนาดอัตโนมัติในแนวนอนอาจทำให้ UX ไม่ราบรื่น (เช่น textarea ที่มีตัวยึดตำแหน่งยาวจะหดตัวในแนวนอนอย่างกะทันหันเมื่อผู้ใช้พิมพ์อักขระเพียงตัวเดียว) หากต้องการป้องกันปัญหานี้ ให้ใช้ความกว้างที่ชัดเจน (เช่น width: 100%) กับ textarea ซึ่งจะบังคับให้ textarea คงความกว้างแนวนอนที่คงที่ไว้ขณะที่ยังคงปรับขนาดแนวตั้งโดยอัตโนมัติเมื่อเนื้อหาตัดขึ้นบรรทัดใหม่
ขอแนะนำให้ตั้งค่า max-inline-size (หรือ max-width) ในองค์ประกอบ <select> โดยใช้ field-sizing: content เพื่อให้แน่ใจว่าตัวเลือกที่เลือกซึ่งมีความยาวมากจะไม่ทำให้เลย์เอาต์ของหน้าเสียหาย
/* 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% คุณต้องรีเซ็ตเป็น width: auto (หรือ width: fit-content) อย่างชัดเจนในองค์ประกอบที่ใช้ field-sizing: content เพื่อให้การปรับขนาดอัตโนมัติทำงาน ในทางกลับกัน คุณควรตั้งค่า height: auto ใน textarea อย่างชัดเจนหากก่อนหน้านี้มีการตั้งค่าความสูงคงที่ไว้ทั่วโลก
สำคัญ: เลย์เอาต์แบบตารางกริดและ Flexbox มักจะยืดองค์ประกอบย่อยโดยนัยเพื่อเติมพื้นที่ว่างที่มีอยู่ หากตัวควบคุมแบบฟอร์มที่ใช้ field-sizing: content ไม่ยอมหด ให้ตรวจสอบพร็อพเพอร์ตี้การจัดแนวของคอนเทนเนอร์และใช้ align-self: start หรือ justify-self: start กับตัวควบคุมแบบฟอร์มเพื่อลบล้างการยืด
กลยุทธ์สำรอง
ควรใช้ field-sizing เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง ในเบราว์เซอร์ที่ไม่รองรับพร็อพเพอร์ตี้นี้ ตัวควบคุมแบบฟอร์มจะลดลงอย่างค่อยเป็นค่อยไปกลับไปเป็นลักษณะการทำงานของการปรับขนาดคงที่ตามค่าเริ่มต้น ผู้ใช้จะเห็นการเลื่อนแบบมาตรฐานสำหรับเนื้อหาที่ล้นภายในอินพุตและ textarea ที่มีขนาดคงที่
หากจำเป็นต้องใช้ช่องที่ขยายแบบไดนามิกสำหรับเบราว์เซอร์รุ่นเก่า คุณต้องใช้การตรวจหาฟีเจอร์และวิธีแก้ปัญหาที่ซับซ้อน ทางเลือกสำรองที่มีประสิทธิภาพที่สุดสำหรับ textarea ใช้เคล็ดลับ CSS Grid โดยที่องค์ประกอบจำลองที่ซ่อนอยู่จะแสดงอินพุตของผู้ใช้แบบเรียลไทม์ ซึ่งจะบังคับให้คอนเทนเนอร์ Grid (และ 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 สำหรับการควบคุมแบบฟอร์มทุกรายการ การใช้ลักษณะการทำงานสำรองเริ่มต้นของอินพุตแบบคงที่จึงเป็นแนวทางที่แนะนำสำหรับแอปพลิเคชันส่วนใหญ่ เว้นแต่ว่าการปรับขนาดแบบไดนามิกจะมีความสำคัญต่อประสบการณ์ของผู้ใช้