Creating fancy Horizontal Rule lines

Hi!

Horizontal rules are a fun element to style, though sometimes it’s frustrating to do special things with them.

Here’s a collection of templates to show off different things you can do to style them.

Gradient Horizontal Rules

Starting out quite simply, you can make the line a gradient from transparent on the sides to a solid color in the center.

The code:

body {
    --hr-line-offset: 25%;
    --hr-color: lightsalmon;
}

:root hr {
    border-image-slice: 1;
    border-image-source: linear-gradient(
        to right,
        transparent,
        var(--hr-color) calc(50% - var(--hr-line-offset)),
        var(--hr-color) calc(50% + var(--hr-line-offset)),
        transparent
    );
}

You may have seen similar snippets to this, but I’ve added two CSS variables to make it easier to customize.

  • --h1-line-offset allows you to change how wide the center solid color is
  • --hr-color is the original horizontal rule color variable, placed here for your convenience

Center Text Horizontal Rules

A bit more complicated now, this is the type you may have seen in themes like ITS or Maple.

The improvement here is a set of calc() functions that give a specific number of characters (or pixels if you prefer) offset from the symbol to the rest of the gradient. There’s also a sneaky translate declaration to ensure that any text you enter will be centered vertically, even if you want to have horizontal rules 20px tall or something.

The code:

body {
    --hr-line-offset: 25%;
    --hr-color: lightsalmon;
    --hr-text-color: lightblue;
    --hr-text-offset: 2ch;
    --hr-thickness: 4px;
}

:root hr {
    --hr-line-color: var(--hr-color);
    display: grid;
    place-items: center;
    border-image-slice: 1;
    border-image-source: linear-gradient(
        to right,
        var(--hr-line-color),
        var(--hr-line-color) calc(50% - var(--hr-text-offset)),
        transparent calc(50% - var(--hr-text-offset)),
        transparent calc(50% + var(--hr-text-offset)),
        var(--hr-line-color) calc(50% + var(--hr-text-offset)),
        var(--hr-line-color)
    );
}

:root hr::after {
    content: "★";
    font-weight: bold;
    color: var(--hr-text-color);
        position: absolute;
        translate: 0 calc(var(--hr-thickness) / -2);
}

Center Text with Gradient Horizontal Rules

The fanciest, this is basically what the Maple theme has. My addition here is the same as before with the specific character count offset.

The secret sauce here is another set of calc() functions to expand the line.

The code:

body {
    --hr-line-offset: 25%;
    --hr-color: lightsalmon;
    --hr-text-color: lightblue;
    --hr-text-offset: 2ch;
    --hr-thickness: 4px;
}

:root hr {
    --hr-line-color: var(--hr-color);
    display: grid;
    place-items: center;
    border-image-slice: 1;
    border-image-source: linear-gradient(
        to right,
        transparent,
        var(--hr-line-color) calc(50% - var(--hr-line-offset)),
        var(--hr-line-color) calc(50% - var(--hr-text-offset)),
        transparent calc(50% - var(--hr-text-offset)),
        transparent calc(50% + var(--hr-text-offset)),
        var(--hr-line-color) calc(50% + var(--hr-text-offset)),
        var(--hr-line-color) calc(50% + var(--hr-line-offset)),
        transparent
    );
}

:root hr::after {
    content: "★";
    font-weight: bold;
    color: var(--hr-text-color);
        position: absolute;
        translate: 0 calc(var(--hr-thickness) / -2);
}
15 Likes

Hi @FireIsGood, Thanks for this, I love customizing things like HR and Headings. I am adding some I came up with using a different method from this post Customised symbolic hr line that doesn’t use border but instead uses background. Two of them use windows fonts call Wingdings, not sure if Mac or Linux has them, the third one uses emoji.

I call this one Gothic Filigree

/*
** Customised symbolic hr line in Preview modded from TriDiamond's post (https://forum.obsidian.md/t/meta-post-common-css-hacks/1978/223)
*/
.markdown-source-view hr,
.markdown-preview-view hr {
  margin-block-start: 2em;
  margin-block-end: 2em;
  border: none;
  height: 1px;;
  background-image: linear-gradient(to right, var(--background-primary), tan, yellow, #e6d265, yellow, tan, var(--background-primary));
}
.markdown-source-view hr::before, 
.markdown-preview-view hr::before {
  content: '🙤x🙦'; /* '🙦 🙤' */
  color: #e6d265; /* #e6d265; */
  display: inline-block;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -55%);
  transform-origin: 50% 50%;
  padding: none;
  background-color: var(--background-primary);
}

I call this one Flower

/*
** Customised symbolic hr line in Preview modded from TriDiamond's post (https://forum.obsidian.md/t/meta-post-common-css-hacks/1978/223)
*/
.markdown-source-view hr,
.markdown-preview-view hr {
  margin-block-start: 2em;
  margin-block-end: 2em;
  border: none;
  height: 1px;;
  background-image: linear-gradient(to right, var(--background-primary), DarkOliveGreen, green, yellowgreen, yellowgreen, green, DarkOliveGreen,var(--background-primary));
}
.markdown-source-view hr::after, 
.markdown-preview-view hr::after {
  content: '🏶' ;/*'' */
  color: Tomato; /*lightcoral*/
  display: inline-block;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%); 
  transform-origin: 50% 50%;
  padding: none;
  background-color: var(--background-primary);
}
.markdown-source-view hr::before, 
.markdown-preview-view hr::before {
  content: '🙘🙤\00a0🙦🙚'; /* '🙦 🙤 🙐🙖 🙚 🙘' */
  color: DarkSeaGreen; 
  display: inline-block;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -55%);
  transform-origin: 50% 50%;
  padding: none;
  background-color: var(--background-primary);
}

Here is Flower using Emoji instead of fonts

/*
** Customised symbolic hr line in Preview modded from TriDiamond's post (https://forum.obsidian.md/t/meta-post-common-css-hacks/1978/223)
*/
.markdown-source-view hr,
.markdown-preview-view hr {
  margin-block-start: 2em;
  margin-block-end: 2em;
  border: none;
  height: 1px;
  background-image: linear-gradient(to right, var(--background-primary), DarkOliveGreen, green, yellowgreen, yellowgreen, green, DarkOliveGreen,var(--background-primary));
}
.markdown-source-view hr::after, 
.markdown-preview-view hr::after {
  content: '🌸';
  display: inline-block;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%); 
  transform-origin: 50% 50%;
  padding: none;
  background-color:transparent;
}

.markdown-source-view hr::before, 
.markdown-preview-view hr::before {
content: '🍀🍀';
display: inline-block;
position: absolute;
left: 50%;
transform: translate(-50%, -50%)rotate(160deg);
transform-origin: 50% 50%;
padding: none;
background-color: var(--background-primary);
}
6 Likes