Thẻ `<output>`
(denodell.com)- Thẻ
<output>không được nhiều lập trình viên web biết đến, nhưng mặc định hỗ trợ hiển thị kết quả động và khả năng truy cập cho screen reader - Đã tồn tại từ lâu trong đặc tả HTML và được tự động ánh xạ thành role="status", giúp công nghệ hỗ trợ cho người khiếm thị thông báo các thay đổi
<output>được dùng để thông báo kết quả được tính toán dựa trên giá trị đầu vào, nhưng thường bị bỏ qua trong đa số hướng dẫn và thư viện- Cung cấp khả năng truy cập vượt trội, bao gồm hỗ trợ thuộc tính
for="", và cũng tương thích rất tốt với các framework JavaScript - Có thể được áp dụng hữu ích trong nhiều dự án thực tế như máy tính, định dạng giá trị slider, phản hồi kiểm tra hợp lệ của biểu mẫu
Viên ngọc ẩn trong HTML: thẻ <output>
Mọi lập trình viên đều rất quen thuộc với phần tử <input>, đây là phương tiện nhập liệu cốt lõi của web.
Nhưng phần tử <output> thì hầu như chưa từng được đa số người dùng tới, thậm chí nhiều người còn không biết nó tồn tại.
Điều này khá đáng tiếc, vì biểu diễn kết quả động và khả năng truy cập mà lâu nay chúng ta thường chắp vá bằng <div> và ARIA thực ra đã được <output> giải quyết sẵn theo mặc định.
Thẻ này đã tồn tại trong đặc tả HTML từ rất lâu, nhưng đến nay vẫn chưa được biết đến rộng rãi.
Định nghĩa trong đặc tả HTML5
Theo đặc tả HTML5,
phần tử
<output>biểu thị kết quả được tính toán trong ứng dụng hoặc kết quả của hành động người dùng
Trong cây truy cập, nó được ánh xạ thành role="status", nên mỗi khi giá trị thay đổi, screen reader sẽ tự động thông báo toàn bộ nội dung cho người dùng.
Điều này tương tự như việc mặc định có aria-live="polite" aria-atomic="true".
Cách hoạt động này có đặc điểm là đọc toàn bộ nội dung một cách từ tốn mà không làm gián đoạn luồng thao tác của người dùng.
Nếu cần, lập trình viên vẫn có thể chỉ định thêm các thuộc tính ARIA để thay đổi hành vi.
Cách dùng <output>
Có thể dùng đơn giản như sau:
<output>Hiển thị giá trị động tại đây</output>
Chỉ như vậy thôi cũng đã nhận được hỗ trợ công nghệ hỗ trợ tích hợp sẵn, không cần thuộc tính bổ sung hay API khó nhớ, và có thể đạt khả năng truy cập chỉ bằng HTML thuần.
Khoảnh khắc phát hiện ra nó
Tác giả nhận ra giá trị của <output> trong một dự án về khả năng truy cập khi xử lý hiển thị điểm số của biểu mẫu nhiều bước.
Sự thay đổi điểm số có thể nhìn thấy trên màn hình, nhưng người dùng screen reader lại không thể biết điều gì đã thay đổi.
Có thể giải quyết bằng ARIA live region, nhưng dùng HTML có ngữ nghĩa rõ ràng vẫn là lựa chọn tốt hơn.
Trong lúc xem lại đặc tả, tác giả phát hiện ra <output> có thể dùng tách biệt với form và tự động thông báo kết quả, và nhận ra rằng lời giải đơn giản nhất thực ra đã có sẵn trong đặc tả từ lâu.
Vì sao nó ít được dùng
Đây là một thẻ bị lãng quên, hầu như không được nhắc đến trong đa số tutorial hay thư viện component, và cũng gần như không có ví dụ sử dụng trong các kho mã công khai trên Github.
Vì vậy, khoảng trống kiến thức cứ tiếp tục lặp lại, tạo nên vòng luẩn quẩn rằng nó không được dùng nhiều nên càng ít người biết đến.
Những điểm đáng biết
<output>cũng có thuộc tínhfor=""giống như<label>- Có thể khai báo các
idcách nhau bằng dấu cách để chỉ ra kết quả phụ thuộc vào những giá trị đầu vào nào
- Có thể khai báo các
- Về mặt hiển thị trực quan thì không khác biệt, nhưng trong cây truy cập, nó tạo liên kết ngữ nghĩa giữa đầu vào và kết quả
- Có thể dùng ở bất cứ đâu cho văn bản thay đổi động theo đầu vào của người dùng, ngay cả khi không có phần tử
<form> - Mặc định là phần tử inline, nên tùy mục đích bố cục có thể cần style như
<span>hoặc<div> - Đã có trong đặc tả từ năm 2008, nên hỗ trợ của trình duyệt và screen reader là rất tốt
- Tương thích rất tốt với mọi framework JS như React, Vue
- Tính đến tháng 10/2025, vẫn có một số screen reader không đọc các cập nhật, nên trong trường hợp này nên thêm thuộc tính
role="status"
Quan trọng:
<output> phù hợp với kết quả tính toán hoặc kết quả hành động có liên kết rõ ràng với đầu vào của người dùng,
không nên dùng cho thông báo toàn cục (ví dụ: toast message); với phản hồi hệ thống thì nên xử lý bằng role="status" hoặc role="alert".
Ví dụ sử dụng thực tế
Ứng dụng máy tính
Khi tạo một ứng dụng máy tính đơn giản, nếu dùng <output> để hiển thị kết quả thì có lợi thế là giá trị kết quả được tự động thông báo mà không cần thêm vai trò ARIA.
Định dạng giá trị slider (trường hợp của Volvo Cars)
Điều chỉnh giá trị nội bộ bằng slider (ví dụ: 10000), rồi hiển thị trong <output> dưới dạng dễ đọc hơn (10,000 miles/year).
Có thể gán role="group" và nhãn dùng chung cho container để phục vụ khả năng truy cập cũng như khả năng kết hợp component trong React.
Phản hồi kiểm tra hợp lệ của biểu mẫu
Các thông báo kiểm tra theo thời gian thực như độ mạnh mật khẩu cũng có thể được thông báo ngay cho người dùng công nghệ hỗ trợ thông qua <output>.
Hiển thị kết quả tính toán từ máy chủ
<output> cũng phù hợp cho các giá trị được máy chủ tính toán như chi phí vận chuyển, thuế, hay giá trị gợi ý lấy từ API máy chủ.
Như trong ví dụ React bên dưới, có thể nhận số tiền từ máy chủ và hiển thị ngay trong <output>.
Cảm giác hài lòng khi dùng phần tử native
Bằng cách sử dụng đúng phần tử HTML thuần theo đúng mục đích mà đặc tả đã định nghĩa,
có thể nâng cao khả năng truy cập, đơn giản hóa mã nguồn,
và khám phá lại giá trị cũng như cách ứng dụng của thẻ <output> ít người biết đến.
Điều này cũng gợi ý rằng trong HTML vẫn còn nhiều phần tử giống như những viên ngọc ẩn.
Cập nhật mới nhất: Bob Rudis đã công bố trang ví dụ hoạt động phù hợp với bài viết này
1 bình luận
Ý kiến trên Hacker News
Vấn đề của phần tử <output> là nó mới được triển khai nửa vời nên trên thực tế cảm giác gần như vô dụng
Tôi nghĩ nếu nó có thuộc tính
typenhưinputthì sẽ thực tế hơn nhiềuTôi đã thử nghiệm
output|typetrong Sciter của mình và thêm một số kiểu như sautype="text": mặc định, không định dạngtype="number": định dạng số theo locale của người dùngtype="currency": định dạng tiền tệ theo locale của người dùngtype="date": hiển thị dưới dạng ngày, không chuyển đổi múi giờtype="date-local": định dạng ngày cục bộ, chuyểndatetimeUTC sang giờ địa phươngtype="time": hiển thị dưới dạng giờtype="time-local": giờ địa phương, giá trị được xử lý nhưdatetimeUTCTheo cách này, server vẫn có thể gửi dữ liệu mà không cần biết locale của người dùng
Đúng như trong bài viết và spec, <output> dùng để hiển thị kết quả tính toán trong app hoặc kết quả của hành động người dùng
Phần ngữ nghĩa ARIA mới là điểm quan trọng, và khi trang được cập nhật thì screen reader sẽ đọc kết quả
Bên trong <output> bạn có thể tự đưa vào cách biểu diễn kiểu dữ liệu mong muốn
"text"là mặc định, còn ngày giờ thì có thể dùng thẻ <time>Hiện chưa có thẻ chuyên cho định dạng số, nhưng từ sau khi có
Intlthì nhu cầu này ngày càng nhiềuVí dụ:
<output>The new date is <time datetime="2025-10-11">Oct 11</time></output>
Tức là <output> không cần tự xử lý mọi kiểu dữ liệu, mà toàn bộ HTML mới là nơi biểu đạt kiểu dữ liệu
Tôi đồng ý với ý rằng vì là tính năng nửa vời nên nó gần như vô dụng
Đáng tiếc là đến năm 2025 vẫn còn quá nhiều trường hợp như vậy
Tôi nghĩ Safari phải chịu trách nhiệm cho một phần không nhỏ
Ví dụ cực đoan nhất là
<input type="date">Người ta bảo có thể dùng ngay trong production, nhưng vì vấn đề giữa các trình duyệt nên cuối cùng lại hay dùng JS date picker hơn, cảm giác rất kỳ
Điều tôi mong là <output> có thể nối trực tiếp với <input> để hiển thị kết quả
Ví dụ: <input type="range" id="example_id" name="example_nm" min="0" max="50"> <output name="example_result" for="example_id"></output> Tôi muốn nó có thể hiển thị trực tiếp giá trị của input như vậy
Sẽ càng tốt hơn nếu có thêm chỉ định
"type", và cũng hỗ trợ thay đổi nội dung bằngcontent:trong CSS::beforehay::afterTôi nghĩ nếu có các tính năng định dạng kiểu này cho nhiều loại
<input>khác nhau thì sẽ rất hữu íchĐặc biệt với
type="tel", sẽ tiện nếu có thể hiển thị số nhập vào theo định dạng đẹp hơnNó cũng có thể áp dụng cho
'checkbox, color, date, datetime-local, file, month, number, radio, range, tel, time, url, week'Với các kiểu văn bản, trong một số điều kiện nhất định cũng có thể hữu ích
Và tôi cũng muốn thuộc tính
for=""có nhiều vai trò hơnHiện tại phần lớn ví dụ đều biến tấu theo kiểu
<output name="result"><form oninput="result.value=...">Nghĩ rằng <output> nên có
typeđối xứng với input là một cách tiếp cận saioutput không phải là thứ có kiểu dữ liệu như input, mà là một container có nội dung thay đổi trên trang
Tôi thích dạng bên dưới hơn <output for=input>
<!-- chèn component time-locale tùy biến --><time is=time-locale datetime=2001-02-03>2001-02-03</time> </output> Tôi muốn component này có thể đổi giá trị theo locale
Tạo nội dung giả bằng HTML/CSS dễ gây ra đủ loại vấn đề
Ví dụ khi copy thứ được chèn bằng CSS
::before/:after, hoặc sự khác biệt giữa.innerTextvà inner text thực tếDĩ nhiên vẫn cần đưa ra quyết định cho những chuyện này, nhưng nếu nhồi quá nhiều tính năng vào một thẻ thì cuối cùng nó sẽ thành một DSL chỉ dành riêng cho thẻ đó
Loại giá trị (tuyệt đối/tương đối), dữ liệu đi kèm (như loại tiền tệ), đều trở thành một phần của cách HTML xử lý và không còn dễ chỉnh linh hoạt bằng JS nữa
<output>? Tôi cũng chưa từng dùng
Hôm nay mới biết đến nó nên đã thêm vào danh sách TIL (hôm nay học được gì)
Ngay cả khi tìm trong các repo public trên GitHub cũng hầu như không thấy, vì nếu không ai dạy thì sẽ không ai dùng
Từ đó tôi chợt nghĩ đến chuyện liệu LLM khi sinh code có thực sự dùng thẻ này không, hay là thậm chí chưa hề học đến nó
Tôi cũng lo chuyện AI không đọc tài liệu/spec
Nếu một spec W3C mới xuất hiện mà phần lớn mọi người chỉ “vibe coding” thì sao?
Nếu AI không phản ánh spec mới nhất mà chỉ lặp lại các pattern code cũ, thì việc phổ biến các cập nhật spec có lẽ sẽ còn khó hơn bây giờ
Tôi lần đầu phát hiện ra thẻ <output> là nhờ Claude sinh code cho tôi
LLM không trực tiếp đọc tài liệu tiêu chuẩn, mà sinh code dựa trên các mẫu thống kê từ lượng dữ liệu khổng lồ lấy từ các dự án có sẵn
Nếu trong code thực tế thẻ này gần như không được dùng, thì đầu ra code của LLM cũng sẽ gần như không có nó
Cập nhật ngày 7 tháng 10 năm 2025: một số screen reader vẫn chưa nhận ra các thay đổi cập nhật của thẻ <output>, nên trong một thời gian có lẽ tốt hơn là chỉ định rõ thuộc tính
role, ví dụ:<output role="status">Không rõ có phải chúng ta chỉ còn cách tiếp tục chờ hỗ trợ cho một thẻ đã tồn tại 17 năm hay không
Trên Windows, nếu mở issue trong repo NVDA thì họ xử lý khá tốt
https://github.com/nvaccess/nvda
Dù đã là chuẩn suốt 17 năm, vẫn cần nỗ lực để cải thiện chuyện screen reader bỏ qua thẻ này
Theo tôi đây rõ ràng là vấn đề từ phía screen reader
Tôi đã học nhiều khóa về web accessibility phía frontend nhưng chưa từng thấy thẻ <output> lần nào
Cảm ơn vì đã chia sẻ thông tin hữu ích
<output> cũng có thuộc tính
for=""giống như <label>, nên tôi khá tò mò liệu với người dùng screen reader điều đó có mang ý nghĩa thực tế nào khôngVì trên web hiện nay gần như không ai dùng, nên có thể người dùng screen reader cũng không quen với nó, nhưng cuối cùng chắc vẫn phụ thuộc vào UX của phần mềm
Tôi vẫn nghi ngờ liệu nó có được lộ ra đúng cách cho công nghệ hỗ trợ hay không
Hiện tôi không ở trước máy nên không thể test ngay bây giờ
Cá nhân tôi nghĩ tốt hơn là gắn nhãn rõ ràng cho giá trị output
Ví dụ: <label for="output">Total</label> <output id="output">£123.45</output> Làm vậy thì screen reader sẽ đọc kiểu “Total, £123.45”, dễ nắm được ngữ cảnh hơn
Tôi thấy semantic HTML chỉ là một cái bẫy cho người mới
Đừng bận tâm nữa, cứ dùng các giải pháp thực sự hoạt động như
aria-liveMấy phần tử kiểu này có thể vui để thử, nhưng với tư cách developer thì trách nhiệm là tạo ra cấu trúc thực sự hoạt động cho người dùng
Thay vì các thẻ semantic ít được dùng, nên dùng thứ mà browser và hệ sinh thái hiện có đang kỳ vọng
Với kinh nghiệm làm nhiều EPUB, tôi thấy cấu trúc trang mang tính ngữ nghĩa giúp mọi thứ dễ dàng và tốt hơn nhiều
Hôm nay tôi mới biết <output> là thẻ phục vụ accessibility trên web page, đặc biệt là hỗ trợ screen reader
“ARIA” là viết tắt của Accessible Rich Internet Applications, tức tập hợp các thuộc tính HTML giúp tăng khả năng tiếp cận cho người khuyết tật
Nghe như đang giải thích JavaScript là gì ngay dưới một bài về React vậy
Không biết nền tảng về accessibility thì chẳng có gì phải xấu hổ, nhưng cũng không cần phản ứng như thể việc độc giả không biết là điều gì lạ lùng
MDN có tài liệu liên quan được tổng hợp rất tốt
(tác giả bài viết cũng nhấn mạnh cùng một hướng dẫn)
“Quy tắc đầu tiên khi dùng ARIA là: nếu đã có phần tử hoặc thuộc tính HTML native đáp ứng được ngữ nghĩa và hành vi cần thiết, thì đừng tái sử dụng bằng cách thêm ARIA role, state hoặc property; hãy dùng ngay phần tử/thuộc tính native đó.”
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA
Cảm ơn lời giải thích
Thật ra tôi cũng có thể tự Google, nhưng vào một chiều thứ Bảy lười biếng thế này thì đọc bình luận của bạn vẫn thoải mái hơn
Cảm ơn lần nữa
Chỉ nhìn tiêu đề bài này tôi đã tưởng <output> đang bị dùng sai, nhưng đọc xong thì thực sự bất ngờ
(nhất là khi nhìn cái ảnh dodgy GenAI calculator ở trên cùng, tôi còn nghĩ sẽ là một màn fail nặng hơn nhiều, vậy mà nội dung hay đến mức đọc xong hết rồi tôi mới lại nhớ đến cái ảnh đó)
Cái ảnh dodgy GenAI calculator buồn cười thật
Nó chỉ cộng, nhân, chia được chứ không trừ được
Nhân nói về ảnh dodgy GenAI calculator
Có cảm giác chúng ta đang quên mất rằng trước thời AI, con người cũng từng tạo ra vô số hình ảnh còn cẩu thả hơn thế
Nhờ AI mà giờ ít nhất cũng có thể tạo ra ngay những hình ảnh không đến mức gây xấu hổ
Trường hợp này thì (theo cảm nhận cá nhân) nó còn mang được chất retro IT kiểu vintage nên cũng có giá trị riêng
Tôi không nghĩ mọi cách dùng AI đều nhằm thay thế công việc của nghệ sĩ chuyên nghiệp
Mỗi lần thấy mấy nội dung như thế này tôi đều thích
Một mẹo khác là đặt tên form sao cho khớp với cấu trúc dữ liệu ở backend, như vậy sẽ bớt phải lấy giá trị bằng JS hoặc tái cấu trúc dữ liệu
Ví dụ như thế này: <input name=“entity[id]”> <input name=“entity[relation]”> Làm vậy thì không cần mất công tạo dữ liệu riêng bằng JS nữa, chỉ submit form là ra đúng dữ liệu mong muốn