Writing CSS for Markdown is Writing CSS for the standard HTML elements. This is where those Classless CSS works pretty well. Pick the one you like and then add your own. That should keep the CSS file size low enough to be negligible and sometime even embed in your HTML.
I want this guide page to also explain the decisions behind CSS for styling markdown as well though. I'm hoping to help people be able to write their own CSS, or at least become better at evaluating existing projects.
The article mentions targeting both `<picture>` and `<img>` elements, but that is redundant - just target `<img>`s. `<picture>` has to have one `<img>` node anyway.
As others have said, this is nothing to do with Markdown. It’s regular HTML styling.
—⁂—
> Paragraph <p>
… proceeds to talk about CSS Custom Properties (misnaming them CSS Variables—I wouldn’t mind “CSS variables” so much, but the capital V implies a proper noun), which are utterly irrelevant to styling, and body styles, saying that <p> then needs nothing extra.
body {
font-family: ui-sans-serif, "Source Sans Pro", "Helvetica", system-ui;
line-height: 1.75;
}
No, no, no.
1. ui-sans-serif and system-ui are inappropriate here. UI fonts are not designed for long-form content, and in some OS/language combinations you’ll get an absolutely obnoxious result. Just use `sans-serif`. Or `"Source Sans Pro", sans-serif` if you’re loading that as a web font.
2. 1.75 is unreasonably spacious, especially on small displays. If you’re choosing a single value, you probably shouldn’t go beyond 1.5.
If you think this is worthwhile, you should probably apply it to more than just headings. You may argue that headings’ larger sizes make overflow within a single word more likely, but in my experience it happens much more often in body text, when you do things like write a URL out literally.
—⁂—
img, picture {
object-fit: scale-down;
}
Unnecessary, given `height: auto`. Aside: I believe this is the first time I’ve ever seen scale-down used.
> If you are using a framework like Astro, to center the image you will want to add margin-inline: auto and display: block to center the image.
What has this to do with Astro!? Just as Markdown is a red herring or worse, Astro is irrelevant here.
—⁂—
ol, ul {
margin-left: 1em;
}
I’m guessing you haven’t used a CSS reset, because otherwise you’d have been adding block margins to things like headings and paragraphs. So, you’ve still got the user-agent stylesheet’s `padding-inline-start: 40px`. And padding is definitely more semantically reasonable than margin, when you consider how the list item markers are placed outside—if you were putting border on the list itself, you’d want the markers to sit inside that border.
So, at present you’ve got 1em + 40px (≈56px) of indent on list item bodies. This is way too much. Even the 40px is too much. But if you forgot to mention that you were zeroing the padding-inline-start: the 1em by itself (≈16px) is too little for numbered lists, double-digit markers will typically overflow (and in some other language or font configurations, even the 1em will be overflowing). I’d suggest 1.5em (≈24px) as the smallest reasonable value for English text with decimal markers.
li {
overflow-wrap: anywhere;
}
As before: ditch this, and if you want its effect, apply it more generally.
—⁂—
> "There's never a space under paintings in a gallery where someone writes their opinion,"
Argh! The image of this has the " straight quotes turned into the wrong curly quotes! ”…“.
> <footer>— Natalie Dee</footer>
Possibly worth mentioning it’s relatively common to have `blockquote footer::before { content: "— "; }`.
Could have done `td, th` for the first rule and deduplicated.
background-color: grey; //different background color applied to every second row
No such thing as // comments in CSS. Write /* … */. (There’s another case like it later.)
Also it’s worthwhile mentioning the name for this technique: zebra stripes.
—⁂—
background-color: blue !important;
There’s almost never a good reason to use !important. Definitely I can’t see one here. If you’re using it to override inline styles from your “Astro Expressive Code” or similar: don’t, fix it in its configuration instead.
It grates that, where normally you’re using obviously placeholder colours, just occasionally you use variables, sometimes gratuitous unnecessary ones.
code,
code span,
pre {
This is not a well-thought out rule set. Consider each declaration inside and whether it should be applied to all three of these selectors. Most of them shouldn’t (though they’re mostly harmless in practice).
One final remark in this code styling stuff: I find it unreasonably common for this sort of page to apply conflicting sets of styles, with the base styles applied to the HTML actually illegible (e.g. white on white), relying on classes like <html class="light"> being added by JavaScript to make things legible.
Writing CSS for Markdown is Writing CSS for the standard HTML elements. This is where those Classless CSS works pretty well. Pick the one you like and then add your own. That should keep the CSS file size low enough to be negligible and sometime even embed in your HTML.
- <https://classless.de>
- <https://github.com/dbohdan/classless-css>
Thanks for sharing this as well! I will mention that repo of classless CSS projects.
I also mentioned that using one of these is a viable alternative to writing your own. I included a link to this repo there: https://github.com/swyxio/spark-joy/blob/master/README.md#dr...
I want this guide page to also explain the decisions behind CSS for styling markdown as well though. I'm hoping to help people be able to write their own CSS, or at least become better at evaluating existing projects.
The article mentions targeting both `<picture>` and `<img>` elements, but that is redundant - just target `<img>`s. `<picture>` has to have one `<img>` node anyway.
Thanks for this! Gonna update the post.
I personally always use
so that flexbox behaves in a way you would expect.It's truly wonderful that this post is getting some traction a whole week after I posted it!
If you have any feedback, e.g. possible improvements, or links to other relevant high-quality sources please let me know!
I also just realised that one paragraph is duplicated, will fix that later.
My aim for this site is to make it into a guide on creating clean bloat-free websites that can scale well.
I think I probably used this one https://github.com/sindresorhus/github-markdown-css
Side by side markdown and its rendering under this CSS?
For every instance of a Markdown element in the common core?
With tuners, selectors or sliders to make variables change?
This article doesn’t fill me with confidence.
—⁂—
> Styling Markdown
As others have said, this is nothing to do with Markdown. It’s regular HTML styling.
—⁂—
> Paragraph <p>
… proceeds to talk about CSS Custom Properties (misnaming them CSS Variables—I wouldn’t mind “CSS variables” so much, but the capital V implies a proper noun), which are utterly irrelevant to styling, and body styles, saying that <p> then needs nothing extra.
No, no, no.1. ui-sans-serif and system-ui are inappropriate here. UI fonts are not designed for long-form content, and in some OS/language combinations you’ll get an absolutely obnoxious result. Just use `sans-serif`. Or `"Source Sans Pro", sans-serif` if you’re loading that as a web font.
2. 1.75 is unreasonably spacious, especially on small displays. If you’re choosing a single value, you probably shouldn’t go beyond 1.5.
—⁂—
If you think this is worthwhile, you should probably apply it to more than just headings. You may argue that headings’ larger sizes make overflow within a single word more likely, but in my experience it happens much more often in body text, when you do things like write a URL out literally.—⁂—
Unnecessary, given `height: auto`. Aside: I believe this is the first time I’ve ever seen scale-down used.> If you are using a framework like Astro, to center the image you will want to add margin-inline: auto and display: block to center the image.
What has this to do with Astro!? Just as Markdown is a red herring or worse, Astro is irrelevant here.
—⁂—
I’m guessing you haven’t used a CSS reset, because otherwise you’d have been adding block margins to things like headings and paragraphs. So, you’ve still got the user-agent stylesheet’s `padding-inline-start: 40px`. And padding is definitely more semantically reasonable than margin, when you consider how the list item markers are placed outside—if you were putting border on the list itself, you’d want the markers to sit inside that border.So, at present you’ve got 1em + 40px (≈56px) of indent on list item bodies. This is way too much. Even the 40px is too much. But if you forgot to mention that you were zeroing the padding-inline-start: the 1em by itself (≈16px) is too little for numbered lists, double-digit markers will typically overflow (and in some other language or font configurations, even the 1em will be overflowing). I’d suggest 1.5em (≈24px) as the smallest reasonable value for English text with decimal markers.
As before: ditch this, and if you want its effect, apply it more generally.—⁂—
Argh! The image of this has the " straight quotes turned into the wrong curly quotes! ”…“. Possibly worth mentioning it’s relatively common to have `blockquote footer::before { content: "— "; }`.—⁂—
Could have done `td, th` for the first rule and deduplicated. No such thing as // comments in CSS. Write /* … */. (There’s another case like it later.)Also it’s worthwhile mentioning the name for this technique: zebra stripes.
—⁂—
There’s almost never a good reason to use !important. Definitely I can’t see one here. If you’re using it to override inline styles from your “Astro Expressive Code” or similar: don’t, fix it in its configuration instead. It grates that, where normally you’re using obviously placeholder colours, just occasionally you use variables, sometimes gratuitous unnecessary ones. This is not a well-thought out rule set. Consider each declaration inside and whether it should be applied to all three of these selectors. Most of them shouldn’t (though they’re mostly harmless in practice).One final remark in this code styling stuff: I find it unreasonably common for this sort of page to apply conflicting sets of styles, with the base styles applied to the HTML actually illegible (e.g. white on white), relying on classes like <html class="light"> being added by JavaScript to make things legible.
Why is this comment collapsed? There's so much valuable feedback here.