Markdown-ish Styling Posted on: 2013-06-06

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.