Markdown-ish StylingPosted on: June 06, 2013

Being a developer, I wanted to roll in a bit of geekiness into my latest redesign and since I absolutely love Markdown I figured I might as well do something with that.

The bits of MarkDown I decided to use are the following:

  • h1 & h2: I only need two levels of heading on my site, and I went with the # prefixed flavour
  • Inline code
  • Unordered list items
  • Italicized text
  • Bolded text

What I didn't do anything about, and why:

  • Paragraphs are already identical in style.
  • Links would just be awkward in my opinion.
  • For proper chunks of code, I wanted to rather use Prism.
  • Blockquotes - this is probably my least favourite part of markdown. All those > symbols hearken too much to the chain emails of the 90s for my liking.

Now while Markdown is great, I didn't want selecting the text to also select the markdown flavoured stuff which is where the :before and :after pseudo elements came to my rescue. Without further waffling on my part, here's what makes it all work (note, this is in SCSS):

/*===== Spacing =====*/
h1,
h2,
em,
strong,
code:not([class]),
ul li {
  position: relative;
}
h1 {
  padding-left: 0.8em;
}
h2 {
  padding-left: 1.6em;
}
em {
  padding: 0 0.6em;
}
strong {
  padding: 0 1.1em;
}
code {
  margin: 0 0.6em;
}
ul {
  padding-left: 1em;
  li {
    padding-left: 1em;
  }
}

/*===== Positioning =====*/
%posTop {
  position: absolute;
  top: 0;
}
h1::before,
h2::before {
  left: 0;

  @extend %posTop;
}
em,
strong {
  &::before,
  &::after {
    @extend %posTop;
  }
  &::before {
    left: 0;
  }
  &::after {
    right: 0.1em;
  }
}
code {
  position: relative;
  &::before,
  &::after {
    @extend %posTop;
    display: block;
  }
  &::after {
    right: -0.6em;
  }
  &::before {
    left: -0.6em;
  }
}
pre code {
  margin: 0;

  &::before,
  &::after {
    display: none;
  }
}
ul li::before {
  left: -1em;
  position: relative;
}

/*===== Markdown Elements =====*/
h1::before {
  content: "#";
}
h2::before {
  content: "##";
}
em {
  &::before,
  &::after {
    content: "*";
  }
}
strong {
  &::before,
  &::after {
    content: "**";
  }
}
code {
  &::before,
  &::after {
    content: "`";
  }
}
ul li {
  list-style: none;

  &::before {
    content: "+";
  }
}
ol li {
  list-style: decimal;
}

Note: Wherever there's padding will probably need tweaking based on the font you use.

The last thing I did was to provide some fallback for when I wanted to unset the markdown style on any child element:

.no-md {
  h1::before,
  h2::before,
  li::before,
  em::before,
  em::after,
  strong::before,
  strong::after,
  code:not([class])::before,
  code:not([class])::after {
    display: none;
  }
  h1,
  h2 {
    padding-left: 0;
  }
  em,
  strong,
  code:not([class]) {
    padding: 0;
  }
}

To close, I would just say that I'm fairly sure this isn't 100% perfect, and there will be things that I'll change and I'll try my best to update this post to reflect that.