Custom CSS Headers

As a follow up from:

I ended up making my own custom headers. As “just make the text larger” isn’t something that really helped me split my content. (honestly whether that is in Word or Logseq lol)
So I managed to get it working both for my queries and for normal bullets.

In Logseq

Page markdown

- [:b.header [:b.icon "📅"] "Header with icon"]
	- Other text
- [:b.header "Header without icon"]
	- Other text
- #+BEGIN_QUERY
  {:title [:b.header [:b.icon "📅"] "Query header with icon"]
   :query [:find (pull ?b [*])
    :where
     [?p :block/name "experiment"]
     [?h :block/page ?p]
     [?h :block/content "[:b.header \"Header without icon\"]"]
     [?b :block/parent ?h]
   ]
   :breadcrumb-show? false
   :group-by-page? false
  }
  #+END_QUERY
- #+BEGIN_QUERY
  {:title [:b.header "Query header without icon"]
   :query [:find (pull ?b [*])
    :where
     [?p :block/name "experiment"]
     [?h :block/page ?p]
     [?h :block/content "[:b.header \"Header without icon\"]"]
     [?b :block/parent ?h]
   ]
   :breadcrumb-show? false
   :group-by-page? false
  }
  #+END_QUERY

CSS code

b.icon {
  font-size: 1.4rem;
  line-height: 1.6;
  margin-left: 0.2em;
  margin-right: 0.5em;
}
div.block-content-inner:has(b.header) {
  background-color: var(--ls-page-mark-bg-color);
}
.custom-query>.th:has(b.header) {
	background-color: var(--ls-page-mark-bg-color);
	color: var(--ls-page-mark-color);
}
.custom-query>.th:has(b.header) .fade-link {
	color: var(--ls-page-mark-color);
}
b.header {
  font-size: 1.2rem;
  line-height: 1.6;
  color: var(--ls-page-mark-color);
  margin-left: 0.4em;
}
b.header b.icon {
  font-size: 1.2rem;
  margin-left: 0em;
}

Notes

  • You can also :b.icon outside of :b.header as shown in the linked thread.
  • This is just an example, you can change the values to create your own look.

Thanks!
I was doing something similar with :title [:h3 {:class "outstanding-tasks"} "📅 Outstanding Tasks"], but was still missing a few css options for line-height and similar so it still looked a bit ugly. I didn’t realize hiccup could just tag on classes like that.

1 Like

I extended my suite with some other options for myself. Thought I’d share those too.

Markdown:

- [:b.pauze [:b.icon "🕯️"] "Test break"]
- [:b.faint][:b.icon "🔦"] Test highlight
- [:b.header [:b.icon "🕯️"] "Test header"]
- [:b.headerS [:b.icon "🕯️"] "Test small header"]
- [:b.subtle [:b.icon "🕯️"] "Test subtle header"]
- [:b.under [:b.icon "🕯️"] "Test underlined header"]

(For the :b.faint one I needed something that wouldn’t interfere with references, hence it only adds a background color.)

CSS:

b.icon {
  font-size: 1.4rem;
  line-height: 1.6;
  margin-left: 0.2em;
  margin-right: 0.5em;
}
div.block-content-inner:has(b.pauze) {
  background-color: var(--ls-quaternary-background-color);
  border-radius: 0.25em;
}
b.pauze {
  font-weight: 600;
  font-size: 1.2rem;
}
b.pauze b.icon {
  margin-right: 0.7em;
}

/* COMMON B LOOKS*/
b.header,
b.headerS,
b.subtle,
b.under {
  margin-left: 0.4em;
}
b.header,
b.subtle,
b.under {
  font-size: 1.2rem;
  line-height: 1.6;
}
b.header b.icon,
b.subtle b.icon,
b.under b.icon {
  font-size: 1.2rem;
  margin-left: 0em;
}
div.block-content-inner:has(b.header), 
.custom-query>.th:has(b.header),
div.block-content-inner:has(b.headerS), 
.custom-query>.th:has(b.headerS),
div.block-content-inner:has(b.subtle),
.custom-query>.th:has(b.subtle),
div.block-content-inner:has(b.faint),
.custom-query>.th:has(b.faint) {
  border-radius: 0.25em;
}

b.headerS b.icon {
  font-size: 1rem;
  margin-left: 0em;
}

/* Header colors */
div.block-content-inner:has(b.header),
.custom-query>.th:has(b.header),
div.block-content-inner:has(b.headerS),
.custom-query>.th:has(b.headerS) {
  background-color: var(--ls-page-mark-bg-color);
}
b.header,
.custom-query>.th:has(b.header),
.custom-query>.th:has(b.header) .fade-link,
b.headerS,
.custom-query>.th:has(b.headerS),
.custom-query>.th:has(b.headerS) .fade-link {
  color: var(--ls-page-mark-color);
}

div.block-content-inner:has(b.subtle) {
  background-color: #1c1817;
  border-bottom: thin solid #442222;
}
.custom-query>.th:has(b.subtle) {
  background-color: var(--ls-primary-background-color);
  border-bottom: thin solid var(--ls-border-color);
}

div.block-content-inner:has(b.under) {
  border-bottom: thin solid var(--ls-page-mark-bg-color);
}
.custom-query>.th:has(b.under) {
  border-bottom: thin solid var(--ls-page-mark-bg-color);
}

div.block-content-inner:has(b.faint),
.custom-query>.th:has(b.faint) {
  background-color: #442222;
}

Yes it has gotten quite big to make it all work.
Should someone with css knowledge know a better way, I’d love to hear it!

  • I would suggest to make your css classes more modular. Examples:
    • instead of b.header , use b.header.dflt
    • instead of b.headerS , use b.header.small
    • instead of b.subtle , use b.header.subtle
    • instead of b.under , use b.header.under
  • Then could e.g.:
    • simplify this:
      b.header,
      b.headerS,
      b.subtle,
      b.under {
        margin-left: 0.4em;
      }
      
    • to this:
      b.header {
        margin-left: 0.4em;
      }
      
  • In general, instead of defining all possible combinations, for each style could define only:
    • one default rule
    • one rule for each exception
  • With careful choices, your css can go down to half.
2 Likes

Thanks! I’ll fiddle around with this some more. See if I can come to something a bit more modular.
Should probably start back from basics and make it easier to change/add to.

A whole lot of fiddling later :smiley:

/* HEADERS
Can be used with any hiccup element.
- for example: [:span.h "text"]
- or for bold text: [:b.h "text"]
Can add extra's with .name (eg. b.h.light or b.h.light.size2)
For extra's that don't affect text, the text can be placed outside the hiccup to allow Logseq rendering
- for example [:span.h.dark] ((block id))
Background color and/or border:
- .light : text + background color
- .dark : background color
- .subtle : background color + bottom border
- .under : bottom border
Font size:
- .size2 : 1.2x root element
- .size4 : 1.4x root element
- .size6 : 1.6x root element
Can change font size of parts of header.
- for example: [:span.h.size4 "part 1" [:span.h.size2 "part 2"]]
Special .mr class for extra spacing. Mainly for icons
- for example: [:span.h.mr "✅"] Text or [:span.h.dark [:span.mr "✅"] "Text"]
- can also add font size modifier to change icon size.
Final notes:
- .h adds margin to the left and line-height.
- .h is therefore optional, but looks better for headers with a background and/or border.
*/

/* General header settings */
.h {
  margin-left: 0.4rem;
  line-height: 1.6;
}
/* Margin right for extra spacing after an icon */
.mr {
  margin-right: 0.7rem;
}

/*Light Highlight */
.light,
.custom-query>.th:has(.light) .fade-link {
  color: #262626;
}
div.block-content-inner:has(.light),
.custom-query>.th:has(.light) {
  border-radius: 0.25rem;
  background-color: #ca8051;
}

/* Dark Highlight */
div.block-content-inner:has(.dark), 
.custom-query>.th:has(.dark) {
  border-radius: 0.25rem;
  background-color: #442222;
}

/* Grey Highlight */
div.block-content-inner:has(.grey), 
.custom-query>.th:has(.grey) {
  background-color: #362f2e;
  border-radius: 0.25rem;
}

/* Subtle Highlight */
div.block-content-inner:has(.subtle), 
.custom-query>.th:has(.subtle) {
  border-radius: 0.25rem;
  background-color: #1c1817;
  border-bottom: 0.11rem solid #442222;
}

/* Underline "Highlight" */
div.block-content-inner:has(.under), 
.custom-query>.th:has(.under) {
  border-bottom: thin solid #ca8051;
}

/* Text Sizes */
.size2 { font-size: 1.2rem; }
.size4 { font-size: 1.4rem; }
.size6 { font-size: 1.6rem; }

Markdown:

- [:b.h.under.size4 "Examples mentioned in code"]
- [:span.h "text"]
- [:b.h "text"]
- [:span.h.dark] ((66714566-2e87-46ab-b90c-0b9f33a3501e))
- [:span.h.size4 "part 1" [:span.h.size2 "part 2"]]
- [:span.h.mr "✅"] Text
- [:span.h.dark [:span.mr "✅"] "Text"]
-
- [:b.h.under.size4 "Extra examples"]
- | Icon size | Normal space | .mr class |
  | Normal | 🧺 Text | [:span.mr "🧺"] Text |
  | Size 2 | [:span.size2 "🧺"] Text | [:span.mr.size2 "🧺"] Text |
  | Size 4 | [:span.size4 "🧺"] Text | [:span.mr.size4 "🧺"] Text |
  | Size 6 | [:span.size6 "🧺"] Text | [:span.mr.size6 "🧺"] Text |
- [:span.h.light "Light with .h"]
- [:span.light "Light without .h"]
- [:span.h.size2 "Size 2 with .h"]
- [:span.size2 "Size 2 without .h"]
- #+BEGIN_QUERY
  {:title [:span.h.light.size4 "Light size4 query header"]
  }
  #+END_QUERY
-
- [:b.h.under.size4 "Overview of individual options"]
- [:span.h.light "Light header"]
- [:span.h.dark "Dark header"]
- [:span.h.subtle "Subtle header"]
- [:span.h.under "Under header"]
- [:span.h.grey "Grey header"]
- [:span.h.size2 "Size2 header"]
- [:span.h.size4 "Size4 header"]
- [:span.h.size6 "Size6 header"]
-
- [:b.h.under.size4 "My personal use"]
- [:span.h.grey][:span.mr.size4 "🕯️"] [:b.size2 "To show breaks in my day planning"]
- [:span.h.dark][:span.mr.size4 "🔦"] To show focus items in my day planning
- [:span.h.mr.size4 "🧺"] To show regular items in my day planning
- [:b.h.light.size2 "For use as headers"]
- [:b.h.light.size2 [:b.mr "✅"] "Sometimes with header icons"]
2 Likes

Nice. The next level is to go semantic. That means for your classes to not describe the applied style, but the intended usage. Some example classes:

  • .break
  • .day
  • .focus
  • .header
  • .icon

I find that one quite hard. Because it leaves classes with intended use, which over time may no longer reflect actual use and that, for me at least, may lead to confusion.
I quite liked the outcome of my focus coloring, or dark highlight header and am now using it for normal headers too.
Having to remember that it is called focus, is more difficult than remembering it is called dark.