← Go Back

A hack for missing @at-root for Tailwind CSS Plugin

Broken Post?Let me know

Introduction

I was creating a Tailwind CSS ("TW") plugin, @downwindcss/debug. for a utility outline-{n} to apply outline.

The utility should apply to a whole page when a user adds the utility class anywhere in the DOM tree.
Basically @at-root in SASS.

Problems and Attempts

When you add a utility, you can use a CSS-in-JS syntax, to refer to the parent with & (ampersand).

Attempt #1

My attempt was to do was to apply to descendants of <body /> (line #5, "body *, &").

const numberedOutlines = Object.entries(values)
  .filter(([key]) => key !== "DEFAULT")
  .map(([key, value]) => ({
    [`.${e(`outline-${key}`)}`]: {
      "body > *": {
        outline: `${value} solid red`,
      },
    },
  }))

But TW appended .outline to the output.

.outline body > * {
  outline: 1px solid red;
}

That's not the selector I wanted. I wanted a simple body > * to apply the outline to the whole page!

Attempt #2

As & refers to the parent selector, .outline, I was adding & either to the left or to the right separated by ,.

"body > *, &": {
    outline: `${value} solid red`,
},

// or

"&, body > *": {
    outline: `${value} solid red`,
},

But both of them still appeneded .outline in front of body like,

.outline body > *, .outline
// or
.outline, .outline body > *

Working Code

Ok, frustrated I was, I decided to hack it by excluding the current & and including it again (body * > :not(&), &).

const numberedOutlines = Object.entries(values)
  .filter(([key]) => key !== "DEFAULT")
  .map(([key, value]) => ({
    [`.${e(`outline-${key}`)}`]: {
      "body * > :not(&), &": {
        outline: `${value} solid red`,
      },
    },
  }))

You can see that outline-5 was applied somewhere in the DOM tree and outline was applied to the whole page.
(disregard the fact that it's showing outline-4 cuz it's WIP 😅)

working!


Image by Peter H from Pixabay

Webmentions

Loading counts...

❤️ 0 💬 0
Fetching Replies...
There is no reply...