The Actual Mechanism
Completed checklist items (- [x] ...) get struck through and dimmed by Obsidian’s own core CSS, on by default. Confirmed via Obsidian’s own DevTools (Ctrl+Shift+I → inspect element → Styles panel shows the winning rule and its source file/line directly — the fastest way to answer “why does this render like X”, see feedback_css_debugging_devtools_first for the general lesson):
.markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="x"],
.markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="X"] {
text-decoration: var(--checklist-done-decoration);
color: var(--checklist-done-color);
}(source: app.css:14146)
Reading view picks up the equivalent via .task-list-item.is-checked. This is genuinely not discoverable by grepping the shipped JS/CSS bundles for literal strings like line-through — the values are indirected through var(--checklist-done-decoration) etc., so the rendered behaviour’s name never appears next to the selector.
The Working Fix
.obsidian/snippets/GoogleCompletedTasks.css — found via a plain web search rather than reverse-engineering the app, and it just works, no !important needed:
/* Affects Reading Mode */
.markdown-preview-view ul > li.task-list-item.is-checked,
.markdown-preview-view ol > li.task-list-item.is-checked {
text-decoration: none;
color: var(--text-normal);
}
/* Affects Editing/Live Preview Mode */
.markdown-source-view.mod-cm6 .HyperMD-task-line[data-task]:not([data-task=" "]) {
text-decoration: none;
color: var(--text-muted);
}Targets the actual rendering selectors directly rather than overriding the --checklist-done-* CSS variables — beats Obsidian’s default on specificity/source order alone. Live Preview intentionally uses var(--text-muted) (slightly dimmed) rather than fully normal text, tuned by Rick to taste — Reading Mode gets fully normal colour instead, but that’s moot since Rick basically never uses Reading Mode.
Deliberately doesn’t touch Tasks-plugin query block (```tasks ) results. Rick’s query blocks are filtered to not-done tasks anyway, so a completed task never actually shows up there — nothing to style. The fix only needed to cover native checklists sitting directly in notes, for readability when looking back at a note later.
Enabled via .obsidian/appearance.json’s enabledCssSnippets. Syncs across devices via OneDrive like any other vault file.
Dead Ends (kept so this isn’t re-investigated the same way twice)
- Adding a
text-decoration: line-throughrule to “fix” completed tasks not being struck through in atasksquery block. Backwards — the default already IS struck through everywhere via the core rule above; nothing needed adding, only removing/overriding. - Overriding
--checklist-done-decoration/--checklist-done-colordirectly at:root. Correct variables, correct values, but lost the cascade fight against the core rule without!important— worth knowing that this override path needs forcing, whereas selector-based overrides (the working fix above) don’t. Never got to confirm whether the!importantversion would have worked cleanly, since the Google snippet solved it first. - A
background: red !importantdiagnostic confirmed a snippet loads and matches, but doesn’t reveal that a competing rule already sets the same property to the same value —backgroundwasn’t contested by anything, so it lit up fine regardless of whether the real fix (targetingtext-decoration/color) was winning.