Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Obsidian scss

Obsidian SASS theme switching tools

I was building up a small library of css snippets, and mixing and matching via copy-paste was getting tiresome.
So, I knocked myself up a little solution using https://sass-lang.com/
To use this solution, you need to follow the instructions on the website to install the SASS command line utility.

Instructions

For my purposes, I created a subfolder in my Obsidian vault called ./.themes where my obsidian.scss file lives. I also created a subfolder for mixins (./.themes/mixins) containing small snippets like "Andy Matuschak" mode and collapsing sidebars (and my preferred custom colours for my Base2Tone theme)

For themes I want to switch between which have git repositories, I check them out into the .themes folder, and can reference them from my obsidian.scss with the @add directive, alongside @adding any of the mixin tweaks I want (I've included an example of my obsidian.scss below)

Once I'm happy with the theme and mixins I want, I run the following command from the root of my obsidian vault: sass .\.themes\obsidian.scss .\obsidian.css
This will compile the obsidian.css file and place it in my vault. A few moments later, Obsidian is looking different!

Bonus: Syntax highlighting themes

The syntax highlighting uses Prism.js and there are plenty of themes available.
Obsidian does wrap them in .theme-dark or .theme-light classes though, so you can't just drop in a theme and expect it to work.

This is exactly the kind of thing SASS is good at. Just wrap the whole theme in a .theme-dark { or .theme-light { block, and SASS will generate the appropriate css.
I've included the theme I'm using (originally from here) as an example.

/* .themes/mixins/_andy-matuschak.css */
/* Andy Matuschak mode! */
.workspace-split.mod-vertical { overflow-x:auto; }
.workspace-leaf, .workspace-split > .workspace-split { min-width: 500px; min-height: 500px; }
.workspace-split.mod-horizontal { overflow-y: auto; }
/* .themes/mixins/_Base2Tone-sfs.css */
:root {
/* change these hues for an entirely new look */
--uno: 231;
--duo: 9;
/* this is a hack workaround for now */
/* go to https://convertacolor.com/ to convert the --baseD0 hsl to rgb */
/* i.e. hsl(--duo, 58%, 55%) */
--D0-rgb: 207,94,74;
}
/* .themes/mixins/_collapsing-sidebars.css */
/* Collapsing sidedocks, courtesy of kmaasrud#1732 (https://github.com/kmaasrud/clean-theme-obsidian) */
.app-container.is-left-sidedock-collapsed .side-dock.mod-left:not(:hover), .app-container.is-right-sidedock-collapsed .side-dock.mod-right:not(:hover) {
width: 5px !important; /* 5px so there's still something to hover on if not fullscreen */
}
/* .themes/mixins/_font-mixins.scss */
@mixin preview($font) {
.cm-s-obsidian, .markdown-preview-view{
font-family: $font;
}
}
@mixin editor($font) {
.markdown-source-view,
.cm-s-obsidian .cm-url {
font-family: $font;
}
@include operators($font);
}
@mixin operators($font) {
.cm-s-obsidian .hmd-fold-html-stub,
.cm-s-obsidian .hmd-fold-code-stub,
.cm-s-obsidian.CodeMirror .HyperMD-hover > .HyperMD-hover-content code,
.cm-s-obsidian .cm-formatting-hashtag,
.cm-s-obsidian .cm-inline-code,
.cm-s-obsidian .HyperMD-codeblock,
.cm-s-obsidian .cm-formatting-task,
.cm-s-obsidian .cm-hmd-indent-in-quote,
.cm-s-obsidian .HyperMD-hr,
.cm-s-obsidian .cm-hmd-frontmatter,
.cm-s-obsidian .cm-hmd-orgmode-markup,
.cm-s-obsidian .cm-formatting-em,
.cm-s-obsidian .cm-formatting-strong,
.cm-s-obsidian .cm-formatting-strikethrough,
.cm-s-obsidian .cm-formatting-code,
.cm-s-obsidian .cm-formatting-link,
.cm-s-obsidian .cm-formatting-image,
.cm-s-obsidian .cm-math,
.cm-s-obsidian span.hmd-fold-math-placeholder,
.cm-s-obsidian .CodeMirror-linewidget kbd,
.cm-s-obsidian .hmd-fold-html kbd {
font-family: $font;
}
}
@mixin urls($font) {
.cm-s-obsidian .cm-url {
font-family: $font;
}
}
@mixin code($font) {
body {
--font-monospace: $font;
}
}
/* .themes/obsidian.scss */
/* Stuff I'm using right now */
@use 'Base2Tone-For-Obsidian.md/obsidian.css'; // the theme I'm using
@use 'mixins/Base2Tone-sfs'; // my cutom 2tone colours
@use 'mixins/andy-matuschak'; // Andy Matuschak mode
@use 'mixins/collapsing-sidebars'; // collapsible sidebars
@use 'mixins/font-mixins' as fonts; // some helper mixins I made for fonts
@use 'prism-vdc-dark-plus'; // a prism theme I found for changing the syntax highlighting theme
// These are the fonts I prefer (overrides anything defined in the theme above)
body {
--font-editor: 'Inter', sans-serif;
--font-preview: 'Inter', sans-serif;
--font-monospace: 'Fira Code', monospace; // for code blocks
}
// run the mixins to change the fonts
@include fonts.preview(var(--font-preview));
@include fonts.editor(var(--font-editor));
/* These are some of the themes I have checked out
* I'll comment out the code above and uncomment the one I want to use
*/
// 'Ursa' (Bear) theme by @ezs
// @use 'obsidian-ursa/obsidian.css';
// Roam theme by me
// @use 'Obsidian-Roam-theme/obsidian.css';
// 80's Neon theme by me
//@use '80s-Neon-for-Obsidian.md/obsidian.css';
/* .themes/prism-vdc-dark-plus.scss */
.theme-dark {
pre[class*="language-"],
code[class*="language-"] {
color: #d4d4d4;
font-size: 13px;
text-shadow: none;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::selection,
code[class*="language-"]::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
pre[class*="language-"],
code[class*="language-"] {
text-shadow: none;
}
}
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
background: #1e1e1e;
}
:not(pre) > code[class*="language-"] {
padding: .1em .3em;
border-radius: .3em;
color: #db4c69;
background: #f9f2f4;
}
/*********************************************************
* Tokens
*/
.namespace {
opacity: .7;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #6a9955;
}
.token.punctuation {
color: #d4d4d4;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #b5cea8;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #ce9178;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #d4d4d4;
background: #1e1e1e;
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #c586c0;
}
.token.function {
color: #dcdcaa;
}
.token.regex,
.token.important,
.token.variable {
color: #d16969;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.constant {
color: #9CDCFE;
}
.token.class-name {
color: #4EC9B0;
}
.token.parameter {
color: #9CDCFE;
}
.token.interpolation {
color: #9CDCFE;
}
.token.punctuation.interpolation-punctuation {
color: #569cd6;
}
.token.boolean {
color: #569cd6;
}
.token.property {
color: #9cdcfe;
}
.token.selector {
color: #d7ba7d;
}
.token.tag {
color: #569cd6;
}
.token.attr-name {
color: #9cdcfe;
}
.token.attr-value {
color: #ce9178;
}
.token.entity {
color: #4ec9b0;
cursor: unset;
}
.token.namespace {
color: #4ec9b0;
}
/*********************************************************
* Language Specific
*/
pre[class*="language-javascript"],
code[class*="language-javascript"] {
color: #4ec9b0;
}
pre[class*="language-css"],
code[class*="language-css"] {
color: #CE9178;
}
pre[class*="language-html"],
code[class*="language-html"] {
color: #d4d4d4;
}
.language-html .token.punctuation {
color: #808080;
}
/*********************************************************
* Line highlighting
*/
pre[data-line] {
position: relative;
}
pre[class*="language-"] > code[class*="language-"] {
position: relative;
z-index: 1;
}
.line-highlight {
position: absolute;
left: 0;
right: 0;
padding: inherit 0;
margin-top: 1em;
background: #f7ebc6;
box-shadow: inset 5px 0 0 #f7d87c;
z-index: 0;
pointer-events: none;
line-height: inherit;
white-space: pre;
}
}
@mrkuramoto

This comment has been minimized.

Copy link

@mrkuramoto mrkuramoto commented Jan 29, 2021

Thank you for sharing your knowledge about CSS - it is not easy to get information about it and count on contributors like you is it very nice. I don't want to bother you but I will take my chance and make a question: do you know how to add extra spaces between blocks in preview mode? I had success in the edit mode but never in preview mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment