What is a CSS file and why do you need it in Obsidian?
CSS
— is a language for styling the interface. And in Obsidian it unlocks incredible flexibility: you can change the look of any interface element — from links to callout blocks, tables, even the editor.
Unlike plugins, CSS doesn’t load down the system, doesn’t require updates and lets you control every pixel of your environment. It’s like a “hidden setting” you create yourself, for yourself.
📁 Where do you enable CSS files?
- Go to Settings → Appearance → CSS snippets
- Click “Open snippets folder”
- Put a
.cssfile in there (e.g.elton-style.css)- To create such a file, create an ordinary notepad file in that folder
- Then “Save as” > add .css at the end of the file name

- Restart Obsidian or just activate it with the toggle in the list
🔥 An example of my custom CSS file
.callout[data-callout="health"] {
--callout-color: 255, 199, 234;
--callout-icon: activity;
}
▶️ What this rule does:
-
healthis the name of the callout block. In Obsidian you write:>[!health], and this block gets a special style. -
--callout-color— sets a soft pink background (the colour is taken from here) -
--callout-icon: activity;— adds a “pulse” icon (taken from Lucide Icons)
.cm-s-obsidian .cm-link:hover {
color: #ffd700;
text-shadow: 0 0 5px #ffd700;
transition: all 0.3s ease;
}
▶️ What this rule does:
-
Changes the colour of links on hover to gold
#ffd700 -
Adds a soft glow (text-shadow) for emphasis
-
transition— makes the effect smooth
.callout[data-callout="motivation"] {
--callout-color: 255, 183, 0;
--callout-icon: "zap";
border-radius: 10px;
font-style: italic;
}
▶️ What this rule does:
-
motivation— the callout’s name. You can write>[!motivation]— and it’ll be highlighted. -
The colour — bright yellow, like a marker
-
The ⚡
zapicon adds energy -
border-radius: 10px— rounds the corners -
font-style: italic— makes the style “inspiring”, like handwriting
✨ What else can you do with CSS files?
Here are a few more cool ideas:
-
Make different styles for different tags — e.g. highlight
#🧠in blue and#🔥in red -
Style all tables with borders, shadows or zebra striping
-
Change the syntax-highlighting styles — e.g. your own colour for
Dataviewcode -
Add background images to certain callout blocks
-
Change the styling of specific editor elements — e.g. hide line numbers or highlight the current line
Cases:
-
The background of the app or panels. With CSS you can set an arbitrary background image or colour. For example, to set a background image in the main window, you can use the
.horizontal-main-containerselector, as in this snippet:.horizontal-main-container { /* A background image across the whole working screen */ background: url(https://images.unsplash.com/photo-1454496522488-7a8e488e8606?…); background-size: cover; }Here
background-size: coverstretches the image across the whole area. It’s also recommended to make the note background transparent, e.g. via--background-primary: transparent;, so the background behind it is visible. Such a setup lets you style the backdrop nicely. -
Font size and type. Fonts are set via the theme’s CSS variables or directly via
font-size. A general change to the base font size is conveniently done via variables (e.g.--font-size-base), or using media queries for different devices. An example from the Obsidian forum for different font sizes on PC and mobile:@media (min-width: 768px) { .cm-line { font-size: 14px; } /* Desktop */ } @media (max-width: 480px) { .cm-line { font-size: 16px; } /* Mobile */ } @media (min-width: 480px) and (max-width: 768px) { .cm-line { font-size: 17px; } /* Tablet */ }This snippet changes the text size in the editor for different screen widths.
-
Link and highlight colours. You can change the colour of internal links by overriding variables or selectors. For example, to change the colour of “dead” (unresolved) links, a CSS snippet specifies:
.markdown-rendered .internal-link.is-unresolved { /* The colour of an unresolved link */ --link-unresolved-color: #6272a4; font-size: var(--font-ui-small); }This is an example from a forum discussion [27] that sets a different shade for an unresolved link. For general colour settings (the background and decorative colour of a link) you can use the theme’s CSS variables, e.g.
--link-unresolved-color,--link-unresolved-decoration-color. Similarly, when searching you can configure the colour of the found text: one example makes the background transparent and changes the colour of found fragments to the theme’s accent colour:.workspace-leaf-content[data-type="search"] .search-result-file-matched-text { background: none; color: var(--text-accent); }Such a rule removes the yellow highlight and gives the found words the main text colour.
-
Styling lists. You can set different markers for different list nesting levels. For example, a snippet from GitHub changes the shape of the circles in marker lists: the first level — a filled circle, the second — an empty circle, the third — a square, the fourth — a triangle, and so on. A simplified example:
/* Level 1: filled circle */ .markdown-reading-view .markdown-preview-section ul li > .list-bullet:after { height: 7px; width: 7px; border-radius: 50%; } /* Level 3: square */ .markdown-reading-view .markdown-preview-section ul li ul li ul li > .list-bullet:after { height: 7px; width: 7px; border-radius: 0%; } /* Level 4: triangle */ /* (a triangle is created using border styles) */The full code and details are in snippet [25] (GitHub), which provides different marker shapes across 5 list levels.
-
Panels and icons. With CSS you can hide or change interface elements. For example, to hide the icons of unwanted plugins on the side panel (ribbon), you can target the elements by
aria-labeland give themdisplay: none:.clickable-icon[aria-label='Templater'], .clickable-icon[aria-label='Toggle custom sorting'] { display: none; }This code removes the Templater and Custom Sort plugin buttons from the ribbon menu. In the same way you can hide other icons or change the order of the buttons. You can also set up automatic hiding of the ribbon: an example solution with
body:has(.is-sidedock-collapsed)hides the ribbon when the left sidebar is collapsed (see discussion [32]). -
Graph View. The graph area is a
<canvas>, which you can style with underlying gradients or images. For example, designers suggest making the graph background starry: setting CSS forcanvas, overlaying a gradient and an SVG with stars. It’s also known from discussions that you can overlay a background image on.workspace-leaf-content[data-type="graph"] .view-contentor its pseudo-element::after. So, one example makes a blurred background (an image across the whole graph background) and darkens it:.workspace-leaf-content[data-type="graph"] .view-content { z-index: 0; position: absolute; background-image: url(https://picsum.photos/200); background-size: cover; filter: blur(4px) brightness(50%) saturate(50%); left:0; top:0; right:0; bottom:0; }This overlays a background with blur and darkening filters on the graph. There’s also an improved version with
::after, so the graph stays in the foreground:.workspace-leaf-content[data-type="graph"] .view-content::after { z-index: -1; content:""; position:absolute; background-image: url(https://picsum.photos/200); filter: blur(4px) brightness(50%) saturate(50%); left:0; top:0; right:0; bottom:0; }Such styles noticeably change the look of the Graph View, making the background more atmospheric (the code fragments are taken from discussion [40]).
-
Interactivity of images and videos. For reading comfort you can add “smart” scaling of embedded media. In one snippet for images, the cursor changes on hover, and on click the image expands to full screen:
.view-content img { max-width:100%; cursor:zoom-in; } .view-content img:active { cursor:zoom-out; } /* and rules for .image-embed:active to fix and centre it */For videos you can assign aliases and shrink the player accordingly. From a Telegram chat: when you add the alias
vid-20to a video object, the rule[alt~="vid-20"] video { width: 20%; }is applied, and the video immediately shrinks to 20% of the screen width. That is, by putting
![[video.mp4|vid-20]]in a note, we get a shrunken video. This trick improves UX when working with large media files (the example is taken from a user’s chat). -
Adapting for mobile devices. With media queries you can adjust the interface for mobile screens. Besides the font-size example above, people often configure the width of panels or other sizes. For example, you can change the size of folders and items in the side tree:
@media (max-width: 480px) { .tree-item-children, .nav-folder-title { font-size: 17px; } }(the fragment is from the same discussion where they configure fonts and navigation panel elements for mobile). Such adaptation makes the app convenient on small screens.
Keep going?

