`not-prose` does not reset `prose-lg`
pySilver opened this issue · 2 comments
What version of @tailwindcss/typography are you using?
0.5.9
What version of Node.js are you using?
20
What browser are you using?
Chrome
What operating system are you using?
macOS
Reproduction repository
https://play.tailwindcss.com/PuKQCiWJ8q
Describe your issue
not-prose does not unset font sizes and line heights set by prose-lg
Here is the playground: https://play.tailwindcss.com/PuKQCiWJ8q
Hey! So I totally understand why this is unexpected behavior...you're expecting the not-prose class to completely disable all the prose styles. And while this generally works, it falls apart a bit with the root styles that set the font size and line height. This is because the font-size and line-height properties are inherited, which means they cascade to child elements.
I spent a bunch of time on this today, and the only way to reliably prevent the prose styles from being applied to the not-prose element would be to never put them on the root element to begin with and only apply the font size and line height to each direct child that doesn't have the not-prose class on it. Something like this:
.prose-lg > :where(:not([class~="not-prose"])) {
font-size: 18px;
}The only problem with that solution is that today not-prose works on any descendant element, not just direct children, so this would be a breaking change. For example, if we made this change, this code that has not-prose applied to a div within an article would break:
<div class="prose">
<h1>Title</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
<article>
<div class="not-prose">
I am not styled with prose
</div>
</article>
</div>An alternative solution could be to select all of the descendants, not just the direct children. Something like this:
.prose :where(h1:not([class~="not-prose"] *)) {
font-size: 30px;
}
.prose-lg :where(:not([class~="not-prose"])) {
font-size: 18px;
}
.prose-lg :where(h1:not([class~="not-prose"] *)) {
font-size: 36px;
}This works great until you add a child element to something that the typography plugin styles — such as an h1, p, li, etc. The child element would get targeted by the prose-lg selector (because we're using *), which would result in the wrong styles being applied.
Using the example above, that would mean if you include a span within an h1, that span would end up being 18px instead of 36px, which isn't what you want:
<div class="prose prose-lg">
<h1>Title <span class="text-gray-600">secondary</span></h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
<div class="not-prose">I am not styled with prose</div>
</div>Also worth noting that we can't simply reset not-prose back to 1rem (the Tailwind preflight default) because it's possible that someone has changed their root font size, or even the font size of the prose section.
CSS does have a new feature coming called scoped styles, which will make implementing not-prose much, much easier, since we can limit prose styles from inheriting into not-prose:
@scope (.md\:prose-lg) to (.not-prose) {
:scope {
font-size: 1.125rem;
line-height: 1.7777778;
}
}Unfortunately this feature is still very early on and isn't supported by any browsers yet.
My recommendation for you at this point would be to simply apply the correct font size (and line-height utility if needed) when using not-prose:
<div class="prose md:prose-lg">
<h1>Title</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
<div class="not-prose md:text-base">I am not styled with prose</div>
</div>Hope that helps!