Screenwriting CSS Snippet - Write in Markdown, Export as a Well-Formatted Screenplay

Copy the Snippet
@import url('https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap');
body {
    --screenplay-font: 'Courier Prime';
}

.screenplay {
    font-family: var(--screenplay-font), 'Courier', var(--font-monospace) !important;
    --h1-font: var(--screenplay-font) !important;
    --h2-font: var(--screenplay-font) !important;
    --h3-font: var(--screenplay-font) !important;
    --h4-font: var(--screenplay-font) !important;
    --h5-font: var(--screenplay-font) !important;
    --h6-font: var(--screenplay-font) !important;
    --file-margins: 1in 1in 1in 1.5in !important;
    --file-line-width: 6.2in !important;
    font-size: 12pt;
    --font-text: var(--screenplay-font);
    line-height: 1.3;
}
.screenplay .markdown-preview-view .cm-line, .screenplay .markdown-source-view .cm-line {
    font-family: var(--screenplay-font) !important;
}



/* scene headings */
.screenplay h1, .screenplay .HyperMD-header-1 {
    font-size: inherit;
    text-transform: uppercase; 
    font-weight: 600;
}

/* character names */
.screenplay h2, .screenplay .HyperMD-header-2 {
    font-size: inherit;
    padding-left: 2.2in !important;
    text-transform: uppercase;
    margin-top: 0.2in;
}

/* dialogue */
.screenplay div:has(h2) + div:has(p),
.screenplay div:has(h3) + div:has(p),
.screenplay .HyperMD-header-2 + .cm-line,
.screenplay .HyperMD-header-3 + .cm-line {
    padding-left: 1.2in !important;
    max-width: 5in !important;
    margin-bottom: 0.2in;
}

/* transitions */
.screenplay h4, .screenplay .HyperMD-header-4 {
    text-align: right;
    font-size: inherit;
    font-weight: 600;
}

/* parentheticals */
.screenplay h3,
.screenplay .HyperMD-header-3 {
    padding-left: 1.5in !important; 
    font-size: inherit;
    font-weight: normal;
}

/* Acts */
.screenplay h5, 
.screenplay .HyperMD-header-5 {
    padding-left: 2.5in !important;
    text-decoration: underline;
}

/* inlint title */
.screenplay .inline-title{
    font-size: 17pt;
    text-align: center !important;
    width: 100% !important;
    font-family: var(--h1-font);
}

/* frontmatter */
.screenplay .frontmatter-container .frontmatter-container-header {
    border-bottom: none;
    color: var(--text-muted);
    padding: 0px;
    text-decoration: underline;
}
.screenplay .frontmatter-container {
    padding: 0px;
    margin: 0px 0px 0px 0px;
    background-color: transparent;
    border: none;
}

.screenplay .frontmatter-section >* {
    flex-wrap: wrap;
    font-size: var(--font-smaller) !important;
}

/* highlights */
.screenplay.markdown-rendered mark,
.cm-highlight {
    background-color: transparent !important;
    text-decoration: underline;
    font-weight: 600;
}

/* links */
a {
    font-family: inherit;
    color: var(--text-normal);
    text-decoration-color: var(--text-accent);
}

/* printing elements */

@media print {
    
/* scene headings */
body {
    font-size: 12pt !important;
    --file-line-width: 8.5in !important;
}

.print .markdown-preview-view {
    max-width: var(--file-line-width);
    margin: auto;
    padding: 0px;
}


h1 {
    font-size: inherit;
    text-transform: uppercase; 
    font-weight: 600;
}


/* character names */
h2 {
    font-size: inherit;
    padding-left: 2.2in !important;
    text-transform: uppercase;
    margin-top: 0.2in;
}

/* dialogue */
h2 + p,
h3 + p {
    padding-left: 1.2in !important;
    max-width: 5in !important;
    margin-bottom: 0.2in;
}

/* transitions */
h4 {
    text-align: right;
    font-size: inherit;
    font-weight: 600;
}

/* parentheticals */
h3  {
    padding-left: 1.5in !important; 
    font-size: inherit;
    font-weight: normal;
}

/* Acts */
h5 {
    padding-left: 2.5in !important;
    text-decoration: underline;
}


/* force page break with hr */
hr {
    break-after:page;
    visibility: hidden;
}

}

/* @settings

name: Screenplay
id: screenplay-settings
settings:
    -
        id: screenplay-font
        title: Font
        type: variable-text
        default: 'Courier New'
*/

If you like to write screenplays in Obsidian, this snippet will solve all of your formatting problems!

Each heading level renders as a different screenplay element, and dialogue is auto-formatted.

  • No codeblocks required. Just the screenplay css class.
  • Quick, easy Markdown. No constant tabs to cycle between elements—just create Markdown headers like you would in any other .md file!
  • Well-formatted PDF Export
  • Accurate line spacing—if you were to write the exact same thing in Celtx or Studiobinder, and you counted the words per action line there and in Obsidian, they’d be exactly the same!

Syntax

Now, before you use the snippet, you should probably be aware of the syntax.

Header 1 - Scene Heading/Shot
Header 2 - Character Name
Header 3 - Parenthetical
Header 4 - Transition
Header 5 - Act
Highlight - Underline
Horizontal Divider (hr) - Page Break

So this right here:

# INT. DAVE'S KITCHEN  - DAY

Dave walks into the kitchen with a yawn. His eyes widen, and his **World's Best Employee** mug shatters on the ground. A SHORT MAN, 20-ish, is standing at the sink, rummaging through a drawer.

## DAVE
OSCAR. IN MY HOUSE, DUDE?

He advances towards the man with a serious expression.

## OSCAR
### (nervously)
Hey, sorry man, I forgot to knock--

Dave picks him up abruptly...and gives him a hug.

## DAVE
DUDE. I missed you.

Oscar frowns in confusion. Slips something shiny into his pocket.

## OSCAR
Yeah, uh...missed you too, bud.

Will be rendered as:

And here’s the PDF export of the Markdown file:

PDF

Here’s the same script in Celtx:

CELTX

As you can see, it’s pretty consistent.

Also, you can change the font with style settings :star:

8 Likes

Also, for clarificaton, the frontmatter has to look like this:

cssClass: screenplay

This may cause incompatibility with the Fountain plug-in, since it also uses .screenplay and different heading levels.

2 Likes

Fantastic work. Thank you very much!

1 Like

That is pure genius. :person_kneeling: :+1: :pray: :performing_arts: :person_raising_hand:

1 Like

This is exactly what I need! I’ve never done anything with the CSS, is there a basic tutorial of how to use this in particular?

1 Like

Just like any snippet, you just put it in (your vault name) \ .obsidian \ snippets. You might have to create the snippets folder yourself if it doesn’t already exist.

Then, you go to settings > appearance in your vault, and you toggle the snippet so that it is on.

Then, when you want to use this screenplay class in a note, you just add the class to the frontmatter, like this:

---
cssclass: screenplay
---

(Rest of note will go here)

This frontmatter has to be at the very top of the note or it won’t work.

Then, boom! Start writing the next cinematic masterpiece!

Also, to add the snippet you can create a .txt file in the snippets folder, open the file and paste the code in, and then change the file extension to .css.

I also made a new version of the snippet here that supports the fountain plugin. You’d have to convert old notes with the screenplay class to md-screenplay, though, because the plugin already uses the class screenplay.