lightningcss icon indicating copy to clipboard operation
lightningcss copied to clipboard

Escape hatch for "Unknown at rule: X"

Open jh3y opened this issue 1 year ago • 2 comments

🐛 bug report

I spend some time working with CSS primitives in my work and this often means syntax that isn't widely used yet or that is changing. I've bumped into this issue a couple of times. But, where there are primitives that are in use, transformer-css doesn't have a documented way to get around them if they aren't supported by the transformer. For example, CSS @scroll-timeline.

If I put this in my CSS

@scroll-timeline yourFirstTimeline {
  source: auto; 
  orientation: vertical;
  scroll-offsets: 0px, var(--distance);
}

Which is valid CSS and works in Chrome Canary behind the experimental features flag

I'll get Unknown at rule: @scroll-timeline and I'm not sure how to bypass trying to "transform" it. It's like I need an eslint-ignore but for transforming new things.

🎛 Configuration (.babelrc, package.json, cli command)

Default set up with no configurations.

🤔 Expected Behavior

Should either compile and not complain or perhaps warn about it. Or provide users some way to get around it.

For example:

/* @parcel/transformer-css <start-ignore> */
@scroll-timeline yourFirstTimeline {
  source: auto; 
  orientation: vertical;
  scroll-offsets: 0px, var(--distance);
}
/* @parcel/transformer-css <end-ignore> */

😯 Current Behavior

Won't transform and compile.

💁 Possible Solution

Listed above.

🔦 Context

I'm unable to work with the tool as I wish. Instead I have to manually resort to injecting the CSS into the <head> myself.

const HEAD = document.querySelector('head')

const insertStyles = styles => {
	const STYLE = document.createElement('style')
	STYLE.setAttribute('type', 'text/css')
	STYLE.innerHTML = styles
	HEAD.appendChild(STYLE)
}

const STYLES_TO_INSERT = `
	@scroll-timeline yourFirstTimeline {
		source: auto;
		orientation: vertical;
		scroll-offsets: 0px, var(--distance);
	}
`

insertStyles(STYLES_TO_INSERT)

💻 Code Sample

Try this valid CSS in a Parcel CSS file.

@scroll-timeline yourFirstTimeline {
    source: auto;
    orientation: vertical;
    scroll-offsets: 0px, var(--distance);
}

🌍 Your Environment

Software Version(s)
Parcel 2.6.2
Node 17.8.0
npm/Yarn bun
Operating System MacOS

jh3y avatar Jul 16 '22 01:07 jh3y

I just added an errorRecovery option, but that will skip unsupported/invalid rules, and sounds like you want to preserve them. Generally, parsing unknown rules is difficult because the parser must know what to expect (e.g. whether the rule has a block, what goes in the block, etc.). In this case, the right solution is to implement support for @scroll-timeline in @parcel/css, given that it is implemented in browsers.

devongovett avatar Jul 16 '22 02:07 devongovett

Hey @devongovett 👋

Cheers for getting back to me. Hmm 🤔 I wonder how other tools handle this? Is it maybe a little too restrictive to completely remove it / ignore it? Especially if there is no preprocessor at play. That said some preprocessors will process and trust you know what you're up to.

Is there a way perhaps to have a stylesheet from your entry point that doesn't get transformed but is still pulled in? I'm using a HTML entry point. And I can think of other scenarios where this is a problem too. Especially as specs change before release, etc. I'd really prefer to keep using Parcel for my work because it does make life a lot easier so thank you for that! 🙏 👏

Other scenarios: Shared Element Transitions API uses different pseudo selectors that aren't currently supported by Parcel so I'm having to use these little JS snippets to inject things.

::page-transition-container(avatar),
::page-transition-outgoing-image(avatar),
::page-transition-incoming-image(avatar) {
  animation-duration: 0.5s;
}

::page-transition-outgoing-image(avatar),
::page-transition-incoming-image(avatar) {
  height: 100%;
}

::page-transition-image-wrapper(avatar) {
  mix-blend-mode: normal;
}

jh3y avatar Jul 16 '22 12:07 jh3y