Pre in Astro + Tailwind
This blog is built with Astro and styled with Tailwind CSS, as many technical blogs are. After starting, it took only a few posts for me to find the need to include a code snippet.
Astro makes syntax highlighting very easy, so I added my code snippet, fiddled with the theme, and published away. Checking out the post on my phone, I noticed that the code snippet had some issues with long lines: the block was wider than the viewport and expanded all of the text on the page to also be too wide.
It was not pretty!
The Bandaid
I fiddled with the tailwind classes for a moment.
This did not help.
I settled on the quickest fix to get the post readable on mobile: setting wrap
to true
in my shikiConfig
.
// astro.config.mjs
export default {
// ...
markdown: {
shikiConfig: {
// ...
wrap: true,
},
},
};
Just to hedge my bets, I threw in a quick note below the wrapped code in the blog post.
<aside>
Reading on mobile? Sorry about the code formatting... shoot me a message if
you know how to customize the rendering of shiki components generated from
markdown in astro.
</aside>
Today, I am revisiting this bandaid so that I can be proud of my code snippets again.
Background
Let’s go over what’s happening when I render a code block in Astro:
Astro uses Shiki to render code blocks.
Shiki parses the code block and generates a pre
tag with a code
tag inside, then a span
for each line.
When wrap
is set to true
, Shiki adds some styles directly to the root pre
element.
<pre
class="..."
style="...; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"
tabindex="0"
data-language="ts"
>
<code>...</code>
</pre>
With wrap
set to false
, the pre
tag has no white-space: pre-wrap
and word-wrap: break-word;
styles. As far as I know, this should make things work perfectly!
But it didn’t, for me.
This blog post plus a handful of GitHub issues and StackOverflow questions validated my experience: pre
tags have some issues at smaller screen sizes in Tailwind.
Solution
I went in circles and circles and circles, writing and reqriting tailwind classes and vanilla css, adding and removing shiki config values, and so much more.
I read the resources above and though I tried all their approaches, and still I was stuck.
Finally, pondering the blog post above once more, I read and re-read the diagnosis:
Where the problem lies: When the <pre> content is wrapped within a flex and grid parent, it experiences stretching.
I looked once more at my generated HTML, noting with satisfaction that the article
parent of my code blocks was flex-free.
Absentmindedly, I navigated in dev tools to the Flexbox Overlays
section of the Layout
tab.
While my article
was not a flex container, the base html
was!
I assume this is a rookie mistake.
Removing the flex
class from the html
tag in my layout fixed the issue on mobile.
This introduced a styling issue on desktop, left-justifying the article content, that I addressed with the advice given in the Github issue linked above.
Further, I added max-w-prose
class to my header to match the article content.
So, if you are using Tailwind CSS and Astro and you are having issues with code blocks on mobile, check your flex containers!
<html lang="en" class="flex justify-center max-w-full">
<html lang="en">
<body class="bg-black mt-8 mx-4 text-white">
<main>
<article class="prose ...">
<article class="prose mx-auto ...">
<!-- ... -->
</article>
</main>
</body>
</html>