Cài đặt cue và ::cue CSS trong WebVTT: định vị phụ đề video web
💡 Để định vị một cue WebVTT, hãy thêm cài đặt như
line:90% position:5% align:starttrực tiếp sau-->trên dòng timestamp. Để tạo kiểu toàn cục, hãy thêm khốiSTYLEở đầu file .vtt với::cue { color: white; background-color: rgba(0,0,0,0.75); text-shadow: 1px 1px 2px black; }. Đây là hai cơ chế kiểm soát vị trí và giao diện phụ đề mà WebVTT cung cấp cho video web.
Điểm chính
- Cài đặt cue (
line:,position:,size:,align:) đặt sau-->trên dòng timestamp, phân cách bằng dấu cách, theo từng cue. - Khối
STYLEphải xuất hiện trước cue đầu tiên trong file. Bất kỳ khối STYLE nào đặt sau một cue đều bị trình phân tích bỏ qua. ::cuehỗ trợcolor,background-color,font-family,text-shadowvàopacity. Không hỗ trợmargin,padding,transformhay các thuộc tính layout.line:90%(phần trăm) định vị cue ở 90% chiều cao viewport.line:-1(số nguyên) căn vào dòng hiển thị cuối cùng ở dưới cùng.- Trình duyệt hỗ trợ
::cuerộng rãi từ tháng 1/2020.::cue-regioncó trong spec nhưng chưa có trình duyệt nào hỗ trợ.
Cài đặt cue trong WebVTT là gì?
WebVTT (Web Video Text Tracks) là định dạng văn bản có thời gian gốc của phần tử <video> trong HTML. Một file .vtt chứa chuỗi các cue. Mỗi cue có dòng timestamp, một định danh tùy chọn và phần văn bản payload. Cài đặt cue nằm trên dòng timestamp, sau -->, cho trình duyệt biết vị trí hiển thị cue trên màn hình.
Khác với SRT không có thông tin định vị, WebVTT cung cấp năm điều khiển không gian cho mỗi cue. Đây không phải CSS: chúng là một phần cú pháp cài đặt cue trong đặc tả WebVTT cấp 1 của W3C, và chỉ áp dụng cho cue được gắn vào.
Tôi dùng WebVTT cho mọi phần phụ đề web. Tất cả trình duyệt hiện đại hỗ trợ nó mà không cần JavaScript, và nó hoạt động tốt với cả định vị từng cue lẫn khối STYLE cho toàn bộ file.
Năm cài đặt cue và giá trị của chúng
Tất cả cài đặt cue đặt trên dòng timestamp sau -->, phân cách bằng dấu cách. Dưới đây là ví dụ file .vtt với hai cue được định vị khác nhau:
WEBVTT
cue-1
00:00:05.000 --> 00:00:10.000 line:90% position:5% size:90% align:start
Caption at the bottom-left.
cue-2
00:00:12.000 --> 00:00:17.000 line:10% align:center
Title card near the top.
| Cài đặt | Giá trị | Tác dụng |
|---|---|---|
line | Số nguyên (-1, 0, 3) hoặc phần trăm (90%) | Vị trí dọc. Số nguyên: snap theo số dòng từ trên (dương) hoặc từ dưới (âm). Phần trăm: phân số của viewport. Mặc định: tự động (gần đáy). |
position | Phần trăm (5% đến 100%) | Vị trí ngang của cue box. 0% = cạnh trái, 100% = cạnh phải. Mặc định: tự động. |
size | Phần trăm (80%, 50%) | Chiều rộng cue box. Box hẹp hơn sẽ xuống dòng sớm hơn. Mặc định: 100%. |
align | start, center, end, left, right | Căn chỉnh văn bản trong cue box. Mặc định: center. |
vertical | rl hoặc lr | Chiều văn bản dọc cho CJK. Bỏ qua để dùng văn bản ngang thông thường. |
Sự khác biệt quan trọng của line: số nguyên kích hoạt snap-to-lines, trình duyệt đếm theo đơn vị line-height từ cạnh. Phần trăm dùng phân số thô của chiều cao viewport. Tôi thường dùng phần trăm vì kết quả nhất quán trên các kích thước viewport khác nhau.
Làm thế nào để viết STYLE block và ::cue CSS?
Khối STYLE đặt ở đầu file .vtt, trước timestamp của cue đầu tiên. Nó dùng pseudo-element ::cue với CSS thông thường:
WEBVTT
STYLE
::cue {
color: white;
background-color: rgba(0, 0, 0, 0.75);
font-family: Arial, sans-serif;
font-size: 1.1em;
text-shadow: 1px 1px 2px black;
}
STYLE
::cue(b) {
color: #FFD700;
}
STYLE
::cue(v[voice="Narrator"]) {
color: #ADD8E6;
}
00:00:05.000 --> 00:00:10.000
Welcome to this <b>tutorial</b>.
00:00:12.000 --> 00:00:18.000
<v Narrator>The story begins here.</v>
- Từ khóa
STYLExuất hiện riêng trên một dòng, ngay sau đó là CSS, không có dòng trắng ở giữa. - Dòng trắng kết thúc khối. Có thể viết nhiều khối STYLE và chúng được áp dụng theo thứ tự.
- Mọi khối STYLE đặt sau một cue timestamp đều bị bỏ qua. Luôn đặt tất cả style ở đầu file.
::cue(b) nhắm vào thẻ <b> trong payload cue. Bạn cũng có thể dùng ::cue(i), ::cue(c.classname) và ::cue(v[voice="Tên"]) để tô màu theo diễn giả. Với các dự án cần dịch phụ đề sang tiếng Việt hoặc ngôn ngữ khác, tôi dùng cùng định dạng .vtt này và kết nối với quy trình dịch phụ đề.
Những thuộc tính CSS nào hoạt động trong ::cue?
W3C giới hạn tập thuộc tính được phép trong ::cue có chủ ý. Cho phép CSS tùy ý có thể tạo một khối mờ đục che phủ vùng khó đoán của khung hình.
- Được hỗ trợ:
color,backgroundvà tất cảbackground-*,fontvà tất cảfont-*,line-height,opacity,outline,text-decorationvà các longhand,text-shadow,visibility,white-space. - Không hỗ trợ:
margin,padding,border,width,height,display,position,top,left,transform,animation,transition.
Lỗi phổ biến nhất tôi thấy là thêm padding trong ::cue để tạo hộp nền gọn hơn quanh văn bản. Cách này không hoạt động. Giải pháp là thu hẹp cue box bằng cài đặt size, căn giữa bằng position, rồi áp dụng background-color trong ::cue.
Lưu ý thêm: background-color áp dụng cho từng cue box riêng lẻ, không phải một khối chung cho tất cả cue. Đây là thiết kế có chủ đích để tránh hình chữ nhật mờ đơn xuất hiện khi nhiều cue cùng hiển thị. Trang MDN ::cue liệt kê đầy đủ các thuộc tính được hỗ trợ.
Nhúng vào HTML và quy trình tự làm
File .vtt kết nối với phần tử <video> qua thẻ <track>. Dùng kind="captions" cho phụ đề cùng ngôn ngữ (bao gồm mô tả âm thanh cho accessibility) và kind="subtitles" cho track ngôn ngữ dịch:
<video controls src="video.mp4">
<track kind="captions" src="captions.en.vtt" srclang="en" label="English" default />
<track kind="subtitles" src="subtitles.vi.vtt" srclang="vi" label="Tiếng Việt" />
</video>
Thuộc tính srclang nhận thẻ ngôn ngữ BCP 47: en, vi, zh, fr. Thuộc tính default kích hoạt track nếu người xem chưa có tùy chọn lưu. Chỉ một track trên mỗi video nên có default. Lưu ý CORS: file .vtt phải được phục vụ từ cùng origin với trang, hoặc server phải gửi Access-Control-Allow-Origin: *. Kiểm tra với URL file:// thường sẽ thất bại vì lý do này.
Với video web đơn ngôn ngữ và vị trí tiêu chuẩn, tạo file .vtt là tác vụ có thể tự làm: chỉ cần trình soạn thảo văn bản và trình duyệt hiện đại để kiểm tra. Khi nào cần thêm:
- Phân phối đa ngôn ngữ: mỗi ngôn ngữ cần file .vtt riêng. Phụ đề tiếng Việt dịch từ tiếng Anh thường dài hơn, cần ngắt dòng lại để giữ tốc độ đọc thoải mái.
- Yêu cầu nền tảng: Netflix, phát sóng và rạp chiếu ít khi chấp nhận WebVTT. Netflix chỉ định SRT hoặc TTML/IMSC. Khách hàng phát sóng cần SCC cho phụ đề đóng tiếng Anh 608 hoặc SMPTE-TT cho 708.
- SDH: thêm mô tả âm thanh và nhãn diễn giả là quyết định kỹ thuật vượt ra ngoài công việc định dạng.
Nếu bạn cần phụ đề dịch, đa ngôn ngữ hoặc tệp phân phối theo nền tảng, dịch vụ dịch phụ đề chuyên nghiệp xử lý cả định dạng và bản địa hóa cùng lúc.
Câu hỏi thường gặp
Có thể dùng ::cue để thay đổi cỡ chữ phụ đề không?
Có. font-size là thuộc tính được hỗ trợ trong ::cue. Tôi khuyên dùng đơn vị em hoặc rem để cỡ chữ có thể theo tùy chọn của trình duyệt người xem thay vì bị khóa theo giá trị pixel.
Tại sao khối STYLE của tôi không có hiệu lực?
Kiểm tra vị trí của khối trong file. Bất kỳ khối STYLE nào đặt sau timestamp cue đầu tiên đều bị bỏ qua. Di chuyển tất cả khối style lên đầu file, ngay sau dòng header WEBVTT.
::cue có hoạt động trên trình duyệt di động không?
::cue có mặt rộng rãi và được hỗ trợ trong Safari iOS, Chrome Android và Firefox Android trong nhiều năm qua. Selector phức tạp như ::cue(v[voice="..."]) có biến động hỗ trợ rộng hơn, nên hãy kiểm tra trên thiết bị mục tiêu nếu dùng.
Có thể có nhiều hơn một khối STYLE trong file .vtt không?
Có. Nhiều khối STYLE là hợp lệ và được áp dụng cộng dồn. Tôi thường đặt kiểu cue toàn cục trong khối đầu và các quy tắc tô màu diễn giả trong khối thứ hai để dễ đọc.
Netflix có chấp nhận WebVTT làm tệp giao hàng không?
Không phải định dạng chính. Netflix chỉ định SRT hoặc TTML/IMSC tùy ngôn ngữ. Khách hàng phát sóng cần SCC cho phụ đề đóng tiếng Anh 608 hoặc SMPTE-TT cho 708. WebVTT phù hợp cho trình phát web nhưng cần chuyển đổi định dạng khi giao hàng cho nền tảng.
Nguồn
- Đặc tả WebVTT cấp 1 của W3C - cú pháp cài đặt cue, khối STYLE, ::cue và tích hợp <track>. Đã kiểm tra tháng 10/2026.
- MDN WebVTT API Reference - tổng quan định dạng, thẻ cue nội tuyến, tương thích trình duyệt. Đã kiểm tra tháng 10/2026.
- MDN ::cue pseudo-element - danh sách đầy đủ thuộc tính CSS được hỗ trợ và không hỗ trợ trong ::cue. Đã kiểm tra tháng 10/2026.
Written by Dao Huy (Lucas), Vietnamese translator & localization specialist (EN · ZH · FR → Vietnamese). See translation services →
