'Can HTML5 subtitles be positioned with css?
I am using a custom HTML5 app for streaming videos on a local network, and now I am adding subtitles support.
I have around 500 .vtt subtitles converted from .srt. After I converted them from .srt, I noticed they display right at the bottom of the screen, and I'd like them to have a little margin-bottom.
I am able to style the subtitles with css pseudo element ::cue, but only for font size, color, background. Doesn't seem to support any margin, padding or positioning rules.
Before coding a script to modify all the .vtt files to add line:XX% to the cues (that's the only way I found so far to move them), I was wondering if there's a way to position the subtitles without having to modify all the .vtt files.
If I disable my custom controls and tried the default controls instead. When a subtitle is displayed and I put the mouse over the video to show the controls, the subtitle do move up, and when the controls get auto hidden after a few seconds that line of subtitles stay at that place. But the next line move back down. This is the reason I am wondering if they can be moved without editing the .vtt files, since showing the controls move them up, maybe there's a way I can do it programmatically.
So the question is, can .vtt subtitles be positioned using CSS or any other method other than modifying the .vtt files?
This is the basic code I am using for testing:
<video controls autoplay>
<source src="http://192.168.0.1/video.mp4" type="video/mp4" />
<track src="http://192.168.0.1/subtitles.vtt" kind="subtitles" srclang="en" label="English" default />
</video>
<style>
video::cue {
font-size:100%;
color:white;
}
</style>
Solution 1:[1]
Solution 2:[2]
This isn't css, but incase new visitors want a solution with JS:
const track = document.getElementsByTagName('track')[0].track;
// Position the cue at the top
track.activeCues[0].line = 0;
// Position the cue at the bottom (default)
track.activeCues[0].line = -1;
// Move the cue up 3 lines to make room for video controls
track.activeCues[0].line = -4;
Solution 3:[3]
you can extract text from individual cues using textTrack.activeCues[0].text and display them in div and set position of div.
Solution 4:[4]
You can give the line-height to the ::cue, but the problem with it is if subtitle goes into multiple lines then the gap between the lines increases.
Solution 5:[5]
The best solution I could think of (in React+Typescript, principle should work anywhere. hacky but works). The main idea is:
- Wait for load event to fire on
trackelement - Get VTT cues of track
- Set line property of each cue
trackRef = (node: HTMLTrackElement) => {
if (node == null) return
node.addEventListener('load', () => {
if (node.track.cues == null) return
Array.from(node.track.cues).forEach((c) => {
(c as VTTCue).line = -4
})
})
}
//...
<video>
<source
src="..."
/>
<track
default
src="..."
ref={this.trackRef}
/>
</video>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Supraja Ganji |
| Solution 2 | internet-nico |
| Solution 3 | sithLords |
| Solution 4 | Supraja Ganji |
| Solution 5 | erik |
