Skip to main content
Obsidian

Obsidian #

I use Obsidian with macOS 10.15 Catalina, iOS 16, and iPadOS 15.

Admin #

Sync between devices #

Do not use iCloud WITH git. Pick one.

Working with multiple vaults #

Set a different accent colour for each vault for a more obvious visual reminder.

Plugins (for peaceful writing) #

Show Whitespace #

Repo: deathau/cm-show-whitespace-obsidian

Reference: Core styles of this plugin, obtained from inspection

Source: deathau/cm-show-whitespace-obsidian/styles.scss

body.plugin-cm-show-whitespace .cm-whitespace::before,
body.plugin-cm-show-whitespace .cm-tab::before,
body.plugin-cm-show-whitespace .CodeMirror-code > div > pre > span > :last-child:after,
body.plugin-cm-show-whitespace .CodeMirror-line > span > :last-child::after,
body.plugin-cm-show-whitespace [class*=cm-trailing-space] + [class*=cm-trailing-space]:last-child::after {
    pointer-events: none;
    color: var(--text-faint);
    font-weight: normal;
    opacity: 0.5;
}

body.plugin-cm-show-whitespace {
    --spaceChar: "·";
    --trailingSpaceChar: "·";
    --singleSpaceChar: var(--spaceChar);
    --tabChar: "→";
    --newlineChar: "¬";
    --strictLineBreakChar: var(--newlineChar);
}

body.plugin-cm-show-whitespace.plugin-cm-show-whitespace-show-strict-line-break {
    --strictLineBreakChar: "↲";
}

Because this plugin has been unmaintained for a while, a patch is needed to make everything look consistent. Add a CSS file with the following contents: (the <br> style came from here)

body.plugin-cm-show-whitespace [class*=cm-trailing-space]::after,
body.plugin-cm-show-whitespace [class*=cm-trailing-space]::before {
  /* sometimes one of these doesn't work depending on the theme: */
  /* color: var(--text-faint); */
  color: var(--text-muted);
}

.markdown-source-view br {
  content: "&nbsp;";
  display: block !important;
}

.markdown-source-view br::after {
  content: var(--newlineChar);
  white-space: pre;
  pointer-events: none;
  color: var(--text-muted);
  font-weight: normal;
  opacity: 0.5;
}

Control Characters #

Repo: joethei/obsidian-control-characters

When I was looking for an alternative of cm-show-whitespace-obsidian, I found this plugin which also integrates with mgmeyers/obsidian-style-settings to make customising possible without fiddling with CSS files. However, I did not like the default SVGs, and could not bother with finding new SVGs right now, so I am still using the old plugin.

Hider #

Repo: kepano/obsidian-hider

Hide ribbon, vault name, file explorer icons when in writing mode.

Hover Editor #

Repo: nothingislost/obsidian-hover-editor

Need to turn on the core Page Preview plugin first, or force reload.

Together with ![[]] embed, and setting hotkeys option+ and option+ for swap lines (credit: @seviche@kongwoo.icu) makes an ok block-editing environment1.

Quiet Outline #

Repo: guopenghui/obsidian-quiet-outline

Use Command palette ▸ Quiet Outline: Quiet Outline to activate.

Turning on dragging titles to rearrange document for a pseudo block editing experience.

Some styles I wrote for more obvious current entry highlighting:

/* **** all entries **** */
.n-tree .n-tree-node {
  --n-node-text-color: var(--nav-item-color);
  transition: none;
  font-size: var(--nav-item-size);
  border-radius: var(--radius-s);
}

.quiet-outline .n-tree-node .n-tree-node-content {
  margin-bottom: var(--size-2-1);
  padding: var(--nav-item-padding);
  padding-left: 0;
  line-height: var(--line-height-tight);
}

/* **** cursor-focused entries **** */
.n-tree.n-tree--block-line .n-tree-node:not(.n-tree-node--disabled).n-tree-node--selected {
  /* accent highlight */
  background-color: var(--interactive-accent) !important;
  /* muted highlight */
  /* background-color: var(--nav-item-background-hover) !important; */
}
.n-tree .n-tree-node--selected .n-tree-node-content .n-tree-node-content__text {
  color: var(--text-on-accent) !important;
  font-weight: normal !important;
}

/* **** scrolled-to entries **** */
.n-tree .n-tree-node.located {
  background-color: var(--nav-item-background-hover) !important;

  font-weight: normal !important;
}

/* **** hovered entries **** */
.quiet-outline .n-tree.n-tree--block-line .n-tree-node:not(.n-tree-node--disabled):hover {
  background-color: var(--nav-item-background-hover);
}

/* **** expand switcher **** */
.n-tree .n-tree-node-switcher {
  height: unset;
}

Stille #

Repo: michaellee/stille

Click the moon icon in the Ribbon, or use Command palette ▸ Stille: Toggle Stille to activate.

Plugins (for aggressive note-taking) #

TBE.

Themes #

iA Writer #

Repo: mrowa44/obsidian-ia-writer

The recommended artisticat1/focus-active-sentence plugin blinks when scrolling the page, which I found distracting. Instead, I tried michaellee/stille which turned out to be great.

Unfortunately, the very appealing artisticat1/nl-syntax-highlighting only supports English, which is not my primary writing language in Obsidian.

The file tree is very buggy on my setup.

iB Writer #

Repo: whereiswhere/iB-Writer

Less buggy than iA Writer, but does not respect the accent colour setting.

Some tiny fixes to this theme that I wrote:

* {
  /* iB: hsl(195, ..., ...) */
  --indicator-color: #4480EF;
  --my-accent-color: #D4E2FC;
  --my-accent-color-render: #D4E2FC;
  /* hsl(219, 84%, 85%) #B9CFF9 */
  /* hsl(219, 87%, 91%) #D4E2FC */
}

/* recover setting font size */
.markdown-source-view {
  font-size: unset;
}

body:not(.is-grabbing) .nav-file-title.is-active:hover,
body:not(.is-grabbing) .nav-folder-title.is-active:hover,
.nav-file-title.is-active, .nav-folder-title.is-active {
  color: var(--text-on-accent);
}

.cm-s-obsidian span.cm-hmd-internal-link:hover {
  color: var(--indicator-color, var(--interactive-accent));
}

Minimal #

Repo: kepano/obsidian-minimal

Changed a lot of CSS classes (maybe for good but very confusing when writing snippets). It did not made a huge difference to me compared to default theme with Hider, so in the end I went back to that.

Some styles I wrote to make the right sidebar to have the same background colour as the left sidebar:

.workspace-split.mod-right-split .workspace-tabs {
    --tab-container-background: var(--bg2) !important;
    --background-secondary: var(--bg2) !important;
    --titlebar-background-focused: var(--bg2) !important;
}

.sidebar-toggle-button.mod-right {
    background-color: var(--bg2) !important;
}

General CSS nippets #

  • Style for text-decoration will not apply in selection layer.
  • ::selection does not work for some reason.

Thicker cursor (kind of) #

Nothing really worked. I also tried Ninja cursor, no luck with Obsidian 1.3.7.

The characters are not typos!

Reference: Core styles of the default cursors, obtained from inspection
.ͼ1.cm-focused {
  outline: 1px dotted #212121;
}

.ͼ1 {
  position: relative !important;
  box-sizing: border-box;
  display: flex !important;
  flex-direction: column;
}

.ͼ1 .cm-scroller {
  display: flex !important;
  align-items: flex-start !important;
  font-family: monospace;
  line-height: 1.4;
  height: 100%;
  overflow-x: auto;
  position: relative;
  z-index: 0;
}

.ͼ1 .cm-content[contenteditable=true] {
  -webkit-user-modify: read-write-plaintext-only;
}

.ͼ1 .cm-content {
  margin: 0;
  flex-grow: 2;
  flex-shrink: 0;
  display: block;
  white-space: pre;
  word-wrap: normal;
  box-sizing: border-box;
  padding: 4px 0;
  outline: none;
}

.ͼ1 .cm-lineWrapping {
  white-space: pre-wrap;
  white-space: break-spaces;
  word-break: break-word;
  overflow-wrap: anywhere;
  flex-shrink: 1;
}

.ͼ2 .cm-content {
  caret-color: black;
}

.ͼ3 .cm-content {
  caret-color: white;
}

.ͼ1 .cm-line {
  display: block;
  padding: 0 2px 0 6px;
}

.ͼ1 .cm-layer>* {
  position: absolute;
}

.ͼ1 .cm-layer {
  position: absolute;
  left: 0;
  top: 0;
  contain: size style;
}

.ͼ2 .cm-selectionBackground {
  background: #d9d9d9;
}

.ͼ3 .cm-selectionBackground {
  background: #222;
}

.ͼ2.cm-focused>.cm-scroller>.cm-selectionLayer .cm-selectionBackground {
  background: #d7d4f0;
}

.ͼ3.cm-focused>.cm-scroller>.cm-selectionLayer .cm-selectionBackground {
  background: #233;
}

.ͼ1 .cm-cursorLayer {
  pointer-events: none;
}

.ͼ1.cm-focused>.cm-scroller>.cm-cursorLayer {
  animation: steps(1) cm-blink 1.2s infinite;
}

@keyframes cm-blink {
  50% {
    opacity: 0;
  }
}

@keyframes cm-blink2 {
  50% {
    opacity: 0;
  }
}

.ͼ1 .cm-cursor,
.ͼ1 .cm-dropCursor {
  border-left: 1.2px solid black;
  margin-left: -0.6px;
  pointer-events: none;
}

.ͼ1 .cm-cursor {
  display: none;
}

.ͼ3 .cm-cursor {
  border-left-color: #444;
}

.ͼ1 .cm-dropCursor {
  position: absolute;
}

.ͼ1.cm-focused>.cm-scroller>.cm-cursorLayer .cm-cursor {
  display: block;
}

.ͼ2 .cm-activeLine {
  background-color: #cceeff44;
}

.ͼ3 .cm-activeLine {
  background-color: #99eeff33;
}

.ͼ2 .cm-specialChar {
  color: red;
}

.ͼ3 .cm-specialChar {
  color: #f78;
}

.ͼ1 .cm-gutters {
  flex-shrink: 0;
  display: flex;
  height: 100%;
  box-sizing: border-box;
  left: 0;
  z-index: 200;
}

.ͼ2 .cm-gutters {
  background-color: #f5f5f5;
  color: #6c6c6c;
  border-right: 1px solid #ddd;
}

.ͼ3 .cm-gutters {
  background-color: #333338;
  color: #ccc;
}

.ͼ1 .cm-gutter {
  display: flex !important;
  flex-direction: column;
  flex-shrink: 0;
  box-sizing: border-box;
  min-height: 100%;
  overflow: hidden;
}

.ͼ1 .cm-gutterElement {
  box-sizing: border-box;
}

.ͼ1 .cm-lineNumbers .cm-gutterElement {
  padding: 0 3px 0 5px;
  min-width: 20px;
  text-align: right;
  white-space: nowrap;
}

.ͼ2 .cm-activeLineGutter {
  background-color: #e2f2ff;
}

.ͼ3 .cm-activeLineGutter {
  background-color: #222227;
}

.ͼ1 .cm-panels {
  box-sizing: border-box;
  position: sticky;
  left: 0;
  right: 0;
}

.ͼ2 .cm-panels {
  background-color: #f5f5f5;
  color: black;
}

.ͼ2 .cm-panels-top {
  border-bottom: 1px solid #ddd;
}

.ͼ2 .cm-panels-bottom {
  border-top: 1px solid #ddd;
}

.ͼ3 .cm-panels {
  background-color: #333338;
  color: white;
}

.ͼ1 .cm-tab {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}

.ͼ1 .cm-widgetBuffer {
  vertical-align: text-top;
  height: 1em;
  width: 0;
  display: inline;
}

.ͼ1 .cm-placeholder {
  color: #888;
  display: inline-block;
  vertical-align: top;
}

.ͼ1 .cm-highlightSpace:before {
  content: attr(data-display);
  position: absolute;
  pointer-events: none;
  color: #888;
}

.ͼ1 .cm-highlightTab {
  background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="20"><path stroke="%23888" stroke-width="1" fill="none" d="M1 10H196L190 5M190 15L196 10M197 4L197 16"/></svg>');
  background-size: auto 100%;
  background-position: right 90%;
  background-repeat: no-repeat;
}

.ͼ1 .cm-trailingSpace {
  background-color: #ff332255;
}

.ͼ1 .cm-button {
  vertical-align: middle;
  color: inherit;
  font-size: 70%;
  padding: .2em 1em;
  border-radius: 1px;
}

.ͼ2 .cm-button:active {
  background-image: linear-gradient(#b4b4b4, #d0d3d6);
}

.ͼ2 .cm-button {
  background-image: linear-gradient(#eff1f5, #d9d9df);
  border: 1px solid #888;
}

.ͼ3 .cm-button:active {
  background-image: linear-gradient(#111, #333);
}

.ͼ3 .cm-button {
  background-image: linear-gradient(#393939, #111);
  border: 1px solid #888;
}

.ͼ1 .cm-textfield {
  vertical-align: middle;
  color: inherit;
  font-size: 70%;
  border: 1px solid silver;
  padding: .2em .5em;
}

.ͼ2 .cm-textfield {
  background-color: white;
}

.ͼ3 .cm-textfield {
  border: 1px solid #555;
  background-color: inherit;
}

.ͼp .cm-vimMode .cm-cursorLayer:not(.cm-vimCursorLayer) {
  display: none;
}

.ͼp .cm-vim-panel {
  padding: 0px 10px;
  font-family: monospace;
  min-height: 1.3em;
}

.ͼp .cm-vim-panel input {
  border: none;
  outline: none;
}

.ͼo .cm-vimMode .cm-line {
  caret-color: transparent !important;
}

.ͼo .cm-fat-cursor {
  position: absolute;
  border: none;
  white-space: pre;
}

.ͼo.cm-focused .cm-fat-cursor {
  background: var(--interactive-accent);
  color: var(--text-on-accent);
}

.ͼo:not(.cm-focused) .cm-fat-cursor {
  outline: solid 1px #ff9696;
  color: transparent !important;
}

There are two types of cursors, .cm-cursor (end-border of selection) and .cm-dropCursor (caret when user is typing). The following style only works on the former, using accent colour from iB theme, with default accent as fallback.

/* disable animation for cm-cursor */
.ͼ1.cm-focused>.cm-scroller>.cm-cursorLayer {
  animation: none !important;
}

/* colour and width for cm-cursor */
/* dropCursor does not work for some reason */
/* mimics fat-cursor */
/* better than border-left method for more consistent sizes */
/* colour: iB theme, with default theme as fallback  */
.ͼ1 .cm-cursor,
.ͼ1 .cm-dropCursor {
  visibility: visible !important;
  display: block;
  position: absolute;
  border: none;
  white-space: pre;
  outline: 1px solid var(--indicator-color, var(--interactive-accent));
  color: transparent !important;
  margin-left: 0.5px;
}

/* colour for cm-dropCursor */
.markdown-source-view.mod-cm6 .cm-content {
  caret-color: var(--indicator-color, var(--interactive-accent));
}

iA Writer CSS for default theme #

First 29 lines of mrowa44/obsidian-ia-writer/theme.css (Base64 encoded iA Writer Duo font, too large to include here), plus:

body {
  --h1-size: var(--font-text-size);
  --h2-size: var(--font-text-size);
  --h3-size: var(--font-text-size);
  --h4-size: var(--font-text-size);
  --h5-size: var(--font-text-size);
  --h6-size: var(--font-text-size);
  --vault-name-font-weight: 600;

  --file-line-width: min(800px, 98vw);
  --file-margins: 64px 32px 32px 32px;

  --h1-color: var(--text-normal);
  --link-color: var(--text-normal);
  --text-faint: var(--text-muted);
  --callout-title-color: var(--text-normal);
  --link-unresolved-color: var(--text-normal);
  --link-external-color: var(--text-normal);
  --link-external-color-hover: var(--color-accent);
  --checkbox-color: var(--text-muted);
  --checkbox-border-color: var(--text-muted);
  --list-marker-color: var(--text-muted);
  --tab-text-color: var(--text-normal);
  --tab-text-color-focused: var(--text-normal);
  --tab-text-color-focused-active: var(--text-normal);
  --tab-text-color-active: var(--text-normal);
  --nav-item-color: var(--text-normal);
  --link-unresolved-opacity: 1;
  --list-marker-color: var(--text-normal);
  --titlebar-background-focused: var(--background-secondary);
}

.theme-light,
.theme-dark {
  --font-text: "iA Writer Duo", var(--font-text-override), "iA Writer Duo", var(--font-interface);
  --line-height-normal: 1.7;
  --link-decoration: underline;
  --link-unresolved-decoration-color: var(--text-muted);
  --link-external-decoration-color: var(--text-muted);
  --checklist-done-decoration: line-through;
  --checkbox-color: transparent;
  --checkbox-color-hover: transparent;
  --checkbox-marker-color: transparent;
}

.theme-light {
  --background-primary: #F7F7F7;
  --background-secondary: #FCFCFC;
  --text-normal: #1A1A1A;
  --text-muted: #B5B3B1;
  --text-highlight-bg: #FCEA95;
  --text-highlight-border: 4px solid #FFD700;
  --text-highlight-color: var(--text-normal);
}

.theme-dark {
  --background-primary: #1B1B1B;
  --background-secondary: #141414;
  --text-normal: #CCC;
  --text-muted: #707070;
  --text-highlight-bg: #494113;
  --text-highlight-border: 4px solid #D4B000;
  --text-highlight-color: #DCCF99;
}

/* nav file tree */
body:not(.is-grabbing) .nav-file-title.is-active:hover,
body:not(.is-grabbing) .nav-folder-title.is-active:hover,
.nav-file-title.is-active, .nav-folder-title.is-active {
  background: var(--color-accent);
  color: var(--text-on-accent);
}

/* underline */
.markdown-source-view.mod-cm6 .is-unresolved .cm-underline,
.markdown-source-view.mod-cm6 .cm-underline,
.cm-underline,
/* internal links */
.cm-s-obsidian span.cm-hmd-internal-link,
/* external links */
.cm-s-obsidian span.cm-url {
  text-decoration: underline;
  text-decoration-color: var(--text-muted);
  text-underline-offset: 3px;
}
/* external links */
.cm-s-obsidian span.cm-url {
  color: var(--text-muted);
}
/* unsetting link title style */
.cm-s-obsidian span.cm-link:hover {
  color: unset;
  text-decoration: unset;
}
/* unsetting link formatting characters style */
.cm-s-obsidian span.cm-formatting-link-string,
.cm-s-obsidian span.cm-formatting-link-string:hover,
.cm-s-obsidian span.cm-formatting-link:hover {
  color: var(--text-muted);
  text-decoration: none;
}

/* highlight */
.cm-highlight {
  border-bottom: var(--text-highlight-border);
}
.cm-s-obsidian span.cm-formatting-highlight, .cm-s-obsidian span.cm-highlight {
  color: var(--text-highlight-color);
}

Fade out sidebars when not in use #

.mod-left-split:not(:hover),
.mod-right-split:not(:hover) {
  opacity: 0.3;
}

Things to keep an eye on #

For writing:

For note-taking:

Others:


  1. Yes, I am still missing the Ulysses block editing feature. ↩︎