Custom Subtitle Styles
Write your own CSS for video subtitles — blur the translation, dim the original, or restyle the caption box.
The subtitle style page covers font, scale, weight, color and background opacity. Custom CSS is for everything those sliders do not reach: covering the translation with a blur until you actually need it, underlining it, pushing the original into the background, or reshaping the caption box.
It applies to the Read Frog subtitle overlay only. Webpage translation has its own, separate stylesheet — see Custom Translation Styles.
Open the editor
- Open Options → Video Subtitles.
- Open Subtitle style with Customize style.
- Scroll to Custom CSS and open it.
- Write your CSS. The preview above the editor updates as you type.
- Press Save.
Saving reaches players that are already open, so you can keep a video in another tab and watch each save land. Clearing the editor and saving again removes the CSS and hands the subtitles back to the sliders.
Start from a preset template
The Preset template dropdown carries three ready-made blocks. Choosing one appends it to the end of the editor rather than replacing what is already there, so templates stack: blur the translation and dim the original by picking two.
Blur translation
Listen first, and read only when you give up. The blur lifts while the pointer is over the line.
.subtitles-translation {
filter: blur(6px);
transition: filter 0.15s ease;
}
.subtitles-translation:hover {
filter: none;
}Dashed translation
Marks the translation as a helper rather than the main text.
.subtitles-translation {
text-decoration: underline dashed;
text-decoration-thickness: 1px;
text-underline-offset: 0.25em;
}Dim original
Keeps the source line available without letting your eye fall on it first.
.subtitles-main {
opacity: 0.6;
}Selectors you can target
The overlay is deliberately small. Three class names are part of the contract and will not be renamed:
<div class="read-frog-subtitles-box">
<div class="subtitles-main">Mr. Kamiya isn't confronting the world…</div>
<div class="subtitles-translation" lang="zh" dir="ltr">神谷先生…</div>
</div>| Selector | What it matches |
|---|---|
.read-frog-subtitles-box | the box both lines sit in — background, padding, corners, width, alignment |
.subtitles-main | the original caption line |
.subtitles-translation | the translated line |
The translation line carries two extra hooks:
langanddirfollow your target language, so.subtitles-translation[lang='ja']and.subtitles-translation[dir='rtl']both work.data-pending="true"is set while a translation is still on its way back.
.subtitles-translation[data-pending='true'] {
opacity: 0.35;
}The original always comes first in the DOM; Translation position flips the two visually with order. Match on the class names rather than on :first-child.
Working with the style controls
The font, scale, weight and color you pick in the UI reach each line as CSS variables that a stylesheet rule turns into declarations. Your CSS is injected after that rule, so an ordinary declaration wins — !important is not needed:
.subtitles-translation {
color: #ffd479;
font-weight: 600;
}Two exceptions are worth knowing before you spend time on them.
Set the properties, not the --rf-subtitle-* variables
The variables behind those four controls are written inline on each line, and an inline declaration outranks every stylesheet rule. Writing --rf-subtitle-color in custom CSS does nothing:
/* Ignored — the variable is set inline. */
.subtitles-main { --rf-subtitle-color: #7cf; }
/* Works. */
.subtitles-main { color: #7cf; }The box background needs !important
Background opacity is written inline on the box for the same reason, and this is the one place custom CSS has to insist:
.read-frog-subtitles-box {
background-color: rgba(24, 20, 48, 0.85) !important;
border-radius: 10px;
padding: 8px 14px;
}Everything else on the box — padding, corners, width, alignment — takes a plain declaration.
Size in em, not px
The overlay's root font size is derived from the video's height, which is how subtitles stay proportionate when a video goes fullscreen or shrinks into a mini player. 1em on a line means "the size the player would use"; a size in px freezes and stops following the video.
.subtitles-translation {
font-size: 1.15em;
}More recipes
Outline the text and drop the box
Good on bright footage, where a dark plate is more intrusive than the captions themselves.
.read-frog-subtitles-box {
background-color: transparent !important;
}
.subtitles-main,
.subtitles-translation {
text-shadow:
0 0 4px rgba(0, 0, 0, 0.95),
0 1px 3px rgba(0, 0, 0, 0.9);
}Let the translation lead
Shrinks the source line to a reference and gives the translation the weight.
.subtitles-main {
font-size: 0.75em;
opacity: 0.65;
}
.subtitles-translation {
font-size: 1.1em;
font-weight: 600;
}Left-align long lines
Center alignment is hard to read once a caption wraps onto three lines.
.read-frog-subtitles-box {
max-width: 70%;
text-align: left;
}Per-language typography
Useful when you read in more than one target language and want each to look right.
.subtitles-translation[lang='ja'] {
font-family: "Hiragino Mincho ProN", "Yu Mincho", serif;
}
.subtitles-translation[dir='rtl'] {
font-size: 1.05em;
}Scope and limits
The overlay is rendered inside a shadow root in the player. That boundary is what keeps your CSS from leaking onto the page — and it also decides what quietly does nothing:
- Works, and stays inside the overlay:
@keyframes,@media,@supports, transitions, pseudo-classes, and CSS variables you define yourself. - Ignored:
@font-faceand@property. A shadow root cannot register either, so pick fonts already available on the system instead of loading your own. - Matches nothing:
:rootandbody. There is no page-level element inside the overlay — target the three classes above. - Out of reach: the YouTube player's controls, the page behind it, and the native captions. Custom CSS cannot style anything outside the subtitle overlay.
- Size limit: 8 KB. The editor checks syntax as you type and blocks Save while the CSS is invalid or too long.
/* Animations are fine, and stay contained. */
@keyframes rf-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.subtitles-translation {
animation: rf-fade-in 0.2s ease-out;
}Troubleshooting
- Nothing changed after saving: confirm the status line reads CSS is valid and the button reads Saved, then check that the rule targets one of the three class names.
- A background color on the box is ignored: add
!important. The opacity slider writes that property inline. - A
--rf-subtitle-*override is ignored: setcolor,font-size,font-familyorfont-weightdirectly instead. - Text size jumps when going fullscreen: switch that
font-sizefrompxtoem. - A font never applies:
@font-facedoes not work inside the overlay; use a font installed on the system. - Save is disabled: the editor found a syntax error, or the stylesheet is over 8 KB.
- The overlay looks broken: empty the editor and save. The CSS is removed immediately and the style controls take over again.
Custom CSS is stored with the rest of your settings, so it travels with a configuration export — see Configuration, Sync & Backups. For everything else about the overlay, see Video Subtitles.
