Overview
Learn how to customize an existing theme or design a new one by leveraging the power of CSS.
Important Notes:
- Theming is only available in the Coffee Version. While you can still follow along even if you are on the Online Version, your theme will be automatically switched back to one of the free themes when you are done.
- Theming is an advanced feature. Before beginning this guide, you should have a good understanding of Cascading Style Sheets (CSS) .
Welcome to the Theming Guide! This guide covers the following topics:
- The HTML structure of each verse
- CSS class reference
- Browser Source CSS
- Essential theme CSS
- Font size
- Recreating the default theme
- Questions you may have
By the end of this guide, you will hopefully know enough to create or customize your own themes!
HTML Structure
<div class="bible">
<div class="bible__reference">
<p class="bible__reference-text"></p>
<p class="bible__reference-version"></p>
</div>
<div class="bible__passage">
<p class="bible__passage-text">
<span class="bible__passage-text-span"></span>
</p>
</div>
</div>
<div class="bible">
<div class="bible__reference">
<p class="bible__reference-text">John 3:16</p>
<p class="bible__reference-version">KJV</p>
</div>
<div class="bible__passage">
<p class="bible__passage-text">
<span class="bible__passage-text-span">For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</span>
</p>
</div>
</div>
<div class="bible bible--visible">
<div class="bible__reference">
<p class="bible__reference-text">John 3:16</p>
<p class="bible__reference-version">KJV</p>
</div>
<div class="bible__passage">
<p class="bible__passage-text">
<span class="bible__passage-text-span">For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</span>
</p>
</div>
</div>
<div class="bible bible--visible bible--full-height">
<div class="bible__reference">
<p class="bible__reference-text">John 3:16</p>
<p class="bible__reference-version">KJV</p>
</div>
<div class="bible__passage">
<p class="bible__passage-text">
<span class="bible__passage-text-span">For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</span>
</p>
</div>
</div>
CSS Class Reference
Class | Description |
---|---|
.bible | Root element. Invisible by default. |
.bible--visible | Root element modifier. The verse should be visible. Applied when the user clicks a verse to be displayed. Removed when the user deselects the verse or switches to another one. |
.bible--full-height | Root element modifier. The verse should expand to fill all available height. Applied when the user selects the "Standard" display height option. Removed when the user uses any other display height option. |
.bible__reference | Container for the Bible reference. |
.bible__reference-text | Bible verse reference (e.g., "John 3:16"). |
.bible__reference-version | Abbreviation of the Bible translation (e.g., "KJV"). |
.bible__passage | Container for the Bible verse text. |
.bible__passage-text-span | Bible verse text. |
Browser Source CSS
Before any theme is applied, the Browser Source loads some CSS. Generally speaking, this CSS is not something you have to worry about. However, there are some points to be mindful of before beginning, as some of these will have a cascading effect on your theme.
- The
#root
element, which in the HTML DOM is the parent of the.bible
element, takes up all space. - Overflow is set to hidden.
- Border-box box-sizing is the default.
- Margins on the
body
and#root
are set to zero. - Scrollbars are invisible.
If you're curious, the entire CSS is shown here. Keep in mind that some of it is only used internally.
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#root {
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
width: 100vw;
height: 100vh;
max-height: 100vh;
margin: 0;
margin-top: auto;
}
#invisible-bible {
visibility: hidden;
position: absolute;
}
::-webkit-scrollbar {
display: none;
}
Essential CSS
When you create a new theme by copying an existing one, you will notice that at the top of each file some CSS is applied by default. Here is the essential CSS.
/* Essential CSS */
/*-----------------------------------*/
:root {
font-size: calc(var(--base-font-size, 1rem) * var(--obs-font-scale, 1));
}
.bible {
display: flex;
opacity: 0;
max-height: 100%;
overflow: hidden;
}
.bible--visible {
opacity: 1;
}
.bible__passage {
overflow-y: scroll;
}
.bible__reference {
display: flex;
}
.bible--full-height {
min-height: 100%;
}
.bible--full-height .bible__passage {
flex: 1;
}
/* End of Essential CSS */
/*------------------------------------*/
Unless you have a good reason, we do not recommend overwriting most of these properties in order to avoid breaking any functionality. The only one you may want to replace is the opacity
property (you could use a CSS transform
instead, as long as you set the right invisible and visible values). However, the option is there if you are sure.
You be wondering what the whole font-size
thing in :root
is about. Please refer to the Font Size section of this guide for further details.
Font Size
Generally speaking, your fonts should be relatively big compared to a typical web page. A base font size of around 24px (1.5rem)
to 32px (2rem)
(depending on the font) should yield good results.
To set a base font size, you may think of doing something like this:
:root { font-size: 32px; } /* Don't do this! */
However, do not do this! This will stop font scaling from working properly. Instead, do this:
:root { --base-font-size: 32px; }
If you refer to the essential CSS section, you will note that there already is a font-size
property declared.
:root {
font-size: calc(var(--base-font-size, 1rem) * var(--obs-font-scale, 1));
}
It is calculated based on two CSS custom properties:
--base-font-size
This is the property you should set in the:root
. Setting it here means font scaling will continue to work. You can ignore this CSS property entirely if you do not intend to set thefont-size
property on the:root
.--obs-font-scale
This property is adjusted by the user whenever he or she changes the Font Scale in Settings. It is a floating-point number that defaults to 1.0. The base font size is multipled by this number to achieve scaling.
Recreating the Default Theme
Let's say you plan to make a theme that looks something like the default dark theme:
Excluding the essential CSS, here is the full theme style:
.bible {
flex-direction: column;
margin-top: auto;
background-color: rgba(0, 0, 0, 0.5);
padding: 8px;
transition: opacity 500ms ease;
}
.bible__reference,
.bible__passage-text {
text-align: center;
font-size: 2.5em;
font-family: serif;
color: white;
margin: 0.5em;
}
.bible__passage-text {
margin-top: 0;
}
.bible__reference {
justify-content: center;
align-items: center;
white-space: pre-wrap;
}
.bible__reference-version {
font-size: 0.8em;
margin: 0;
}
.bible__reference-version:before {
content: " (";
}
.bible__reference-version:after {
content: ")";
}
.bible__reference-text {
font-weight: bold;
margin: 0;
}
There are a few things to note:
- The version, reference text, and passage text have different text styles (some are bold, some are smaller, etc.). It is easy to style each one individually by targeting their CSS classes or their container elements, like
.bible__reference
,.bible__passage-text
,.bible__reference-version
, etc. From there, you can apply CSS properties likefont-style
,font-weight
,font-size
, and so on. - The theme is laid out in a column, except for the Bible reference, which is laid out in a row. For this theme, we used CSS Flex and its properties to adjust alignment and position. In the end, the root element
.bible
is set toflex-direction: column;
while.bible__reference
is left at the defaultrow
. - The theme is slightly transparent. You can make any theme transparent by adding an alpha value to the background color of the
.bible
element. For this theme,background-color: rgba(0, 0, 0, 0.5);
- The reference version ("KJV") is surrounded by parentheses. You can easily do this by making use of the CSS
::before
and::after
pseudo-elements on the.bible__reference-version
property. If you add a space before the first parentheses like in the theme, remember to setwhite-space: pre-wrap;
(or another similarwhite-space
property) on the.bible__reference
selector so that the space is not collapsed. - The verse smoothly fades in and out when it is shown/hidden. In the essential CSS, the
.bible
is set toopacity: 0;
and.bible--visible
is set toopacity: 1;
. This theme transitions between them by addingtransition: opacity 500ms ease;
to the.bible
selector. You don't have to just transition onopacity
. Some of the other included themes use CSS transforms like translates instead! Feel free to experiment. - The theme is aligned at the bottom. The
.bible
selector is set tomargin-top: auto;
This fits lower-thirds use cases, but you can always align at the top instead by usingmargin-bottom: auto;
- The theme does not specify a font size for the
:root
element (see the font size section above). You can set the font sizes individually for each element instead. Font scaling will still work as intended as long as you use relative font size units for text (em
,rem
, etc.).
FAQ
What CSS can I use?
OBS Studio uses the Chromium Embedded Framework (CEF) for its web-related work. This means you can use relatively recent CSS features, as well as Chromium-specific CSS. (In fact, we used the non-standard ::webkit-scrollbar
property to hide scrollbars!) The exact version of CEF that OBS Studio uses depends on the OBS Studio version you have, as well as which platform you are running OBS Studio on. Please refer to this OBS Studio GitHub page to know which Chromium version you should target when writing your CSS.
How do I use Google Fonts in my themes?
You can do so in the theme editor. Please refer to this part of the manual for details. Afterwards just set font-family
in your CSS like normal.
Why is there a span in the Bible passage text element?
This element is used internally for calculating the number of lines. However, it is also available for styling if you want!