CSS Tricks for Markdown Blogs

dandep1 pts0 comments

CSS tricks for markdown blogs / My blog / dan—webnotes

Skip to main content

2026-06-28

🔗 CSS tricks for markdown blogs

All the post content you are reading here comes from a single markdown file converted into HTML and stylized with CSS.

Reducing what is rendered via template will limit what's possible in terms of layout and interactivity. But it guarantees that, if I move my site to a different setup, the plain text files will carry most of the content with them.

Also it's interesting to explore what is possible to get out of CSS alone. Here are a few of the tricks used in this blog.

I'm manually writing the post date and post title for each post. I simply add these to the top of the file.

2026-06-28

# CSS tricks for markdown blogs

Then, the CSS targets the date, as the first paragraph at the top of each post, adding a custom styling.

article > p:first-child {<br>font-size: 0.9rem;

Whenever an italic text comes right after an image, I want to style it to make it look like a actual caption.

Photo by Josefin on Unsplash

The CSS uses the sibling selector img + em to target the first italic after an image.

![Green leaves](josefin-WS5yjFjycNY-unsplash.jpg)<br>_Photo by Josefin on Unsplash_

I can make the CSS create a double column layout with two images side-by-side, by simply writing them next to each other in the markdown text.

![Three possums on a red balloon](possum.png)<br>![Three possums on a red balloon](possum.png)

Modern CSS makes this possible, by target the images container, with a combination of the parent selector :has(), sibling selectors and CSS grid .

@media (min-width: 768px) {<br>p:has(img ~ img) {<br>display: grid;<br>grid-auto-flow: column;<br>grid-gap: 0 1.5em;<br>grid-template-columns: repeat(2, minmax(0, 1fr));<br>grid-template-rows: repeat(2, auto);

Two pictures of beautiful possums that will be side by side on desktop

Styling numbered lists with . When doing lists, all the list items' content must fit a single paragraph, even code blocks or images. Splitting the content over multiple paragraphs would make the list number restart.

ol {<br>list-style-type: decimal;

ol > li::marker {<br>content: counter(list-item) " ";

The markdown parser, markdown-it, will automatically set the start attribute on any list that doesn't start with 1. You can then read that value with counter(list-item), if you wish to apply custom styles to the list.

I add links and resources at the bottom of the post manually. While there are plugins that do this, it's nice to have the simplest and most portable setup possible. The markdown parser, markdown-it, adds automatically the hash link and the id to all the headings.

#resources ~ ul > li > a::after {<br>content: "(" attr(href) ")";

Then, with CSS it's possible to target the resources list and style them differently from the article's lists. I also use a ::after pseudo-element and its content property to have the URL of the link displayed inline, which helps to identify links at a glance.

With a regex formula inside the CSS attribute selector, I can target the links that have a certain word inside their href attribute and style it with a favicon, without fetching data and without javascript.

a[href*="wikipedia.org"]::before {<br>width: 1em;<br>height: 1em;<br>mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='.../%3E%3C/svg%3E");

# Resources

File over app

markdown content list post grid tricks

Related Articles