tailwindlabs/tailwindcss-typography

Tailwind 4: `first-child` resets for `margin-top` missing when type scale is added with a breakpoint prefix

danieltott opened this issue ยท 11 comments

What version of @tailwindcss/typography are you using?

v0.5.16

What version of Node.js are you using?

22.13 locally, also happening on Tailwind Play

What browser are you using?

Chrome, Firefox

What operating system are you using?

mac

Reproduction repository

https://play.tailwindcss.com/FbG6fLD0eT

Describe your issue

In .prose, non-h1 headings by default have a margin-top applied. If the heading is the first child, then there is css that resets margin-top to 0.

When you add a size modifier (prose-lg etc), there is an updated margin-top value, and an additional updated margin-top:0 for :first-child for each heading.

When you add a type scale with a breakpoint prefix (ie lg:prose-lg), there is an adjusted margin-top value in a media query, but they are missing the related margin-top:0 for :first-child situations.

I created a Tailwind Play link that describes this: https://play.tailwindcss.com/FbG6fLD0eT

Here are some screenshots

Just .prose (good):

Image

Image

Size modifier: .prose.prose-sm (good):

Image

Image

Size modifier + breakpoint prefix (bad):

Image

Image

Note - this may be related to #361 but that issue involves some overrides etc, and my issue is just straight-up tailwindcss@latest and @tailwindcss/typography@latest.

My current workaround until this gets resolved looks like this:

@plugin "@tailwindcss/typography";

/* Override until https://github.com/tailwindlabs/tailwindcss-typography/issues/383 is fixed */
@layer utilities {
  .prose > :first-child {
    margin-top: 0 !important;
  }
  .prose > :last-child {
    margin-bottom: 0 !important;
  }
}

Just some notes for myself โ€” here's what I see in dev tools in v3:

Image

And here's v4:

Image

Interestingly this entire rule seems to be missing when using the plugin in v4, which looks like the reason for the margin:

Image

No idea why that's being lost but that's where we'll have to investigate.

@adamwathan found it - in the generated CSS, inside the .sm\:prose-sm declaration, the margin override references .prose-sm, not .sm\:prose-sm:

.sm\:prose-sm {
  @media (width >= 40rem) {
    :where(.prose-sm > :first-child):not(
        :where([class~='not-prose'], [class~='not-prose'] *)
      ) {
      margin-top: 0;
    }
  }
}

This needs to be adjusted to

.sm\:prose-sm {
  @media (width >= 40rem) {
-    :where(.prose-sm > :first-child):not(
+    :where(.sm\:prose-sm > :first-child):not(
        :where([class~='not-prose'], [class~='not-prose'] *)
      ) {
      margin-top: 0;
    }
  }
}

This affects several other pseudo-classes inside the modifier+media queries. Looks like any of the keys that start with > . For instance, all of these are affected by the same issue:

'> ul > li p': {
marginTop: em(8, 14),
marginBottom: em(8, 14),
},
'> ul > li > p:first-child': {
marginTop: em(16, 14),
},
'> ul > li > p:last-child': {
marginBottom: em(16, 14),
},
'> ol > li > p:first-child': {
marginTop: em(16, 14),
},
'> ol > li > p:last-child': {
marginBottom: em(16, 14),
},

@danieltott Thanks for the detailed bug report! This was indeed an issue in our compatibility layer that didn't properly replace class names with the utility names in these cases. I pushed a fix onto main that will be part of the next patch release. Thanks again!

@philipp-spiess awesome! Glad I could help and glad it wasn't a huge pain to fix ๐Ÿ˜‚ Keep up the good work ๐Ÿคœ๐Ÿผ

@danieltott Thanks for the detailed bug report! This was indeed an issue in our compatibility layer that didn't properly replace class names with the utility names in these cases. I pushed a fix onto main that will be part of the next patch release. Thanks again!

Thanks for this fix, it is the only thing I need before upgrading to V4. Is there any date decided for when the next patch is released with this fix, or could you simply release it now? :)

@michaelrazmgah Will do a release this week for sure, just trying to get as many fixes in as we can to avoid unnecessary churn.

@philipp-spiess thanks again for the quick fix - I confirmed this is fixed up in tailwindcss@4.0.7!

@michaelrazmgah note that the fix is in tailwindcss, not @tailwindcss/typography ๐Ÿ˜ƒ

@philipp-spiess thanks again for the quick fix - I confirmed this is fixed up in tailwindcss@4.0.7!

@michaelrazmgah note that the fix is in tailwindcss, not @tailwindcss/typography ๐Ÿ˜ƒ

@danieltott Are you sure? It doesn't seem to work for me ๐Ÿค” I still need your workaround for margins top and bottom for first and last elements to be removed.

@michaelrazmgah yeah, it's definitely fixed. You can see the result here: https://play.tailwindcss.com/FbG6fLD0eT - the ones with the red borders had the issue in 4.0.6